时间:2019-02-08 标签:c++gomokudiagonalchecker

c++ Gomoku diagonal checker

所以我是一个相对较新的编码。所以我必须为一个项目制作一个五子棋游戏。 Gomoku 就像井字游戏,但必须连续获得五个。已经给出了某些限制,例如 6x6 到 15x15 的电路板尺寸。至少使用一个class。我选择使用数组。我已经将 PlayerOne 创建为一种算法,该算法基于 PlayerOne 的最后一步移动,并在下一步移动中将一个随机方块从它移开。第二种算法是随机的。在检查获胜时,我的水平和垂直跳棋似乎可以工作,但我的两个对角线跳棋都出现问题,他们说对角线上连续 3 个连续的块是连续 5 个。我单独创建了我的跳棋,手动填写每一行进行测试,对角线跳棋在那里很好,但它们在整个代码中并不好。 我将在这里分享对角线跳棋,然后在下面分享整个代码,希望更容易阅读。它也有相当多的 cout 语句,因为它试图在过程的早期找出问题所在。如果有人能看到问题发生的地方并指出问题所在,将不胜感激。

int game::diagonalCheckerNegSlope(int arr[15][15], int size) {
    int count1;
    int count2;
    int whoWon = 0;

    for (int i = 0; i < size; i++) {
        count1 = 0;
        count2 = 0;
        for (int j = 0; j < size; j++) {
            if (arr[j][i] == 1) {

                for (int d = 0; (i + d < size) && (j + d < size); d++)
                    if (arr[i + d][j + d] == 1) {
                        count1++;
                        if (count1 == 5) {
                            whoWon = 1;
                        }
                    } else {
                        count1 = 0;
                    }

            }
            if (arr[j][i] == 2) {

                for (int d = 0; (i + d < size) && (j + d < size); d++)
                    if (arr[i + d][j + d] == 2) {
                        count2++;
                        if (count2 == 5) {
                            whoWon = 2;
                        }
                    } else {
                        count2 = 0;
                    }

            }

        }

    }
    if (whoWon != 1 && whoWon != 2) {
        whoWon = 3;
    }

    return whoWon;
}

int game::diagonalCheckerPosSlope(int arr[15][15], int size) {
    int count1;
    int count2;
    int whoWon = 0;

    for (int i = 0; i < size; i++) {
        count1 = 0;
        count2 = 0;
        for (int j = 0; j < size; j++) {
            if (arr[i][j] == 1) {

                for (int d = 0; (i + d < size) && (j - d < size); d++)
                    if (arr[i + d][j - d] == 1) {
                        count1++;
                        if (count1 == 5) {
                            whoWon = 1;
                        }
                    } else {
                        count1 = 0;
                    }

            }
            if (arr[i][j] == 2) {

                for (int d = 0; (i + d < size) && (j - d < size); d++)
                    if (arr[i + d][j - d] == 2) {
                        count2++;
                        if (count2 == 5) {
                            whoWon = 2;
                        }
                    } else {
                        count2 = 0;
                    }
            }
        }

    }
    if (whoWon != 1 && whoWon != 2) {
        whoWon = 3;
    }
    return whoWon;
}

int 主代码

#include <iostream>
#include <fstream>
#include "game.h"
#include <iomanip>
#include <ctime>
using namespace std;



int main() {
    string inputSize = "input.txt";
    int size =0;
    srand(time(0));

    int arr[15][15];

    game Gomuko;

    size = Gomuko.getSize(inputSize, arr);
    if(size >=6 && size <=15){

    Gomuko.initZero(arr, size);
//  Gomuko.printArr(arr,size);

    Gomuko.Play(arr, size);

    Gomuko.printArr(arr,size);

    }else{
        cout << "Invalid input" << endl;
    }


    return 0;
}

class

的.h文件
#ifndef GAME_H_
#define GAME_H_

#include <string>
#include <ctime>
using namespace std;

