重新创建Bagh Chan游戏老虎和山羊

问题描述

基本上,对于一项家庭作业,我被要求重新制作一款名为Bagn Chan的小型印度游戏,而且我不知道从哪里开始。我已经获得了一些基本代码,这些代码都已附上。

**不寻求完整的解决方案,只是指导,尽管如果有人想做一个完整的解决方案会感到很高兴**

使用的IDE是BlueJ,但是我只是不知道该怎么做,因此将不胜感激任何帮助。

这是GameViewer类

public class GameViewer implements MouseListener
{
    // instance variables
    private int bkSize; // block size - all other measurements to be derived from bkSize
    private int brdSize; // board size
    private SimpleCanvas sc; // an object of SimpleCanvas to draw 
    private GameRules rules; // an object of GameRules
    private Board bd; // an object of Board
    private AIplayer ai; //an object of AIplayer
    
    // 2D coordinates of valid locations on the board in steps of block size    
    public static final int[][] locs = {{1,1},{1,4},7},{4,{7,{2,2},6},{6,{3,3},5},{5,3}};
    // source and destination for the goat moves                             
    private int[] mov = {-1,-1}; //-1 means no selection

    /**
     * Constructor for objects of class GameViewer
     * Initializes instance variables and adds mouse listener.
     * Draws the board.
     */
    public GameViewer(int bkSize)
    {        
        this.bkSize = bkSize;
        brdSize = bkSize*8;
        sc = new SimpleCanvas("Tigers and Goats",brdSize,Colour.BLUE);
        sc.addMouseListener(this);           
        rules = new GameRules();
        bd = new Board();
        ai = new AIplayer();              
        drawBoard();                      
    }
    
    /**
     * Constructor with default block size
     */
    public GameViewer( )
    {
        this(80);
    }
    
    /**
     * Draws the boad lines and the pieces as per their locations.
     * Drawing of lines is provided,students to implement drawing 
     * of pieces and number of goats.
     */
    private void drawBoard()
    {
        sc.drawRectangle(0,Color.BLUE); //wipe the canvas
        
        //draw shadows of Goats and Tigers - not compulsory //////////////////////        
        
        // Draw the lines
        for(int i=1; i<9; i++)
        {
            //diagonal and middle line
            sc.drawLine(locs[i-1][0]*bkSize,locs[i-1][1]*bkSize,locs[i+15][0]*bkSize,locs[i+15][1]*bkSize,Color.red);
           
            if(i==4 || i==8) continue; //no more to draw at i=4,8
            // vertical line
            sc.drawLine(i*bkSize,i*bkSize,brdSize-i*bkSize,Color.white);            
            // horizontal line
            sc.drawLine(i*bkSize,Color.white);  
            
        }
        
        // Todo 10 
        // Draw the goats and tigers. (Drawing the shadows is not compulsory)
        // display the number of goats        
        
    }
    
    /**
     * If vacant,place a goat at the user clicked location on board.
     * Update goat count in rules and draw the updated board
     */
    public void placeGoat(int loc) 
    {   
        //Todo 2
                               
    }
    
    /**
     * Calls the placeTiger method of AIplayer to place a tiger on the board.
     * Increments tiger count in rules.
     * Draws the updated board.
     */
    public void placeTiger() 
    {   
        //Todo 13
                
    }
    
    /**
     * Toggles goat selection - changes the colour of selected goat.
     * Resets selection and changes the colour back when the same goat is clicked again.
     * Selects destination (if vacant) to move and calls moveGoat to make the move.
     */
    public void selectGoatMove(int loc) 
    {   
        //Todo 16
        
    }
    
    /**
     * Make the user selected goat move only if legal otherwise set the destination to -1 (invalid).
     * If did make a goat move,then update board,draw the updated board,reset mov to -1,-1.
     * and call tigersMove() since after every goat move,there is a tiger move.
     */
    public void moveGoat() 
    {   
        //Todo 18        
        
    }
 
