在洪水填充游戏中显示颜色时遇到问题

时间:2017-02-26 02:08:51

标签: java arrays

我的洪水填充算法有效,但是,我无法打印我游戏的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。

如果有人能提供帮助,那将非常感激。

1 个答案:

答案 0 :(得分:1)

修复所有问题的代码存在太多问题。我在快速浏览后仍然注意到了一些:

  1. 是的,矩阵填充为0的原因是currentColor为0,因为你不打电话给setCurrentSelectedColor

  2. 更深层次的问题是逻辑问题。我们来看看equalityCheck

  3.         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中保存这种颜色!

    1. 等代码
          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)它隐藏来自读者的业务逻辑,该领域不是无限的。