class game {
public:
    game();
    int getSize(string inputFileName, int dataArray[15][15]);
    void initZero(int arr[15][15], int size);
    void printArr(int arr[15][15], int size);
    void movePlayerOne(int arr[15][15], int size, int counter2);
    void movePlayerTwo(int arr[15][15], int size);
    void Play(int arr[15][15], int size);
    int PlayerOneSurroundRow(int arr[15][15],int size);
    int PlayerOneSurroundCol(int arr[15][15],int size);
    int findFirstMoveRow(int arr[15][15], int size);
    int findFirstMoveCol(int arr[15][15], int size);
    bool isValid(int newRow, int newCol, int size);
    int horizontalChecker(int arr[15][15], int size);
    int verticalChecker(int arr[15][15], int size);
    int diagonalCheckerNegSlope(int arr[15][15], int size);
    int diagonalCheckerPosSlope(int arr[15][15], int size);
    int WholeWinnerChecker(int arr[15][15], int size);
private:

    int randRow(int size);
    int randCol(int size);
};

#endif /* GAME_H_ */

最后是 class

的 .cpp 文件
#include "game.h"
#include <iostream>
#include <fstream>
#include <iomanip>
#include <ctime>
using namespace std;

game::game() {
    // TODO Auto-generated constructor stub

}

int game::getSize(string inputFileName, int dataArray[15][15]) {//make between 6 and 15.
    ifstream inputData;

    int size = 0;
    int counter = 0;

    inputData.open(inputFileName);

    if (!inputData) {
        cout << "Cannot open the file \"" << inputFileName << "\"" << endl;
    }
    else {
        while (inputData >> size) {
            counter++;
        }
        cout << "There are " << counter << " board sizes in the inputFile"
                << endl;
        cout << "The size of the board is " << size << "x" << size << endl
                << endl;
    }
    return size;
}

void game::initZero(int arr[15][15], int size) {
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            arr[i][j] = 0;
        }
    }
}

void game::printArr(int arr[15][15], int size) {

    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            cout << arr[i][j] << " ";
        }
        cout << endl;
    }

    cout << endl << endl;
}

int game::randRow(int size) {

    int randNoRow = 0;
    randNoRow = rand() % size;
    return randNoRow;
}

int game::randCol(int size) {

    int randNoCol = 0;
    randNoCol = rand() % size;
    return randNoCol;
}

int game::findFirstMoveRow(int arr[15][15], int size) {
    int positionRow;
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            if (arr[i][j] == 1) {
                positionRow = i;
            }
        }
    }

    return positionRow;
}

int game::findFirstMoveCol(int arr[15][15], int size) {
    int positionCol;
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            if (arr[i][j] == 1) {
                positionCol = j;
            }
        }
    }

    return positionCol;
}

int game::PlayerOneSurroundRow(int arr[15][15], int size) {

    int positionRow = game::findFirstMoveRow(arr, size);
//  cout << "The old row is " << positionRow << endl;

    int oldRow = positionRow;
    int randChoice = 0;
    int newRow = 0;

    randChoice = (rand() % 3);
//  cout << "randChoice Row case:  " << randChoice << endl;

    switch (randChoice) {
    case 0:
        newRow = oldRow - 1;
        break;
    case 1:
        newRow = oldRow;
        break;
    case 2:
        newRow = oldRow + 1;
        break;
    }
//  cout << "Test2" << endl << endl;
    if (newRow > size - 1) {
//      cout << "Row too big as Row is " << newRow << endl;
        newRow = newRow - 1;
//      cout << "Row is now " << newRow << endl;

    }
    if (newRow < 0) {
//      cout << "Row too small as row is " << newRow << endl;
        newRow = newRow + 1;
//      cout << "Row is now " << newRow << endl;

    }

//  cout << "The new row is: " << newRow << endl;

    return newRow;
}

