【发布时间】:2021-01-31 15:38:59
【问题描述】:
基本上,我被要求重新创建一个名为 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},{1,7},{4,7},{7,7},{7,4},{7,1},{4,1},
{2,2},{2,4},{2,6},{4,6},{6,6},{6,4},{6,2},{4,2},
{3,3},{3,4},{3,5},{4,5},{5,5},{5,4},{5,3},{4,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, 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,0,brdSize,brdSize,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,
i*bkSize, brdSize-i*bkSize,Color.white);
// horizontal line
sc.drawLine(i*bkSize, i*bkSize,
brdSize-i*bkSize, 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) {}
}
这是游戏规则类
{
// 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");
}
}
这是简单的画布
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,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, 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, int y, Color c) {
drawLine(x, y, x, y, 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, int y1, int x2, int y2, 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 y, 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, int y, 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) &&
Math.pow(i-x, 2) + Math.pow(j-y, 2) >= Math.pow(r - 5, 2))
drawPoint(i, j, 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, int y, Color c) {
setForegroundColour(c);
graphic.drawString(text, x, y);
if (autoRepaint) canvas.repaint();
}
/**
* Writes the number n on this SimpleCanvas at x,y with colour c.
*/
public void drawString(int n, int x, int y, Color c) {
drawString(n + "", x, y, 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,0,0,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,2},{0,7,6},{0,8,16},{1,9,17},{2,10,18},{2,3,4},{3,11,19},
{4,5,6},{4,12,20},{5,13,21},{6,14,22},{7,15,23},{8,9,10},{8,15,14},
{10,11,12},{12,13,14},{16,17,18},{16,23,22},{18,19,20},{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;
}
}
【问题讨论】:
-
请不在这里问作业。
-
我不是在寻求解决方案,我只是在询问一些指针,因为我只是不知道从哪里开始
标签: java hash 2d-games mouseclick-event