如何在坐标数组列表中查找模式?

How to find pattern in an Arraylist of coordinates?

我 class 调用了 Cell,它有两个扩展 JButton 的属性 x 和 y。这是它的代码。

        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 的 class,用于创建扩展 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;
        }

我怎样才能找到一种方法来创建一个检查获胜者的方法。基本上其他功能已经完成,比如改变玩家的回合并根据玩家的移动改变按钮的颜色 selected(每个玩家可以 select 一个单元格并将其更改为一种颜色, 确实和collect 4很像但是彩色按钮的图案有点不同)。

如果有 9 个按钮以检查每个彩色单元格的北、东北、东、东南、南、西南、西、西北的模式出现,则用户可能获胜。如果 9 个彩色单元格以相同的颜色相连,则用户获胜。

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

我的建议是保持游戏状态并在玩家标记单元格后更新。 我不认为性能是这种 2D 的关注点 game.so 无需寻求优化的复杂算法。

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;

  }
}

引入新的class来跟踪相邻的细胞块。

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;
      }
}

然后新建class保持游戏状态

用户单击单元格后必须调用 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;

  }
}