Four in a row logic

前端 未结 2 669
逝去的感伤
逝去的感伤 2020-12-16 23:15

I\'m currently working on a basic four in a row game for myself, but I\'m rather stuck at the logic behind it.

Currently I have this multi-dimensional array that rep

相关标签:
2条回答
  • 2020-12-16 23:29

    I had developed four in a row game some time back. Here is the code snippet to check for winning condition that is four in a row condition : (This is in C language)

    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;
    }
    
    0 讨论(0)
  • 2020-12-16 23:32

    Best bet is to probably divide the search space into four:

    • vertical;
    • horizontal;
    • right and down;
    • right and up.

    then limit your starting and ending coordinates based on the direction.

    For example, let's say your array is board[row=0-5][col=0-6] with board[0][0] at the top left.

    First vertical (loops are inclusive at both ends in this pseudo-code):

    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]
    

    This limits the possibilities to only those that don't extend off the edge of the board, a problem most solutions have when they simplistically start by checking each cell and going out in all directions from there. By that, I mean there's no point checking a start row of 3, simply because that would involve rows 3, 4, 5 and 6 (the latter which does not exist).

    Similarly, for horizontal:

    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 right and down, followed by right and up:

    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]
    

    Now, you could actually combine those two by making for col = 0 to 3 the outer loop and only doing it once rather than twice but I actually prefer to keep them separate (with suitable comments) so that it's easier to understand. However, if you're addicted to performance, you can try:

    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]
    

    Then, if no wins were found in the four possible directions, simply return 0 instead of the winner 1 or 2.

    So, for example, your sample board:

    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
    

    would detect a winner in the right and up loop where the starting cell was {5,1} because {5,1}, {4,2}, {3,3} and {2,4} are all set to 1.

    0 讨论(0)
提交回复
热议问题