我的洪水填充算法有效,但是,我无法打印我游戏的6种主要颜色。允许我打印二维数组的Java函数在名为toString()的GameModel.java类中:
import java.util.Random;
public class GameModel {
/**
* predefined values to capture the color of a DotInfo
*/
public static final int COLOR_0 = 0;
public static final int COLOR_1 = 1;
public static final int COLOR_2 = 2;
public static final int COLOR_3 = 3;
public static final int COLOR_4 = 4;
public static final int COLOR_5 = 5;
public static final int NUMBER_OF_COLORS = 6;
private static DotInfo[][] dots;
private int size;
private int currentColor;
private Random generator;
private int steps;
/**
* Constructor to initialize the model to a given size of board.
*
* @param size
* the size of the board
*/
public GameModel(int size) {
this.size = size;
dots = new DotInfo[size][size];
generator = new Random();
}
/**
* Resets the model to (re)start a game. The previous game (if there is one)
* is cleared up .
*/
public void reset(){
generator = new Random();
int color = 0;
for (int j=0;j<size;j++) {
for (int i=0;i<size;i++) {
dots[j][i] = new DotInfo(i, j, generator.nextInt(NUMBER_OF_COLORS)+1);
}
}
}
/**
* Getter method for the size of the game
*
* @return the value of the attribute sizeOfGame
*/
public int getSize(){
return size;
}
/**
* returns the current color of a given dot in the game
*
* @param i
* the x coordinate of the dot
* @param j
* the y coordinate of the dot
* @return the status of the dot at location (i,j)
*/
public int getColor(int i, int j){
return dots[j][i].getColor();
}
/**
* returns true is the dot is captured, false otherwise
*
* @param i
* the x coordinate of the dot
* @param j
* the y coordinate of the dot
* @return the status of the dot at location (i,j)
*/
public boolean isCaptured(int i, int j){
return dots[j][i].isCaptured();
}
/**
* Sets the status of the dot at coordinate (i,j) to captured
*
* @param i
* the x coordinate of the dot
* @param j
* the y coordinate of the dot
*/
public void capture(int i, int j){
dots[j][i] = new DotInfo(i, j, currentColor);
dots[j][i].setCaptured(true);
}
/**
* Getter method for the current number of steps
*
* @return the current number of steps
*/
public int getNumberOfSteps(){
return steps;
}
/**
* Setter method for currentSelectedColor
*
* @param val
* the new value for currentSelectedColor
*/
public void setCurrentSelectedColor(int val) {
currentColor = val;
}
/**
* Getter method for currentSelectedColor
*
* @return currentSelectedColor
*/
public int getCurrentSelectedColor() {
return currentColor;
}
/**
* Getter method for the model's dotInfo reference
* at location (i,j)
*
* @param i
* the x coordinate of the dot
* @param j
* the y coordinate of the dot
*
* @return model[i][j]
*/
public DotInfo get(int i, int j) {
return dots[j][i];
}
/**
* The metod <b>step</b> updates the number of steps. It must be called
* once the model has been updated after the payer selected a new color.
*/
public void step(){
steps++;
}
/**
* The metod <b>isFinished</b> returns true iff the game is finished, that
* is, all the dats are captured.
*
* @return true if the game is finished, false otherwise
*/
public boolean isFinished(){
boolean flag=true;
for (int y=0;y<size;y++) {
for (int x=0;x<size;x++) {
if (dots[y][x].isCaptured()==false) {
flag=false;
}
}
}
return flag;
}
/**
* Builds a String representation of the model
*
* @return String representation of the model
*/
public String toString(){
String rep = "";
for (int y=0;y<size;y++) {
for (int x=0;x<size;x++) {
rep += dots[y][x].getColor()+" ";
}
rep+="\n";
}
return rep;
}
}
我打印数组的函数在我的GameController.java类中调用:
System.out.println(model)
import java.awt.*;
public class GameController /*implements ActionListener*/ {
private GameModel model;
private MyStack dots;
private int size;
/**
* Constructor used for initializing the controller. It creates the game's view
* and the game's model instances
*
* @param size
* the size of the board on which the game will be played
*/
public GameController(int size) {
this.size = size;
model = new GameModel(size);
dots = new MyStack(size*size);
}
/**
* resets the game
*/
public void reset(){
model.reset();
System.out.println(model);
}
/**
* Callback used when the user clicks a button (reset or quit)
*
* @param e
* the ActionEvent
*/
/*public void actionPerformed(ActionEvent e) {
}*/
/**
* <b>selectColor</b> is the method called when the user selects a new color.
* If that color is not the currently selected one, then it applies the logic
* of the game to capture possible locations. It then checks if the game
* is finished, and if so, congratulates the player, showing the number of
* moves, and gives two options: start a new game, or exit
* @param color
* the newly selected color
*/
public void selectColor(int color){
model.setCurrentSelectedColor(color);
capturePointAtZero();
sendCapturedToStack();
equalityCheck(color);
System.out.println(model);
}
private void capturePointAtZero() {
int x = 0, y = 0;
if (!model.isCaptured(x, y)) {
model.capture(x, y);
}
}
private void sendCapturedToStack() {
for (int j=0;j<size;j++) {
for (int i=0;i<size;i++) {
if (model.isCaptured(i, j)) {
model.capture(i,j);
dots.push(model.get(i,j));
}
}
}
}
private void equalityCheck(int newColor) {
while (!dots.isEmpty()) {
DotInfo dot = dots.pop();
int x = dot.getX();
int y = dot.getY();
if (model.getColor(x,y+1)==newColor && !model.isCaptured(x,y+1)) {
model.capture(x, y+1);
dots.push(model.get(x,y+1));
} if (model.getColor(x+1,y)==newColor && !model.isCaptured(x+1,y)) {
model.capture(x+1, y);
dots.push(model.get(x+1,y));
} if (model.getColor(x,y-1)==newColor && !model.isCaptured(x,y-1)) {
model.capture(x, y-1);
dots.push(model.get(x,y-1));
} if (model.getColor(x-1,y)==newColor && !model.isCaptured(x-1,y)) {
model.capture(x-1, y);
dots.push(model.get(x-1,y));
}
}
}
}
当它接近矩阵的末尾时,我得到一个IndexOutOfBoundsError。
如果有人能提供帮助,那将非常感激。
答案 0 :(得分:1)
修复所有问题的代码存在太多问题。我在快速浏览后仍然注意到了一些:
是的,矩阵填充为0的原因是currentColor
为0,因为你不打电话给setCurrentSelectedColor
更深层次的问题是逻辑问题。我们来看看equalityCheck
if (model.getColor(x, y + 1) == newColor && !model.isCaptured(x, y + 1))
{
model.capture(x, y + 1);
dots.push(model.get(x, y + 1));
}
此代码表示仅当 具有newColor
时,才会更新(x,y + 1)处的点。显然,如果它与'#34;旧颜色相匹配,你希望它更新。即(0,0)的颜色,但你甚至不想在capturePointAtZero
中保存这种颜色!
public void capture(int i, int j){
for (int y=0;y<size;y++) {
for (int x=0;x<size;x++) {
if (x==i && y==j) {
dots[y][x] = new DotInfo(x, y, currentColor);
dots[y][x].setCaptured(true);
}
}
}
}
效率很低。如果您仍然仅更新单DotInfo
,为什么还需要循环?它可以简化
public void capture(int i, int j){
dots[j][i] = new DotInfo(i, j, currentColor);
dots[j][i].setCaptured(true);
}
希望这有帮助。
<强>更新强>
我理解你的评论,但现在每当我拨打我矩阵末尾的号码时,我都会得到一个arrayIndexOutOfBounds。
异常最有可能发生,因为您未在equalityCheck
中验证您的索引。您可以添加方法isValidPosition
,例如:
public class GameModel
{
....
public boolean isValidPosition(int x, int y)
{
return (x >= 0) && (x < size) && (y >= 0) && (y < size);
}
}
然后
private void equalityCheck(int newColor)
{
...
if (model.isValidPosition(x, y+1) && model.getColor(x, y + 1) == newColor && !model.isCaptured(x, y + 1))
{
model.capture(x, y + 1);
dots.push(model.get(x, y + 1));
}
请注意,isValidPosition
是化合物if
中的第一个调用非常重要。这是有效的,因为Java使用short-circuit evaluation作为布尔语句。
您可以在isValidPosition
中的其他方法中隐藏GameModel
,有时类似的做法也是正确的。但我不认为这是时候因为1)它要求你从getColor
返回一些假值(你现在使用0而我不喜欢它)和2)它隐藏来自读者的业务逻辑,该领域不是无限的。