8

我目前正在为自己制作一个基本的连续四场比赛,但我相当卡在它背后的逻辑上。

目前我有这个代表棋盘的多维数组

[
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0]
]

0将代表一个空槽,而12代表一个玩家。所以让我们说一段时间后你得到这个数组:

[
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 1, 1, 0, 0],
    [0, 0, 0, 1, 1, 0, 0],
    [0, 0, 1, 2, 2, 2, 0],
    [0, 1, 2, 2, 1, 2, 0]
]

如何编写逻辑来检查是否连续有四个?为水平和垂直计算它似乎很容易(尽管仍然找出最好的方法),但我将如何为对角线做到这一点?

4

2 回答 2

16

最好的办法是将搜索空间分成四个:

  • 垂直的;
  • 水平的;
  • 向右和向下;
  • 正确和向上。

然后根据方向限制您的起点和终点坐标。

例如,假设您的数组位于board[row=0-5][col=0-6]左上角board[0][0]

第一个垂直(在此伪代码的两端都包含循环)

for row = 0 to 2:
    for col = 0 to 6:
        if board[row][col] != 0 and
           board[row][col] == board[row+1][col] and
           board[row][col] == board[row+2][col] and
           board[row][col] == board[row+3][col]:
               return board[row][col]

这将可能性限制在那些不超出电路板边缘的范围内,这是大多数解决方案在简单地从检查每个单元格开始并从那里向各个方向延伸时都会遇到的问题。我的意思是,检查第 3 行的起始行是没有意义的,因为这将涉及第 3、4、5 和 6 行(后者不存在)。

同样,对于水平:

for row = 0 to 5:
    for col = 0 to 3:
        if board[row][col] != 0 and
           board[row][col] == board[row][col+1] and
           board[row][col] == board[row][col+2] and
           board[row][col] == board[row][col+3]:
               return board[row][col]

对于右和下,然后是右和上:

for row = 0 to 2:
    for col = 0 to 3:
        if board[row][col] != 0 and
           board[row][col] == board[row+1][col+1] and
           board[row][col] == board[row+2][col+2] and
           board[row][col] == board[row+3][col+3]:
               return board[row][col]

for row = 3 to 5:
    for col = 0 to 3:
        if board[row][col] != 0 and
           board[row][col] == board[row-1][col+1] and
           board[row][col] == board[row-2][col+2] and
           board[row][col] == board[row-3][col+3]:
               return board[row][col]

现在,您实际上可以通过制作外循环并只执行一次而不是两次来将这两者结合起来for col = 0 to 3,但我实际上更喜欢将它们分开(带有适当的注释),以便更容易理解。但是,如果您沉迷于性能,您可以尝试:

for col = 0 to 3:
    for row = 0 to 2:
        if board[row][col] != 0 and
           board[row][col] == board[row+1][col+1] and
           board[row][col] == board[row+2][col+2] and
           board[row][col] == board[row+3][col+3]:
               return board[row][col]
    for row = 3 to 5:
        if board[row][col] != 0 and
           board[row][col] == board[row-1][col+1] and
           board[row][col] == board[row-2][col+2] and
           board[row][col] == board[row-3][col+3]:
               return board[row][col]

然后,如果在四个可能的方向上都没有找到胜利,则只需返回0而不是胜利者12

因此,例如,您的示例板:

row
 0   [0, 0, 0, 0, 0, 0, 0]
 1   [0, 0, 0, 0, 0, 0, 0]
 2   [0, 0, 0, 1, 1, 0, 0]
 3   [0, 0, 0, 1, 1, 0, 0]
 4   [0, 0, 1, 2, 2, 2, 0]
 5 > [0, 1, 2, 2, 1, 2, 0]
         ^
      0  1  2  3  4  5  6 <- col

将在起始单元格所在的右侧和向上循环中检测到获胜者,因为 ,{5,1}{5,1}都设置为.{4,2}{3,3}{2,4}1

于 2013-03-17T05:27:47.237 回答
2

前段时间我开发了四个连续游戏。这是检查连续四个条件的获胜条件的代码片段:(这是用 C 语言编写的)

int checkWinOrLose(int grid[][7],int result,int rowNum) {
//  For checking whether any win or lose condition is reached. Returns 1 if win or lose is reached. else returns 0
//  grid[][] is the 6X7 matrix
//  result is the column number where the last coin was placed
//  rowNum is the row number where the last coin was placed

    int player=grid[rowNum][result];
    if(rowNum<=2 && grid[rowNum+1][result]==player && grid[rowNum+2][result]==player && grid[rowNum+3][result]==player) // 4 in a row vertically
        return 1;
    else {
        int count=1,i,j;
        for(i=result+1;i<7;i++) { // 4 in a row horizontally
            if(grid[rowNum][i]!=player)
                break;
            count++;
        }
        for(i=result-1;i>=0;i--) { // 4 in a row horizontally
            if(grid[rowNum][i]!=player)
                break;
            count++;
        }
        if(count>=4)
            return 1;
        count=1;
        for(i=result+1,j=rowNum+1;i<7 && j<6;i++,j++) { // 4 in a row diagonally
            if(grid[j][i]!=player)
                break;
            count++;
        }
        for(i=result-1,j=rowNum-1;i>=0 && j>=0;i--,j--) { // 4 in a row diagonally
            if(grid[j][i]!=player)
                break;
            count++;
        }
        if(count>=4)
            return 1;
        count=1;
        for(i=result+1,j=rowNum-1;i<7 && j>=0;i++,j--) { // 4 in a row diagonally
            if(grid[j][i]!=player)
                break;
            count++;
        }
        for(i=result-1,j=rowNum+1;i>=0 && j<6;i--,j++) { // 4 in a row diagonally
            if(grid[j][i]!=player)
                break;
            count++;
        }
        if(count>=4)
            return 1;
    }
    return 0;
}
于 2013-03-17T05:44:39.413 回答