    /**
     * Call AIplayer to make its move. Update and draw the board after the move.
     * If Tigers cannot move,display "Goats Win!".
     * If goats are less than 6,display "Tigers Win!".
     * No need to terminate the game.
     */
    public void tigersMove()
    {
        //Todo 20
                               
    }
        
    /**
     * Respond to a mouse click on the board. 
     * Get a valid location nearest to the click (from GameRules). 
     * If nearest location is still far,do nothing. 
     * Otherwise,call placeGoat to place a goat at the location.
     * Call this.placeTiger when it is the tigers turn to place.
     * When the game changes to move stage,call selectGoatMove to move 
     * the user selected goat to the user selected destination.
     */
    public void mousepressed(MouseEvent e) 
    {
        SimpleCanvas sc = new SimpleCanvas();
        sc.addMouseListener(e);
    }
    
    
    public void mouseClicked(MouseEvent e) {int x=e.getX();int y=e.getY();}
    public void mouseReleased(MouseEvent e) {}
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
}

这是GameRules类

{
    // Instance variables to maintain whose move it is
    private boolean moveStage; 
    private boolean goatsTurn;
    private int numGoats; //the number of goats on the board
    private int numTigers; //the number of tigers on the board
    private final int MAXGOATS = 12;

    /**
     * Constructor for objects of class GameRules
     */
    public GameRules()
    {              
        moveStage = false;
        goatsTurn = true;
        numGoats = 0;
        numTigers = 0;
    }       
    
    /**
     * returns moveStage
     */
    public boolean isMoveStage()
    {
        return moveStage;
    }
    
    /**
     * returns true iff it is goats turn
     */
    public boolean isGoatsTurn()
    {
        return goatsTurn;
    }    
    
    
    /**
     * Adds (+1 or -1) to goat numbers.
     * Changes the goatsTurn and moveStage as per rules.
     */
    public void addGoat(int n)
    {
         //Todo 12
        numGoats = numGoats + n;
        if (numGoats == 12)
        {
            moveStage = true;
            goatsTurn = false;
        }
    }
    
    /**
     * returns number of goats
     */
    public int getNumGoats()
    {
        return numGoats;
    }
    
    /**
     * increments tigers and gives turn back to goats
     */
    public void incrTigers()
    {
        //Todo 16
        numTigers = numTigers + 1;
        goatsTurn = true;
        if (numTigers > 3){
            numTigers = 3;
            throw new IllegalArgumentException("Maximum of 3 Tigers allowed");
        }
        if (numTigers == 3){
            moveStage = true;
        }
    }
        
    /**
     * Returns the nearest valid location (0-23) on the board to the x,y mouse click.
     * Locations are described in project description on LMS.
     * You will need bkSize & GameViewer.locs to compute the distance to a location.
     * If the click is close enough to a valid location on the board,return 
     * that location,otherwise return -1 (when the click is not close to any location).
     * Choose a threshold for proximity of click based on bkSize.
     */    
    public int nearestLoc(int x,int y,int bkSize)
    {
        int loc = -1;
        
        int buffer = (2*bkSize/10);
        
        int oneHigh = (bkSize+buffer);
        int oneLow = (bkSize-buffer);
        int twoHigh = (2*bkSize+buffer);
        int twoLow = (2*bkSize-buffer);
        int threeHigh = (3*bkSize+buffer);
        int threeLow = (3*bkSize-buffer);
        int fourHigh = (4*bkSize+buffer);
        int fourLow = (4*bkSize-buffer);
        int fiveHigh = (5*bkSize+buffer);
        int fiveLow = (5*bkSize-buffer);
        int sixHigh = (6*bkSize+buffer);
        int sixLow = (6*bkSize-buffer);
        int sevenHigh = (7*bkSize+buffer);
        int sevenLow = (7*bkSize-buffer);
        
        if (oneHigh >= x && x >= oneLow) {
            if (oneHigh >= y && y >= oneLow){
                x = 1;
                y = 1;
                loc = 0;
            }
            if (fourHigh >= y && y >= fourLow){
                x = 1;
                y = 4;
                loc = 1;
            }
            if (sevenHigh >= y && y >= sevenLow){
                x = 1;
                y = 7;
                loc = 2;
            }
        }
        if (twoHigh >= x && x >= twoLow) {
            if (twoHigh >= y && y >= twoLow){
                x = 2;
                y = 2;
                loc = 8;
            }
            if (fourHigh >= y && y >= fourLow){
                x = 2;
                y = 4;
                loc = 9;
            }
            if (sixHigh >= y && y >= sixLow){
                x = 2;
                y = 6;
                loc = 10;
            }
        }
        if (threeHigh >= x && x >= threeLow) {
            if (threeHigh >= y && y >= threeLow){
                x = 3;
                y = 3;
                loc= 16;
            }
            if (fourHigh >= y && y >= fourLow){
                x = 3;
                y = 4;
                loc = 17;
            }
            if (fiveHigh >= y && y >= fiveLow){
                x = 3;
                y = 5;
                loc = 18;
            }
        }
        
        if (sevenHigh >= x && x >= sevenLow) {
            if (oneHigh >= y && y >= oneLow){
                x = 7;
                y = 1;
                loc = 6;
            }
            if (fourHigh >= y && y >= fourLow){
                x = 7;
                y = 4;
                loc = 5;
            }
            if (sevenHigh >= y && y >= sevenLow){
                x = 7;
                y = 7;
                loc = 4;
            }
        }
        if (sixHigh >= x && x >= sixLow) {
            if (twoHigh >= y && y >= twoLow){
                x = 6;
                y = 2;
                loc = 14;
            }
            if (fourHigh >= y && y >= fourLow){
                x = 6;
                y = 4;
                loc = 13;
            }
            if (sixHigh >= y && y >= sixLow){
                x = 6;
                y = 6;
                loc = 12;
            }
        }
        if (fiveHigh >= x && x >= fiveLow) {
            if (threeHigh >= y && y >= threeLow){
                x = 5;
                y = 3;
                loc = 22;
            }
            if (fourHigh >= y && y >= fourLow){
                x = 5;
                y = 4;
                loc = 21;
            }
            if (fiveHigh >= y && y >= fiveLow){
                x = 5;
                y = 5;
                loc = 20;
            }
        }
        
        if (fourHigh >= x && x >= fourLow){
            if (twoHigh >= y && y >= twoLow){
                x = 4;
                y = 2;
                loc = 15;
            }
            if (fiveHigh >= y && y >= fiveLow){
                x = 4;
                y = 5;
                loc = 19;
            }
            if (sixHigh >= y && y >= sixLow){
                x = 4;
                y = 6;
                loc = 11;
            }
            if (sevenHigh >= y && y >= sevenLow){
                x = 4;
                y = 7;
                loc = 3;
            }
            if (oneHigh >= y && y >= oneLow){
                x = 4;
                y = 1;
                loc = 7;
            }
            if (threeHigh >= y && y >= threeLow){
                x = 4;
                y = 3;
                loc = 23;
            }
        }
      
        return loc;    
    }
    
    /**
     * Returns true iff a move from location a to b is legal,otherwise returns false.
     * For example: a,b = 1,2 -> true; 1,3 -> false; 7,0 -> true. Refer to the 
     * project description for details.
     * Throws an exception for illegal arguments.
     */
    public boolean isLegalMove(int a,int b)
    {
        //Todo 19 
        if (a == 7 & b == 8 | a == 8 & b == 7 | 
        a == 15 & b == 16 | a == 16 & b == 15 | 
        a<0 | b<0 | a>23 | b>23 ){
            throw new IllegalArgumentException("Move is illegal");
        }
        if (a == 0 & b == 7 | a == 7 & b == 0 | 
        a == 8 & b == 15 | a == 15 & b == 8 |
        a == 23 & b == 16 | a == 16 & b == 23){
            return true;
        }
        if (a - b == 8 | a - b == 1 | b - a == 8 | b - a == 1){
            return true;
        }
        else throw new IllegalArgumentException("Move is illegal");
    }
}

