c++ - 在 connect 4 C++ 算法中检查获胜者

标签 c++ algorithm

我已经处理这些代码数小时了,但我一直卡在这段代码所需的算法上。我讨厌成为那个发布整个代码的人,但我觉得这是必要的,这样你才能理解它。我完全不知道如何检查获胜者。我在想它可以递归完成,但在与一些人交谈后他们说这不是最好的方法。我完全不知道如何解决这个问题。

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <time.h>
#include <iostream>

/**
 * @brief Check if a winner exists
 *
 * @param pBoard The board
 * @param colSize The column size
 * @param rowSize The row size
 *
 * @return The character of the winner, 0 for no winner, and 't' for a tie
 */
char checkWinner(char** pBoard, int colSize, int rowSize, int winSize) {
    // TODO

    **This is where the algorithm needs to go.**

    return 0;
}
/**
 * @brief Place a piece onto the board
 *
 * @param pBoard The game board
 * @param colSize The column size
 * @param rowSize the row size
 * @param columnSelection The column selection
 * @param player The players characterS
 *
 * @return True if the piece was placed, else false
 */
bool placePiece(char** pBoard, int colSize, int rowSize, int columnSelection, char player)
{
    // TODO
    int row = rowSize-1;

    while (pBoard[row][columnSelection]!= ' ' && row > 0){
        row--;
    }

    std::cout << row << std::endl;

    if (pBoard[row][columnSelection] == ' ') {
        pBoard[row][columnSelection] = player;
        return true;
    }   else{
        std::cout << "The space is full." << std::endl;
        return false;
    }

}

/**
 * @brief Print out the game board
 *
 * @param pBoard The game board
 * @param colSize The column size
 * @param rowSize The row size
 */
void printBoard(char** pBoard, int colSize, int rowSize) {

    for (int i = 0; i <= rowSize; ++i){
    std::cout << "|" << i;
    }

    std:: cout << "|" << std::endl;

    for (int i = 0; i < rowSize; ++i){
        std::cout << "|";
        for (int j = 0; j < colSize; ++j){
            std::cout << pBoard[i][j] << "|";
        }
        std::cout << std::endl;
    }
    std::cout << std::endl;
}

int main()
{
    bool running = true;
    printf("Welcome to connect four!\n");
    srand (time(NULL));

    int32_t connectedPiecesToWin = 0;
    int32_t rowSize = 0;
    int32_t colSize = 0;

    // setup game
    std::cout << "How many connected pieces does it take to win?" << std::endl;
    std::cin >> connectedPiecesToWin;

    rowSize = connectedPiecesToWin + 2;
    colSize = connectedPiecesToWin + 3;

    std::cout << "You have selected " << connectedPiecesToWin << " in a row with a game board of " << colSize
<< " x " << rowSize << std::endl;

    // setup board
    char** pBoard = NULL; // TODO create the game board


    // initialize board

    pBoard = new char*[rowSize];

    for (int i = 0; i < rowSize; ++i){
        pBoard[i] = new char[colSize];
    }

    for(int i = 0; i < rowSize; ++i){
        for(int j = 0; j < colSize; ++j){
            pBoard[i][j]= ' ';
        }
    }


    // play
    char winner = 0;
    char player = 'p';
    do
    {
        int columnChoice = 0;

        do
        {
            if (player == 'p')
            {
                printBoard(pBoard, colSize, rowSize);
                std::cout << "Player's column: ";
                std::cin >> columnChoice;
            }
            else
            {
                // computers turn
                columnChoice = rand() % colSize;
            }
        } while (!placePiece(pBoard, colSize, rowSize, columnChoice, player));

        winner = checkWinner(pBoard, colSize, rowSize, connectedPiecesToWin);
        player = (player == 'c') ? 'p' : 'c';
    } while (running && winner == 0);

    printBoard(pBoard, colSize, rowSize);

    if (winner == 't')
    {
        std::cout << "Too bad, the game was a tie!" << std::endl;
    }
    else if (winner == 'c')
    {
        std::cout << "Oh man, you lost to a computer that randomly places pieces!" << std::endl;
    }
    else
    {
        std::cout << "Congrats! You won!" << std::endl;
    }

    // cleanup
    // TODO cleanup the board

    for (int i = 0; i < rowSize; ++i){
        delete[] pBoard[i];
    }
    delete[] pBoard;

    return 0;
}

最佳答案

蛮力方法是测试每个单元格,看看它是否在任何有效方向上连接到 connectedPiecesToWin 棋子,因此首先编写一个例程,如果 0,0 处的单元格是获胜单元格,它将返回 true:

  • 选择一个偏移量进行搜索,比如 -1,-1 对角线搜索
  • 对于那个偏移量:
    • 检查与目标单元格偏移处的单元格颜色是否相同。
    • 如果是,增加一个计数器并再次执行相同的测试 在偏移单元格的那个偏移处(这里有一点递归)
    • 当您撞墙或同色单元格的数量大于或等于 connectedPiecesToWin 时停止。\编辑
  • 选择下一个偏移量 (-1,0)、(0,-1)、(1,1) 等。
  • 如果您搜索了所有八个方向但没有获胜,则返回 false。

然后,该例程是在整个棋盘上搜索获胜单元格或仅检查刚刚采取的行动是否创造了胜利的关键。

还是我遗漏了什么?

关于c++ - 在 connect 4 C++ 算法中检查获胜者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35169200/

相关文章:

c++ - C++中 vector 的通用 vector

c++ - Freebsd 的 Makemkv

c++ - 如何增长 GL_TEXTURE_2D_ARRAY?

java - 在数组中找到 3 个或更多相同的对象?

algorithm - 生产者消费者与信号量

javascript - 从具有特定元素的动态字符串创建数组

c++ - 在 C 和我的语言之间创建 FFI

c++ - 友元是在 C++ 中继承的吗?

java - 来自随机值的 Minimax 结果给出了意想不到的低结果

algorithm - 求出他们靠在一起能达到的最大高度?