int game::PlayerOneSurroundCol(int arr[15][15], int size) {

    int positionCol = findFirstMoveCol(arr, size);
//  cout << "The old col is " << positionCol << endl;

    int oldCol = positionCol;
    int randChoice = 0;
    int newCol = 0;

    randChoice = (rand() % 3);
    cout << "randChoice Col case: " << randChoice << endl;

    switch (randChoice) {
    case 0:
        newCol = oldCol - 1;
        break;
    case 1:
        newCol = oldCol;
        break;
    case 2:
        newCol = oldCol + 1;
        break;
    }
//  cout << "Test2" << endl << endl;
    if (newCol > size - 1) {
//      cout << "Col too big as is " << newCol << endl;
        newCol = newCol - 1;
//      cout << "Col is now " << newCol << endl;
    }
    if (newCol < 0) {
//      cout << "Col too small as is " << newCol << endl;
        newCol = newCol + 1;
//      cout << "Col is now " << newCol << endl;

    }

//  cout << "The new col is: " << newCol << endl;

    return newCol;
}

bool game::isValid(int newRow, int newCol, int size) {
    bool valid = false;
    if (((newRow < size) && (newCol < size))
            && ((newRow >= 0) && (newCol >= 0))) {
        valid = true;
    }
    return valid;
}

void game::movePlayerOne(int arr[15][15], int size, int counter2) {

    int newRow = 0;
    int newCol = 0;
    int oldRow = 0;
    int oldCol = 0;
    int count3 = 0;

    if (counter2 == 0) {
        oldRow = randRow(size);
        oldCol = randCol(size);

        arr[oldRow][oldCol] = 1;
//      cout << "Test1" << endl << endl << endl;
        counter2++;
    }

    else {

//      cout << "Test 3" << endl;

        newRow = game::PlayerOneSurroundRow(arr, size);
        newCol = game::PlayerOneSurroundCol(arr, size);

        if (arr[newRow][newCol] == 0 && isValid(newRow, newCol, size)) {
            arr[newRow][newCol] = 1;
//          cout << "Test4" << endl;
//          cout << "randNoRow = " << newRow << endl;
//          cout << "randNoCol = " << newCol << endl;

            oldRow = newRow;
            oldCol = newCol;
        }

        else if ((arr[newRow][newCol] == 1) || (arr[newRow][newCol] == 2)
                || (newRow > size) || (newCol > size) || (newRow < 0)
                || (newCol < 0)) {
            cout
                    << "There has been a match, or even out of bounds, going again. "
                    << endl << endl;

            while ((arr[newRow][newCol] == 1) || (arr[newRow][newCol] == 2)) {

//              cout << "Test5" << endl;
                newRow = game::PlayerOneSurroundRow(arr, size);
                newCol = game::PlayerOneSurroundCol(arr, size);

//              cout << "randNoRow = " << newRow << endl;
//              cout << "randNoCol = " << newCol << endl;

                count3++;
                if ((arr[newRow][newCol] != 1 && arr[newRow][newCol] != 2)
                        && isValid(newRow, newCol, size)) {
                    arr[newRow][newCol] = 1;
//                  cout << "Test6" << endl;
//
//                  cout << "randNoRow = " << newRow << endl;
//                  cout << "randNoCol = " << newCol << endl;

                    oldRow = newRow;
                    oldCol = newCol;
                    break;
                }

                if (count3++ > 3) {
//                  cout << "Test 7" << endl;
//                  newRow = randRow(size);
//                  newCol = randCol(size);
                    while (arr[newRow][newCol] == 1 || arr[newRow][newCol] == 2) {
                        newRow = randRow(size);
                        newCol = randCol(size);
//                      cout << "Test 8" << endl;
//                      cout << "randNoRow = " << newRow << endl;
//                      cout << "randNoCol = " << newCol << endl;

                        if (arr[newRow][newCol] == 0) {
                            arr[newRow][newCol] = 1;
//                          cout << "Test 9" << endl;
//                          cout << "randNoRow = " << newRow << endl;
//                          cout << "randNoCol = " << newCol << endl;
                            oldRow = newRow;
                            oldCol = newCol;
                            break;
                        }
                    }

                    break;
                }
            }

        }
    }
}