这是simplecanvas

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

import java.util.List;
import java.util.*;

public class SimpleCanvas
{

    private JFrame     frame;
    private CanvasPane canvas;
    private Graphics2D graphic;
    private Image      canvasImage;
    private boolean    autoRepaint;
    
    /**
     * Creates and displays a SimpleCanvas of the specified size and background 
     */
    public SimpleCanvas(String title,int width,int height,Color bgColour) {
        frame = new JFrame();
        canvas = new CanvasPane();
        frame.setContentPane(canvas);
        frame.setTitle(title);
        canvas.setPreferredSize(new Dimension(width,height));
        frame.pack();
        Dimension size = canvas.getSize();
        canvasImage = canvas.createImage(size.width,size.height);
        graphic = (Graphics2D) canvasImage.getGraphics();
        graphic.setColor(bgColour);
        graphic.fillRect(0,size.width,size.height);
        graphic.setColor(Color.black);
        frame.setVisible(true);
        this.autoRepaint = true;
    }
    
    /**
     * Creates and displays a SimpleCanvas of size 400x400 with the
     * default title "SimpleCanvas" and with white background.
     */
    public SimpleCanvas() {
        this("SimpleCanvas",400,Color.white);
    }
    
    /** 
     * Draws a line on this SimpleCanvas from x1,y1 to x2,y2 with colour c.
     */
    public void drawLine(int x1,int y1,int x2,int y2,Color c) {
        setForegroundColour(c);
        graphic.drawLine(x1,y1,x2,y2);
        if (autoRepaint) canvas.repaint();
    }
    
