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

时间:2016-02-03 05:31:58

标签: 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;
}

2 个答案:

答案 0 :(得分:3)

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

  • 选择要搜索的偏移量,例如-1,-1以对角线搜索
  • 表示该偏移量:
    • 检查与目标单元格偏移的单元格是否为相同颜色。
    • 如果是,则递增计数器并再次执行相同的测试 在偏移单元的偏移处(这里有一点递归)
    • 当你撞墙或者同色单元格的数量大于或等于connectedPiecesToWin时停止。 \编辑
  • 选择下一个偏移量(-1,0),(0,-1),(1,1)等
  • 如果你搜索所有八个方向并且没有获得胜利归来假。

那个例程就是搜索整个棋盘获胜单元格的关键,或者只是检查刚刚进行的移动是否创造了胜利。

或者我错过了什么?

答案 1 :(得分:2)

由于这显然是家庭作业,我会在不提供实际代码的情况下为您提供天真的策略。

对于(x,y)的任何位置,如果有四个相同颜色的水平,垂直或对角排列,则会成为赢家。因此,让我们来看看RED在水平上获胜的情况:

(x,y)    (x+1,y)  (x+2,y)  (x+3,y)
RED      RED      RED      RED

类似的坐标算法适用于其他安排。所以你真的需要查看数组中的每个位置,从(0,0)(width-4,height-4)(除了一个对角线情况)它在不同的范围内运行)并进行&#34; win-test&#34;从那个位置开始。

更聪明的胜利测试只会检查最近播放的作品周围的区域。