【问题标题】:How can I find three of the same numbers in a row?如何连续找到三个相同的数字?
【发布时间】:2014-03-01 17:51:06
【问题描述】:

我有一个类似下面的数组。

int[][] myArray = 
        {{1, 2, 3, 0, 0, 1}
         {1, 0, 4, 4, 0, 1}
         {1, 2, 4, 3, 4, 0}
         {2, 2, 0, 0, 2, 2}
         {3, 0, 0, 3, 0, 0}
         {4, 2, 3, 0, 0, 0}}

它会说一个赢了,因为第一列的三个 1 中的 1。两个人不会赢,因为他们不在一个“行”中。

我想进行某种获胜检查,以便在行、对角线或列中找到三个相同的数字。有点像井字游戏,但网格更大。在我使用一组凌乱的 if 语句和 goto 语句之前。 (它是用 Basic 编写的。)我尝试使用一个系统,它从最后放置的一块中找到方向,其中有许多相同的,但它不能正常工作。我怎样才能以一种简单且可维护的方式做到这一点?

尝试过的代码:

private static boolean checkBoardCombinations(int[][] board, int inputX, int inputY) {
        int currentPlayer = board[inputX-1][inputY-1];
        boolean[][] directions = new boolean[3][3];
        for(int y = 0; y >= -2; y--){
            for(int x = 0; x >= -2; x--){
                if(inputX+x >= 0 && inputX+x <= 7 && inputY+y >= 0 && inputY+y <= 7 
                        && (board[inputX+x][inputY+y] == currentPlayer)){
                    //System.out.printf("X: %s Y: %s", inputX+x, inputY+y);
                    directions[x+2][y+2] = true;
                }
                else{
                    directions[x+2][y+2] = false;
                }
                //System.out.printf("X: %s Y: %s B: %s,", inputX+x, inputY+y, directions[x+2][y+2]);
            }
            //System.out.println();
        }
        /*
         for(int x = 0; x <= 2; x++){
            for(int y = 0; y <= 2; y++){
                System.out.print(directions[x][y] + " ");
            }
                System.out.println();
        }
        */
        return false;

    }

【问题讨论】:

  • 应用什么逻辑或者粘贴代码会更好
  • 3个相同的值必须一个接一个,还是可以分散在行、对角线或列中?
  • 这些数字的范围是多少?它们只是个位数吗?或者它们的范围可以是任何值吗?还是它们只是 0、1、2、3 和 4?
  • @NiksTyagi 查看底部的代码。我正在考虑创建一个系统,它可以扫描最后放置的相同编号的部件。它将存储最接近的数字与最后放置的棋子相同的方向。从那里它将继续向那个方向扫描。最后它会查看一行、一列或对角线中是否存在三个真值。
  • @halex 数字必须是感人的,有点,所以是的,它们必须一个接一个。

标签: java arrays


【解决方案1】:

假设玩家数量已知,您可以逐个遍历所有玩家,并检查是否有玩家正在形成所需长度的连接。

这样的代码如下所示:

private int[][] grid; // Your array of size ROWS x COLUMNS
private final int ROWS = 6, COLUMNS = 6;
private final int CONSECUTIVE_CONNECTION_REQUIRED = 3;

