使用随机板尺寸对角地循环通过2D阵列

时间:2014-08-02 17:33:25

标签: c++ pointers for-loop multidimensional-array heap

我想知道如果数组的大小是随机的,我可以循环通过一个二维数组,例如6x6或10x10等。想法是搜索四个相同类型的字符,' x&# 39;或者' o'。这通常是棋盘游戏所必需的。

    int main() {
            int array_size = 5; // Size of array
            int array_height = array_size;
            bool turn = true;           // true = player 1, false = player 2
            bool there_is_a_winner = false;
            char** p_connect_four = new char*[array_size];

            for (int i = 0; i < array_size; i++) // Initialise the 2D array
            { // At the same time set a value "_" as blank field
                 p_connect_four[i] = new char[array_size];
                 for (int j = 0; j < array_size; j++) {
                      p_connect_four[i][j] = '_';
                 }
            }
}

这是我到目前为止,检查从[3] [0]到[0] [3]。但这需要我再添加2个循环来检查[4] [0]到[0] [4]和[4] [1]到[1] [4]如果电路板的大小是5x5。

for (int i = 3, j = 0; i > 0 && j < array_size; i--, j++ ) {// CHECK DOWN up right from 3,0 -> 0,3
     if (p_connect_four[i][j] == p_connect_four[i - 1][j + 1] && p_connect_four[i][j] != '_' ) {
         check_diagonalRight++;
         if (check_diagonalRight == 3) {
             there_is_a_winner = true;
             break;
         }
     } 
     else {
             check_diagonalRight = 0;
     }
}
if (there_is_a_winner) { // Break while loop of game.
    break;
}

显然,无论电路板的尺寸如何,我都要沿着对角线检查整个电路板。除了有3个单独的for循环进行检查之外,还有其他方法 [3] [0] - &gt; [0] [3],[4] [0] - &gt; [0] [4]和[4] [1] - &gt; [1] [4]?

3 个答案:

答案 0 :(得分:1)

for (i = array_size - 1, j = array_size - 2;
     i < array_size && i >= 0, j < array_size && j >= 0; j--)
{ // starts from [4][3] and loops to the left if arraysize = 5x5
      // but works on any size
     int k = i, l = j;

     for (k, l; k < array_size && k > 0, l < array_size && l > 0; k--, l++)
     {  // checks diagonally to the right
          if (check_diagonalRight == 3)
          {
              there_is_a_winner = true;
              break;
          }
          if (p_connect_four[k][l] == p_connect_four[k - 1][l + 1] &&
              p_connect_four[k][l] != '_')
          { //check up one square and right one square
              check_diagonalRight++;
          }
          else
          {
              check_diagonalRight = 0;
              // if its not equal, reset counter.
          }
     }
     if (there_is_a_winner) 
     {
         break; // break for loop
     }
}
if (there_is_a_winner)
{
    break; // break while loop of game
}

无论大小如何,都可以向上检查,也可以在其他角度进行检查,它适用于任何板尺寸。您可以使用嵌套循环一次检查左右对角线。

答案 1 :(得分:0)

这对你的程序来说非常合适!希望如此!

int arraySize = 8;

for(int i=0, j=0; i<arraySize && j<arraySize; i++, j++)
{
    if((i == 0 && j == 0) || (i == arraySize - 1 && j == arraySize - 1))
    {
        continue;
    }
    else
    {
        int k = i;
        int l = j;
        //This Loop will check from central line (principal diagonal) to up right side (like slash sign / (representing direction))
        for(k, l; k>0 && l < arraySize - 1; k--, l++)
        {
            //Here check your condition and increment to your variable. like:
            if (p_connect_four[k][l] == p_connect_four[k - 1][l + 1] && p_connect_four[k][l] != '_' )
            {
                check_diagonalRight++;
            }
        }
        //You can break the loop here if check_diagonalRight != k then break
        k = i;
        l = j;
        //This Loop will check from central line (principal diagonal) to down left side (like slash sign / (representing direction))
        for(k, l; k<arraySize - 1 && l > 0; k++, l--)
        {
            //Here check your condition and increment to your variable. like:
            if (p_connect_four[k][l] == p_connect_four[k + 1][l - 1] && p_connect_four[k][l] != '_' )
            {
                check_diagonalRight++;
            }
        }
        if(check_diagonalRight == i+j+1)
        {
            there_is_a_winner = true;
            break;
        }
    }
}

答案 2 :(得分:0)

我建议用额外的特殊情况围绕你的电路板以避免检查绑定。

为了测试每个方向,我建议使用一个偏移数组来应用。

以下可能会有所帮助:

#include <vector>

using board_t = std::vector<std::vector<char>>;

constexpr const std::size_t MaxAlignment = 4;

enum Case {
    Empty = '_',
    X = 'X',
    O = 'O',
    Bound = '.'
};

enum class AlignmentResult { X, O, None };

// Create a new board, valid index would be [1; size] because of surrounding.
board_t new_board(std::size_t size)
{
    // Create an empty board
    board_t board(size + 2, std::vector<char>(size + 2, Case::Empty));

    // Add special surround.
    for (std::size_t i = 0; i != size + 2; ++i) {
        board[0][i] = Case::Bound;
        board[size + 1][i] = Case::Bound;
        board[i][0] = Case::Bound;
        board[i][size + 1] = Case::Bound;
    }
    return board_t;
}

// Test a winner from position in given direction.
AlignmentResult test(
    const board_t& board,
    std::size_t x, std::size_t y,
    int offset_x, int offset_y)
{
    if (board[x][y] == Case::Empty) {
        return AlignmentResult::None;
    }
    for (std::size_t i = 1; i != MaxAlignment; ++i) {
        // Following condition fails when going 'out of bound' thanks to Case::Bound, 
        // else you have also to check size...
        if (board[x][y] != board[x + i * offset_x][y + i * offset_y]) {
            return AlignmentResult::None;
        }
    }
    if (board[x][y] == Case::X) {
        return AlignmentResult::X;
    } else {
        return AlignmentResult::O;
    }
}

// Test a winner on all the board
AlignmentResult test(const board_t& board)
{
    // offset for direction. Use only 4 direction because of the symmetry.
    const int offsets_x[] = {1, 1, 1, 0};
    const int offsets_y[] = {-1, 0, 1, 1};
    const std::size_t size = board.size() - 1;

    for (std::size_t x = 1; x != size; ++x) {
        for (std::size_t y = 1; y != size; ++y) {
            for (std::size_t dir = 0; dir != 4; ++dir) { // for each directions
                auto res = test(board, x, y, offsets_x[dir], offsets_y[y]);
                if (res != AlignmentResult::None) {
                    return res;
                }
            }
        }
    }
    return AlignmentResult::None;
}