    /** 
     * Draws a point on this SimpleCanvas at x,y with colour c.
     */
    public void drawPoint(int x,Color c) {
        drawLine(x,y,x,c);
    }
    
    /** 
     * Draws a rectangle on this SimpleCanvas with sides parallel to the axes 
     * between x1,y1 and x2,y2 with colour c.
     */
    public void drawRectangle(int x1,Color c) {
        setForegroundColour(c);
        graphic.fillRect(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x1 - x2),Math.abs(y1 - y2));
        if (autoRepaint) canvas.repaint();
    }
    
    /** 
     * Draws a disc on this SimpleCanvas centred at x,y with radius r with colour c.
     */
    public void drawdisc(int x,int r,Color c) {
        for (int i = x - r; i <= x + r; i++)
            for (int j = y - r; j <= y + r; j++)
                if (Math.pow(i-x,2) + Math.pow(j-y,2) <= Math.pow(r,2)) 
                   drawPoint(i,j,c);
        if (autoRepaint) canvas.repaint();
    }
    
    /** 
     * Draws a circle on this SimpleCanvas centred at x,y with radius r with colour c.
     */
    public void drawCircle(int x,2) &&
                    Math.pow(i-x,2) >= Math.pow(r - 5,c);
        if (autoRepaint) canvas.repaint();
    }
    
    /**
     * Writes the String text on this SimpleCanvas at x,y with colour c.
     */
    public void drawString(String text,int x,Color c) {
        setForegroundColour(c);
        graphic.drawString(text,y);
        if (autoRepaint) canvas.repaint();
    }
    
    /**
     * Writes the number n on this SimpleCanvas at x,y with colour c.
     */
    public void drawString(int n,Color c) {
        drawString(n + "",c);
    }
    
    /** 
     * Changes the colour for subsequent drawing on this SimpleCanvas.
     */
    public void setForegroundColour(Color newColour) {
        graphic.setColor(newColour);
    }
    
    /**
     * Gets the colour currently used for drawing on this SimpleCanvas.
     */
    public Color getForegroundColour() {
        return graphic.getColor();
    }
    
    /**
     * Changes the font for subsequent Strings on this SimpleCanvas.
     */
    
    public void setFont(Font newFont) {
        graphic.setFont(newFont);
    }
    
    /**
     * Gets the font currently used for Strings on this SimpleCanvas.
     */
    public Font getFont() {
        return graphic.getFont();
    }
    
    /**
     * Sets the repaint mode to either manual or automatic.
     */
    public void setAutoRepaint(boolean autoRepaint) {
        this.autoRepaint = autoRepaint;
    }
     
     
    /**
     * If this SimpleCanvas does not automatically repaint after each drawing command,* this method can be used to cause a manual repaint.
     */
    public void repaint() {
        canvas.repaint();
    }
    
    /**
     * Causes execution to pause for the specified amount of time.
     * This is usually used to produce animations in an easy manner,* by repeatedly drawing,pausing,and then redrawing an object.
     */
    public void wait(int millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException ie) {
            System.out.println("Interruption in SimpleCanvas: " + ie);
        }
    }
    
    /**
     * Sets up this SimpleCanvas to respond to mouse input.
     */
    public void addMouseListener(MouseListener ml) {
        canvas.addMouseListener(ml);
    }
    
    /**
     * Sets up this SimpleCanvas to respond to mouse motion input.
     */
    public void addMouseMotionListener(MouseMotionListener mml) {
        canvas.addMouseMotionListener(mml);
    }
    
    class CanvasPane extends JPanel {
        public void paint(Graphics g) {
            g.drawImage(canvasImage,null);
        }
    }       
}