// Returns true if given playerType is forming a connection, else false.
public boolean checkGrid(int playerType)
{
  // Check downward
  for (int i = 0; i <= ROWS - CONSECUTIVE_CONNECTION_REQUIRED; i++)
  {
    for (int j = 0; j < COLUMNS; j++)
    {
      int counter = 0;
      for (int k = i; k < CONSECUTIVE_CONNECTION_REQUIRED + i; k++)
      {
        if (grid[k][j] == playerType)
          counter++;
      }

      if (counter == CONSECUTIVE_CONNECTION_REQUIRED)
        return true;
    }
  }

  // Check across
  for (int i = 0; i <= COLUMNS - CONSECUTIVE_CONNECTION_REQUIRED; i++)
  {
    for (int j = 0; j < ROWS; j++)
    {
      int counter = 0;
      for (int k = i; k < CONSECUTIVE_CONNECTION_REQUIRED + i; k++)
      {
        if (grid[j][k] == playerType)
          counter++;
      }

      if (counter == CONSECUTIVE_CONNECTION_REQUIRED)
        return true;
    }
  }

  // Check left to right diagonally
  for (int i = 0; i <= ROWS - CONSECUTIVE_CONNECTION_REQUIRED; i++)
  {
    for (int j = 0; j <= COLUMNS - CONSECUTIVE_CONNECTION_REQUIRED; j++)
    {
      int counter = 0;
      for (int k = i, m = j; k < CONSECUTIVE_CONNECTION_REQUIRED + i; k++, m++)
      {
        if (grid[k][m] == playerType)
          counter++;
      }

      if (counter == CONSECUTIVE_CONNECTION_REQUIRED)
        return true;
    }
  }

  // Check right to left diagonally
  for (int i = 0; i <= ROWS - CONSECUTIVE_CONNECTION_REQUIRED; i++)
  {
    for (int j = COLUMNS - 1; j >= COLUMNS - CONSECUTIVE_CONNECTION_REQUIRED; j--)
    {
      int counter = 0;
      for (int k = i, m = j; k < CONSECUTIVE_CONNECTION_REQUIRED + i; k++, m--)
      {
        if (grid[k][m] == playerType)
          counter++;
      }

      if (counter == CONSECUTIVE_CONNECTION_REQUIRED)
        return true;
    }
  }

  return false;
}

其中 playerType 是 0、1、2、3 等等...

您可以使用checkGrid() 方法,如下所示:

for(int i = MIN_PLAYER_NUMBER; i <= MAX_PLAYER_NUMBER; i++)
{
  if(checkGrid(i))
  {
    // Player i is forming the connection!!!
  }
}

但是,如果您不想多次迭代您的网格,那么请删除您的二维数组,并使用具有邻接表表示的图形。为它编写一个适当的 API,让您可以轻松地更改您的特定表示,然后您可以在更少的迭代中找到是否有任何玩家在图表中建立了特定长度的连接。

【讨论】:

  • 什么是具有邻接表表示的图?
  • @Cammy_the_block:它是一个数据结构。就像数组、列表、地图、集合、树一样,也有图。图可以用多种方式表示,其中一种表示方式是使用邻接表。在互联网上搜索以了解更多信息。
【解决方案2】:

虽然你已经接受了一个答案,但我想也向你提交我的多样性答案:)

public static void main (String[] args)
{
    int[][] myArray = 
    {{1, 2, 3, 0, 0, 1},
     {1, 0, 4, 4, 0, 1},
     {1, 2, 4, 3, 4, 0},
     {2, 2, 0, 0, 2, 2},
     {3, 0, 0, 3, 0, 0},
     {4, 2, 3, 0, 0, 0}};
     System.out.println(testForWinner(myArray));
}

/**
 * Returns -1 if no winner
 */
static int testForWinner(int[][] ar) {
    for(int i=0; i<ar.length; i++) {
        for(int j=0; j<ar[i].length; j++) {
            if(checkNext(ar, i, j, 0, 1, 1)) { //Check the element in the next column
                return ar[i][j];
            }
            for(int k=-1; k<=1; k++) { //Check the three adjacent elements in the next row
                if(checkNext(ar, i, j, 1, k, 1)) {
                    return ar[i][j];
                }
            }
        }
    }
    return -1;
}

/**
 * Step number `step` starting at `ar[i][j]` in direction `(di, dj)`.
 * If we made 3 steps we have a winner
 */
static boolean checkNext(int[][] ar, int i, int j, int di, int dj, int step) {
    if(step==3) {
        return true;
    }
    if(i+di<0 || i+di>ar.length-1 || j+dj<0 || j+dj>ar[i].length-1) {
        return false;
    }
    if(ar[i+di][j+dj]==ar[i][j]) {
        return checkNext(ar, i+di, j+dj, di, dj, step+1);
    }
    return false;
}

查看实际操作:http://ideone.com/Ou2sRh

【讨论】:

  • 我不明白整个步骤的事情。您总是以 step 为一步进行 checkNext。另外,您的解决方案对我来说太混乱了。 :P
  • @Cammy_the_block 在checkNext 内部,我使用step+1 递归调用该方法。这样我沿着一个方向走,直到我沿着 3 个相等的值走了 3 步。我的目标是为我的解决方案使用递归:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-16
  • 2017-05-30
  • 2012-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多