四连胜逻辑

时间:2013-03-17 05:19:23

标签: c algorithm

我目前正在为自己制作一个基本的四连胜游戏,但我却坚持其背后的逻辑。

目前我有这个代表董事会的多维数组

[
    [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]
]

如何编写逻辑以检查连续四行? 计算它的水平和垂直似乎相当容易(虽然仍然找出最佳方法),但我如何为对角线做这个?

2 个答案:

答案 0 :(得分:13)

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

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

然后根据方向限制起始坐标和结束坐标。

例如,假设您的数组位于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

答案 1 :(得分: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;
}