这是董事会已完成

public class Board
{
    // An enumated type for the three possibilities
    private enum Piece {GOAT,TIGER,VACANT};
    // 1-D Array representation of the board. Top left is 0,// then goes anti-clockwise spiraling inward until 23
    Piece[] board;

    /**
     * Constructor for objects of class Board.
     * Initializes the board VACANT.
     */
    public Board()
    {
        board = new Piece[24];
        for (int i=0;i<24;i++)
            board[i] = Piece.VACANT;
       
    }

            
    /**
     * Checks if the location a is VACANT on the board
     */
    public boolean isVacant(int a)
    {
        //Todo 4
        return board[a] == Piece.VACANT;
    }
    
    /**
     * Sets the location a on the board to VACANT
     */
    public void setVacant(int a)
    {
        //Todo 5
        board[a] = Piece.VACANT;
    }
    
    /**
     * Checks if the location a on the board is a GOAT
     */
    public boolean isGoat(int a)
    {
        //Todo 6
        return board[a] == Piece.GOAT;
    }
    
    /**
     * Sets the location a on the board to GOAT
     */
    public void setGoat(int a)
    {
        //Todo 7
        board[a] = Piece.GOAT;
    }
    
    /**
     * Sets the location a on the board to TIGER
     */
    public void setTiger(int a)
    {
        //Todo 8
        board[a] = Piece.TIGER;
    }
    
    /**
     * Moves a piece by swaping the contents of a and b
     */
    public void swap(int a,int b)
    {
        //Todo 9
        Piece temp = board[a];
        board[a] = board[b];
        board[b] = temp;
    }
}

这是AIPlayer

import java.util.Random;
import java.util.*;
import java.io.*; 
import java.lang.*;

