提问人:Gabriella 提问时间:5/25/2022 最后编辑:Gabriella 更新时间:5/25/2022 访问量:431
c++ Gomoku 对角线检查器
c++ Gomoku diagonal checker
问:
所以我对编码比较陌生。所以我必须为一个项目制作一个 Gomoku 游戏。Gomoku 就像井字游戏,但必须连续获得五个。已获得某些限制,例如板尺寸为 6x6 至 15x15。使用至少一个类。我选择使用数组。我创建了 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;
}
类的 .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_ */
最后是类的.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 循环,而是依靠语句中要重置的变量。但是,如果你的 d 循环在语句执行之前结束(“过早”变为 false),则计数器不会被重置。解决方案:将零初始化移至 j 循环内部。count1
count2
else
else
(i + d < size) && (j - d < size)
一些改进:
如果许多方法具有相同的参数(例如 和 ),则这可能是这些参数应该成为类成员的标志。int arr[15][15]
int size
可以只有一个检查器功能。此函数的参数将是搜索方向(int deltaX、int deltaY)以及正在检查的值(1 或 2)。所有 8 个方向的增量值如下:
(1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0), (-1, 1), (0, 1), (1, 1)
因此,在 d 循环中,您不会对 和 进行加法或减法,但您总是会对 和 进行加法。d
i
j
deltaX
i
deltaY
j
另外,有点高级,但也很有趣。可以以这样一种方式排列代码,您可以拥有三种类型的游戏:人与人、人与计算机、计算机与计算机。例如,您只需将一个类的对象分配给玩家 1,将一个类的对象分配给玩家 2。这将使您能够选择谁先玩,并且还有几种算法与之抗衡。这两个类都必须使用一些已知方法(如“move”)从基类派生,并且有些类会在循环中将此方法称为“move”,更新游戏状态,并检查游戏是否已结束。HumanPlayer
ComputerPlayer
Player
GameCoordinator
评论