void game::movePlayerTwo(int arr[15][15], int size) {

//  cout << "Test" << endl;

    int randNoRow = 0;
    int randNoCol = 0;

    randNoRow = randRow(size);
    cout << "randNoRow = " << randNoRow << endl;

    randNoCol = randCol(size);
    cout << "randNoCol = " << randNoCol << endl;

    cout << endl;

    if ((arr[randNoRow][randNoCol] == 1) || (arr[randNoRow][randNoCol] == 2)) {
        //cout << "There has been a match, going again. " << endl << endl;
        while ((arr[randNoRow][randNoCol] == 1)
                || (arr[randNoRow][randNoCol] == 2)) {

            int randNoRow = 0;
            int randNoCol = 0;

            randNoRow = randRow(size);
            //cout << "randNoRow = " << randNoRow << endl;

            randNoCol = randCol(size);
            //cout << "randNoCol = " << randNoCol << endl;

            //cout << endl;

            if (arr[randNoRow][randNoCol] == 0) {
                arr[randNoRow][randNoCol] = 2;
                break;
            }
        }

    } else {
        arr[randNoRow][randNoCol] = 2;
    }
}

int game::horizontalChecker(int arr[15][15], int size) {
    int count1;
    int count2;
    int whoWon = 0;

    for (int i = 0; i < size; i++) {
        count1 = 0;
        count2 = 0;
        for (int j = 0; j < size; j++) {
            if (arr[i][j] == 1) {
                count1++;
                if (count1 == 5) {
                    whoWon = 1;
                }

            } else {
                count1 = 0;
            }
            if (arr[j][i] == 2) {
                count2++;
                if (count2 == 5) {
                    whoWon = 2;
                }

            } else {
                count2 = 0;
            }

        }
        if (whoWon != 1 && whoWon != 2) {
            whoWon = 3;
        }
    }
    return whoWon;
}

int game::verticalChecker(int arr[15][15], int size) {
    int count1;
    int count2;
    int whoWon = 0;

    for (int i = 0; i < size; i++) {
        count1 = 0;
        count2 = 0;
        for (int j = 0; j < size; j++) {
            if (arr[j][i] == 1) {
                count1++;
                if (count1 == 5) {
                    whoWon = 1;
                }

            } else {
                count1 = 0;
            }
            if (arr[j][i] == 2) {
                count2++;
                if (count2 == 5) {
                    whoWon = 2;
                }

            } else {
                count2 = 0;
            }

        }
        if (whoWon != 1 && whoWon != 2) {
            whoWon = 3;
        }
    }
    return whoWon;
}
int game::diagonalCheckerNegSlope(int arr[15][15], int size) {
    int count1;
    int count2;
    int whoWon = 0;

    for (int i = 0; i < size; i++) {
        count1 = 0;
        count2 = 0;
        for (int j = 0; j < size; j++) {
            if (arr[j][i] == 1) {

                for (int d = 0; (i + d < size) && (j + d < size); d++)
                    if (arr[i + d][j + d] == 1) {
                        count1++;
                        if (count1 == 5) {
                            whoWon = 1;
                        }
                    } else {
                        count1 = 0;
                    }

            }
            if (arr[j][i] == 2) {

                for (int d = 0; (i + d < size) && (j + d < size); d++)
                    if (arr[i + d][j + d] == 2) {
                        count2++;
                        if (count2 == 5) {
                            whoWon = 2;
                        }
                    } else {
                        count2 = 0;
                    }

            }

        }

    }
    if (whoWon != 1 && whoWon != 2) {
        whoWon = 3;
    }

    return whoWon;
}

int game::diagonalCheckerPosSlope(int arr[15][15], int size) {
    int count1;
    int count2;
    int whoWon = 0;

    for (int i = 0; i < size; i++) {
        count1 = 0;
        count2 = 0;
        for (int j = 0; j < size; j++) {
            if (arr[i][j] == 1) {

                for (int d = 0; (i + d < size) && (j - d < size); d++)
                    if (arr[i + d][j - d] == 1) {
                        count1++;
                        if (count1 == 5) {
                            whoWon = 1;
                        }
                    } else {
                        count1 = 0;
                    }

            }
            if (arr[i][j] == 2) {

                for (int d = 0; (i + d < size) && (j - d < size); d++)
                    if (arr[i + d][j - d] == 2) {
                        count2++;
                        if (count2 == 5) {
                            whoWon = 2;
                        }
                    } else {
                        count2 = 0;
                    }
            }
        }

    }
    if (whoWon != 1 && whoWon != 2) {
        whoWon = 3;
    }
    return whoWon;
}