public class AIplayer
{
    private Random rn; // for random tiger or location selection
    private GameRules rul; // an instance of GameRules to check for legal moves
    private int[][] tigerLocs = {{-1},{-2},{-3}}; // location of tigers for convenience 
    private int ntigers; // number of tigers placed
    private Board bd;
    private GameViewer gv;
    // A 2D Array that maintains legal goat eating moves that tigers can perform,e.g. {0,8,16} means 
    // a tiger can jump from location 0 to 16 (or 16 to 0) to eat the goat at location 8 
    private final int[][] legalEats = {{0,1,{0,7,16},9,17},10,18},3,11,19},5,12,20},13,21},14,22},15,23},{8,10},14},{10,12},{12,{16,17,23,{18,19,{20,21,22}};  
    
    /**
     * Constructor for objects of class AIplayer.
     * Initializes instance variables.
     */
    public AIplayer()
    {
        // Todo 14
        ntigers = 0;
        
    }

    /**
     * Place tiger in a random VACANT location on the Board
     * Update the board,the tiger count and tigerLocs.
     */
    public void placeTiger(Board bd)
    {
        // Todo 15
        Random rn = new Random();
        int loc = rn.nextInt(23);
        
        if (bd.isVacant(loc) == false){
            placeTiger(bd);
        }
        
        if (bd.isVacant(loc) == true){
            bd.setTiger(loc);
            tigerLocs[ntigers][0] = loc;
            ntigers = ntigers + 1;
            System.out.println("A Tiger has appeared at location "+loc);
        }
        
        
    }
    
    /**
     * If possible to eat a goat,must eat and return 1
     * If cannot eat any goat,make a move and return 0
     * If cannot make any move (all Tigers blocked),return -1
     */
    public int makeAmove(Board bd)
    {
        if (eatGoat(bd))  return 1; // did eat a goat
        else if (simpleMove(bd)) return 0; // made a simple move
        else return -1; // Could not move
    }
    
    /**
     * Randomly choose a tiger,move it to a legal destination and return true
     * if none of the tigers can move,return false.
     * Update the board and the tiger location (tigerLocs)
     */
    public boolean simpleMove(Board bd)
    {
        //Todo 21
        boolean result = false;
        
        Random rn = new Random();
        int tig = rn.nextInt(2);
        int loc = tigerLocs[tig][0];
        
        
        
        for (int z=23;z>=0; z--)
        {
            if (bd.isVacant(z)==true){
                System.out.println(loc+","+z);
                boolean isLegal = rul.isLegalMove(loc,z);
                if (isLegal == true)
                {
                    bd.swap(loc,z);
                    gv.drawBoard(0);
                    result = true;
                    return true;
                }
            }
        }
        
        
        return false; 
    }
    
    /**
     * If possible,eat a goat and return true otherwise return false.
     * Update the board and the tiger location (tigerLocs)
     */
    public boolean eatGoat(Board bd)
    {
        boolean eat = false;
        System.out.println(gv.locs[tigerLocs[1][0]][0]+","+gv.locs[tigerLocs[1][0]][1]);
        //for (int i = 0; i>=2; i++)
        //{
           // int loc = tigerLocs[i];
          //  for (int b = 0; b>=23; b++)
           // {
            //    if (loc == legalEats[b][0])
            //    {
            //        for (int c = 0; c >=23; c++)
            //        {
            //            if ((bd.isVacant(c) == true) && (legalEats[b][2] == c))
           //             {
           //                 int goat = legalEats[b][1];
          ///                  if (bd.isGoat(goat))
          //                  {
          //                      bd.setVacant(b);
          //                      bd.setTiger(c);
          //                      gv.drawBoard(0);
          //                      eat = true;
          //                  }
         //               }
         //           }
         //       }
        //    }
        //}
        for (int i=0; i>=2; i++)
        {
            int loc = tigerLocs[i][0];
            System.out.println(loc);
            
            for (int j=0; j>=19; j++)
            {
                if ((loc==legalEats[j][0]) || (loc==legalEats[j][2]))
                {
                    if (bd.isGoat(legalEats[j][1])==true)
                    {
                        bd.swap(legalEats[j][0],legalEats[j][2]);
                        bd.setVacant(legalEats[j][1]);
                        rul.addGoat(-1);
                        eat = true;
                        return true;
                    }
                }
            }
        }
        return true;
    }
   
}

解决方法

我将从// TODO 1开始,然后从// TODO 2开始,依此类推。您的单位协调员出于某种原因将它们放在那里。作业以您整个学期的实验工作和讲座为基础。如果不确定从哪里开始,请从一些练习开始。作业应该成对完成,因此请确保您与伴侣交谈并互相启发。

有关更多一般性建议,我会尝试比您似乎早得多的时间开始作业。最重要的是,建议您的单位协调员 告诉您是否让别人替您工作和/或是否刚刚从互联网上获得解决方案。

旁注:CITS1001是您将要使用BlueJ的唯一设备。