Win conditions for a connect-4 like game

后端 未结 3 1623
时光说笑
时光说笑 2021-01-06 16:48

I have an 5x10 array that is populated with random values 1-5. I want to be able to check when 3 numbers, either horizontally, or vertically, match. I can\'t figure out a wa

相关标签:
3条回答
  • 2021-01-06 17:01

    I think this should work ; If any one point out the mistake, I would be happy to correct.

    for( int row = 0; row<8 ; ++row )
    {
        bool outerLoopBreakFlag = false ;
        for( int col=0 ; col<3; ++col )
        {
             // check for the winning conditions
             // i.e., board[row][col] == board[row][col+1] == board[row][col+2]
             //       board[row][col] == board[row+1][col] == board[row+2][col]
             //       if any one is satisfied, set the outerLoopBreakFlag to true
             else
                 break ;
        }
        if( outerLoopBreakFlag == true )
            break ;
    }              
    
    0 讨论(0)
  • 2021-01-06 17:18

    for the record:

    I think you mean

    for(i = 0; i < 5; i++)
    {
        board[row][i] = rand()%5 + 1; 
        cout << board[row][i] << " ";
    }
    

    And since others posted Code, here is how I would do it :

    for(int i = 0 ; i < 8 ; i++)
    {
        for(int j = 0 ; j < 3 ; j++)
        {
    
            if( ((board[i][j] == board[i][j+1]) && (board[i][j+1] == board[i][j+2])))
                std::cout << "Found a horizontal match on " << i << " " << j << std::endl;
    
            if((board[i][j] == board[i+1][j]) && (board[i+1][j] == board[i+2][j]))
                std::cout << "Found a vertical match on " << i << " " << j << std::endl;
        }
    }
    
    0 讨论(0)
  • 2021-01-06 17:19

    Suppose that you have some particular starting point (x, y) and you're curious if there's three equal numbers in a row that start at this point. Let's consider just the case where you're looking in the horizontal direction. Then one way to do this (ignoring bounds-checking) would be like this:

    bool IsHorizontalMatch(int x, int y) {
        /* Get the value of the start position. */
        const int startValue = board[x][y];
    
        /* Confirm the two values after it match. */
        for (int i = 1; i < 3; ++i)
            if (board[x + i][y] != startValue)
                return false;
    
        /* If we got here, then they all match! */
        return true;
    }
    

    You could similarly write a function like this for checking vertically:

    bool IsVerticalMatch(int x, int y) {
        /* Get the value of the start position. */
        const int startValue = board[x][y];
    
        /* Confirm the two values after it match. */
        for (int i = 1; i < 3; ++i)
            if (board[x][y + i] != startValue)
                return false;
    
        /* If we got here, then they all match! */
        return true;
    }
    

    And finally, one for the diagonals:

    bool IsDiagonalDownMatch(int x, int y) {
        /* Get the value of the start position. */
        const int startValue = board[x][y];
    
        /* Confirm the two values after it match. */
        for (int i = 1; i < 3; ++i)
            if (board[x + i][y + i] != startValue)
                return false;
    
        /* If we got here, then they all match! */
        return true;
    }
    
    bool IsDiagonalUpMatch(int x, int y) {
        /* Get the value of the start position. */
        const int startValue = board[x][y];
    
        /* Confirm the two values after it match. */
        for (int i = 1; i < 3; ++i)
            if (board[x + i][y - i] != startValue)
                return false;
    
        /* If we got here, then they all match! */
        return true;
    }
    

    This works, but it's just not very elegant; all three of these functions look very similar! Fortunately, you can rewrite all of them in terms of a single unifying function. The idea is this - if you'll notice, all three functions work by having some "step size" defined indicating what direction you move. In the horizontal case, the step is (+1, +0), in the vertical case it's (+0, +1), and in the diagonal it's (+1, +1) or (+1, -1). Given this, you can write one function to check if three values match in a line:

    bool IsLinearMatch(int x, int y, int stepX, int stepY) {
        /* Get the value of the start position. */
        const int startValue = board[x][y];
    
        /* Confirm the two values after it match. */
        for (int i = 1; i < 3; ++i)
            if (board[x + i * stepX][y + i * stepY] != startValue)
                return false;
    
        /* If we got here, then they all match! */
        return true;
    }
    

    You can then write

    bool IsLineStartingAt(int x, int y) {
        return (IsLinearMatch(x, y, 1,  0) ||  // Horizontal
               IsLinearMatch(x, y, 0,  1)  ||  // Vertical
               IsLinearMatch(x, y, 1,  1)  ||  // Diagonal Down
               IsLinearMatch(x, y, 1, -1));    // Diagonal Up
    }
    

    Given this primitive, you can check for all possible matches by just iterating over all possible starting points.

    Hope this helps!

    EDIT: Thanks to commenters for helping to fix my silly bugs. :-)

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