问题描述
基本上,对于一项家庭作业,我被要求重新制作一款名为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的唯一设备。