【问题标题】:How to find pattern in an Arraylist of coordinates?如何在坐标的Arraylist中找到模式?
【发布时间】:2015-10-30 02:04:15
【问题描述】:

我有一个名为 Cell 的类,它有两个属性 x 和 y,它们扩展了 JButton。这是代码。

        private static final long serialVersionUID = 1L;

            private int x;
            private int y;

            public Cell(int x, int y) {
                this.x = x;
                this.y = y;

                String cellCoord = x + "," + y;
                JLabel cellLbl = new JLabel(cellCoord);
                this.add(cellLbl);
                this.setBackground(Color.ORANGE);
            }

            public int getx() {
                return x;
            }

            public int gety() {
                return y;
            }

            public void setx(int x) {
                this.x = x;
            }

            public void sety(int y) {
                this.y = y;
            }

还有一个名为 Grid 的类,用于创建扩展 JPanel 的 20x20 Grid。

    public class Grid extends JPanel {

        private static final long serialVersionUID = 1L;

        private ArrayList<Cell> cells;
        private int width = 20;
        private int height = 20;

        public Grid() {
            cells = new ArrayList<Cell>();
        }

        public void drawGrid() {
            this.setLayout(new GridLayout(width, height, 5, 5));
            this.setBackground(Color.RED);

            for (int i = 0; i < height; i++) {
                for (int j = 0; j < width; j++) {
                    Cell cell = new Cell(i, j);
                    cells.add(cell);
                }
            }
            for (Cell c : cells) {
                this.add(c);
            }

        }

        public void refreshGrid() {
            this.removeAll();
            this.repaint();

            for (Cell c : cells) {
                this.add(c);
            }
        }

        public ArrayList<Cell> getCells() {
            return cells;
        }

        public void setCells(ArrayList<Cell> cells) {
            this.cells = cells;
        }

        public void changeCell(Cell c) {
            for (Cell cell : cells) {
                if (cell.getx() == c.getx() && cell.gety() == c.gety()
                        && cell.getBackground() != Color.black ) {
                    cell.setBackground(c.getBackground());
                    refreshGrid();

                }

            }
        }

        public Cell validateCell(int x , int y){
            Cell tmp = new Cell(x,y);
            for(Cell cell : this.cells){
                if(cell.getx() == x && cell.gety() == y){
                    tmp = cell;
                }
            }
            return tmp;
        }

我怎样才能找到一种方法来创建检查获胜者的方法。基本上其他功能已经完成,比如改变玩家的回合,并根据玩家的动作改变选择的按钮的颜色(每个玩家可以选择一个单元格并将其更改为一种颜色,它真的类似于收集 4 但彩色按钮的图案有点不同)。

如果有 9 个按钮,这些按钮的模式检查每个彩色单元格的 North、North East、East、SouthEast、South、SouthWest、West、NorthWest,则用户可以获胜。如果 9 个彩色单元格以相同的颜色连接,则用户获胜。

这是一个有效模式的示例,其中以黄色圆圈突出显示的模式相互连接以形成模式。带有红色圆圈的那个是在这种情况下被丢弃的最后一个单元格,程序注意到有 11 个相同颜色的单元格,这意味着它超过了 9 个匹配规则,因此有一个赢家。

【问题讨论】:

  • 第一个玩家不是每次都赢吗?有9个方向可以将一个块链接到另一个块,没有办法通过每回合放置一个块来阻止第一个玩家
  • 玩家也可以使用一种特殊的力量来禁用细胞,他在每场比赛中有两次机会这样做,因此玩家二可以阻止玩家一获胜。它看起来像这样Image
  • 好了,除此之外,你需要的是使用图遍历算法,统计图中的节点数。
  • 我会检查一下,谢谢你的帮助。

标签: java arrays swing arraylist jbutton


【解决方案1】:

我的建议是保持游戏状态并在玩家标记单元格后更新。 我不认为这种 2D 游戏的性能是一个问题。所以不需要去优化复杂的算法。

class Cell
{

  // other codes

  public boolean isAdjacent(Cell cell)
  {
    int xDiff = cell.getX() - x;
    int yDiff = cell.getY() -y;
    if(xDiff>=-1 && xDiff<=1 && yDiff>=-1 && yDiff<=1)
    {
       return true;
    }
    return false;

  }
}

引入一个新类来跟踪相邻的单元块。

public class Block
{    
  private List<Cell> cells = new ArrayList<Cell>();

      public boolean canMerge(Cell cell)
      {
        if (cells.isEmpty())
        {
          return true;
        }
        else
        {
          for (Cell existingCell : cells)
          {
            if (existingCell.isAdjacent(cell))
            {
              return true;
            }
          }
        }
        return false;
      }

      public void merge(Cell cell)
      {
        cells.add(cell);
      }

      public void merge(Block block)
      {
        cells.addAll(block.getCells());
      }

      public List<Cell> getCells()
      {
        return cells;
      }
}

然后是新的类来维护游戏状态

用户单击单元格后必须调用的 markCell 方法

public class GameStatus
{
  HashMap<Integer,List<Block>> players = new HashMap<Integer, List<Block>>();

  public boolean markCell(Cell cell,int player)
  {
    int count = 0;
    List<Block> blocks = players.get(player);
    if(blocks==null)
    {
      // this is the first cell mark by this player
      blocks = new ArrayList<Block>();
      Block block = new Block();
      block.merge(cell);
      blocks.add(block);
      players.put(player,blocks);
    }
    else
    {
      Block alreadyMergedToThisBlock = null;
      ArrayList<Block> shouldBeRemovedList = new ArrayList<Block>();
      for (Block block : blocks)
      {
        if(block.canMerge(cell)) // cell is adjacent to a block
        {
          if (alreadyMergedToThisBlock==null) // this is the first block we found which is adjacent to the given cell
          {
            block.merge(cell);
            count = block.getCells().size();
            alreadyMergedToThisBlock = block;
          }
          else
          {
            // we have already merge given cell to block,but this block also adjacent to the given cell.
            // that means two blocks can be merged together and this block can be removed once it is merged to the previous one
            alreadyMergedToThisBlock.merge(block); 
            count = alreadyMergedToThisBlock.getCells().size();
            shouldBeRemovedList.add(block);
          }
        }
      }
      blocks.removeAll(shouldBeRemovedList);
    }

    return count>=9;

  }
}

【讨论】:

  • 是否需要在 isAdjacent(Cell cell) 中添加更多语句来检查对角线的情况?
  • 否,同一列表示 xDiff = 0,yDiff=+ 或 - 1,同一行表示 xDiff = + 或 - 1 和 yDiff =0,对角线表示 xDiff= + 或 - 1 和 yDiff =+或-1。那么所有组合都将被该方法覆盖。
猜你喜欢
  • 2021-05-17
  • 1970-01-01
  • 2019-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多