简体   繁体   English

c++ Gomoku 对角线检查器

[英]c++ Gomoku diagonal checker

so I am a relatively new to coding.所以我是一个相对较新的编码。 So I have to make a Gomoku game for a project.所以我必须为一个项目制作一个五子棋游戏。 Gomoku is like tic-tac-toe, but have to get five in a row.五子棋就像井字游戏,但必须连续获得五个。 Have been given certain restrictions such as a board size of 6x6 to 15x15.已获得某些限制,例如 6x6 到 15x15 的板尺寸。 The use of at least one class.使用至少一个类。 I have chosen to use arrays.我选择使用数组。 I have created PlayerOne as an algorithm which bases its moves on PlayerOne's last move, and moves one random block away from it in next move.我创建了 PlayerOne 作为一种算法,它的移动基于 PlayerOne 的最后一步,并在下一步移动一个随机块远离它。 The second algorithm is random.第二种算法是随机的。 For when checking for a win, my horizontal and vertical checkers seem to work but both my diagonal checkers are giving problems, with them saying that 3 consecutive blocks in a row diagonally is 5 in a row.因为在检查胜利时,我的水平和垂直检查器似乎工作,但我的两个对角检查器都出现问题,他们说连续 3 个连续的对角线块是连续 5 个。 I created my checkers separately, filling in each row manually to test, and the diagonal checkers were fine there, but they're not fine in the whole code.我分别创建了我的检查器,手动填写每一行进行测试,对角线检查器在那里很好,但在整个代码中它们并不好。 I'll share both the diagonal checkers up here, and then the whole code a little below so hopefully easier to read.我将在这里分享两个对角线检查器,然后将整个代码放在下面一点,希望更容易阅读。 Also quite a bit of it has cout statements as was trying to see where problems where earlier in the process.还有相当多的内容有 cout 语句,因为它试图查看过程早期的问题所在。 If anyone can see where the issue is occurring if could point out where, would be so appreciative.如果有人能看到问题发生在哪里,如果能指出哪里,将非常感激。

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 main code 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;
}

The .h file of the 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_ */

And finally the .cpp file of the 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++;

    }

}

I have also been using an input of我也一直在使用

6

The problem could be that you don't set count1 and count2 inside the j-loop, but rather count on the variable being reset in the else statement.问题可能是您没有在 j 循环内设置count1count2 ,而是依靠在else语句中重置的变量。 But if your d-loop ends before the else statement is executed ( (i + d < size) && (j - d < size) becomes false "prematurely") then the counter is not reset.但是,如果您的 d 循环在执行else语句之前结束( (i + d < size) && (j - d < size) “过早地”变为 false),则不会重置计数器。 Solution: move the zero-initialization to inside the j-loop.解决方案:将零初始化移到j循环内部。

Some improvements:一些改进:

If lots of methods have the same parameter (such as int arr[15][15] and int size ) then this could be the sign that these parameters should become members of the class.如果许多方法具有相同的参数(例如int arr[15][15]int size ),那么这可能表明这些参数应该成为类的成员。

It is possible to have only one checker function.可以只有一个检查器功能。 Parameters of this function would be the direction of the search (int deltaX, int deltaY), and also the value that is being checked (1 or 2).此函数的参数将是搜索的方向(int deltaX,int deltaY),以及正在检查的值(1 或 2)。 Delta-values for all 8 directions are these:所有 8 个方向的增量值如下:

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

So, in your d-loop you would not add or subtract d to and from i and j , but you would always add deltaX to i , and deltaY to j .因此,在您的 d 循环中,您不会在ij中添加或减去d ,但您总是将 deltaX 添加到i ,并将deltaX deltaYj

Also, a bit advanced, but also fun.另外,有点高级,但也很有趣。 It is possible to arrange the code in such a way that you can have three types of games: human vs human, human vs computer, computer vs computer.可以以这样一种方式排列代码,您可以拥有三种类型的游戏:人类与人类、人类与计算机、计算机与计算机。 You just for instance assign object of a class HumanPlayer to player 1 and object of a class ComputerPlayer to player 2. This would enable you to pick who plays first, and also have several algorithms battling it out.例如,您只需将HumanPlayer类的对象分配给玩家 1,将ComputerPlayer类的对象分配给玩家 2。这将使您能够选择谁先玩,并且还有几个算法可以与之抗衡。 Both classes would have to be derived from the base class Player with some known methods (like 'move'), and some GameCoordinator would in a loop call this method 'move' on both objects, update the game state, and check if game has ended.这两个类都必须从基类Player派生出一些已知的方法(如“move”),并且一些GameCoordinator会在循环中调用这两个对象的方法“move”,更新游戏状态,并检查游戏是否有结束了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM