四连胜逻辑

问题描述 投票:5回答:2

我现在正在为自己开发一个基本的四连胜游戏,但我更倾向于坚持它背后的逻辑。

目前我有这个代表电路板的多维数组

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

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

c algorithm
2个回答
12
投票

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

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

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

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


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;
}
© www.soinside.com 2019 - 2024. All rights reserved.