int game::WholeWinnerChecker(int arr[15][15], int size) {
    int finalWinner = 0;
    int outcome1 = horizontalChecker(arr, size);
    if ((outcome1 == 1) || (outcome1 == 2)) {
        finalWinner = outcome1;
        cout << "Horizontal Win" << endl;
    }
    int outcome2 = verticalChecker(arr, size);
    if ((outcome2 == 1) || (outcome2 == 2)) {
        finalWinner = outcome2;
        cout << "Vertical Win" << endl;
    }
    int outcome3 = diagonalCheckerPosSlope(arr, size);
    if ((outcome3 == 1) || (outcome3 == 2)) {
        finalWinner = outcome3;
        cout << "Diag Pos Win" << endl;
    }
    int outcome4 = diagonalCheckerNegSlope(arr, size);
    if ((outcome4 == 1) || (outcome4 == 2)) {
        finalWinner = outcome4;
        cout << "Diag Neg Win" << endl;
    }

    else if ((finalWinner != 1) && (finalWinner != 2)) {
        finalWinner = 3;
    }

    return finalWinner;
}

void game::Play(int arr[15][15], int size) {
    int counter = 0;
    int Winner=0;
    int boardFull= size*size;
        while(((Winner != 1)&&(Winner != 2))&& (counter < boardFull)){
        cout << "This is turn " << counter + 1 << endl;
        if (counter % 2 == 0) {
            cout << "PlayerOne: " << endl;
            game::movePlayerOne(arr, size, counter);
            if (counter >= 4) {
                Winner = game::WholeWinnerChecker(arr, size);
                if(Winner ==1){
                cout << endl <<"======================" << endl;
                cout << "Winner = " << Winner << endl;
                cout <<"======================" << endl;
                }
            }
        }
        if (counter % 2 == 1) {
            cout << "PlayerTwo:" << endl;
            game::movePlayerTwo(arr, size);
            if (counter >= 5) {
                Winner = game::WholeWinnerChecker(arr, size);
                if (Winner == 2) {
                    cout << endl << "======================" << endl;
                    cout << "Winner = " << Winner << endl;
                    cout << "======================" << endl;
                }
            }
        }
        if(counter == boardFull){
            cout << "Draw" << endl;
        }

        counter++;

    }

}

我也一直在使用

的输入
6

问题可能是您没有在 j-loop 中设置 count1count2,而是指望在 else 语句中重置的变量.但是,如果您的 d-loop 在 else 语句执行之前结束((i + d < size) && (j - d < size) “过早地”变为假),则计数器不会重置。解决方案:将 zero-initialization 移动到 j-loop.

内部

一些改进:

如果许多方法具有相同的参数(例如 int arr[15][15]int size),那么这可能表明这些参数应该成为 class 的成员。

检查器功能可以只有一个。此函数的参数将是搜索方向(int deltaX、int deltaY),以及正在检查的值(1 或 2)。 Delta-values 所有 8 个方向都是这些:

(1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0), (-1, 1), (0, 1), (1, 1)

因此,在您的 d-loop 中,您不会在 ij 中添加或减去 d,但您总是会添加 deltaXideltaYj

还有,有点进阶,不过也很好玩。可以以这样的方式安排代码,使您可以进行三种类型的游戏:人对人、人对计算机、计算机对计算机。例如,您只需将 class HumanPlayer 的对象分配给玩家 1,将 class ComputerPlayer 的对象分配给玩家 2。这将使您能够选择谁先玩,并且也有几种算法与之抗衡。两个 classes 都必须使用一些已知方法(如 'move')从基础 class Player 派生,而一些 GameCoordinator 将在循环调用中此方法 'move' 在两个对象上,更新游戏状态,并检查游戏是否结束。