我制作了一个游戏,其中2个井字游戏AI在3x3网格上互相对抗。但是当我运行代码时,它说bestMoveX正在使用而未初始化。
这个问题可能很容易解决,但是我无法解决这个问题。
#include <iostream>
#include<algorithm>
const short sizeX = 3, sizeY = 3, marksNeeded = 3, n = 3;
struct move
{
int x;
int y;
int score;
};
void printGrid(char grid[][sizeY]);
void initGrid(char grid[][sizeY]);
move getBestMove(bool maxTurn, char grid[][sizeY], char player);
bool isThisMoveWinner(char grid[][sizeY], short iX, short iY);
#include <iostream>
#include<algorithm>
#include "TicTacTo.h"
void printGrid(char grid[][sizeY]) {
for (short x = 0, y = 0; y != sizeY;) {
std::cout << grid[x][y] << ' ';
if (x == sizeX - 1) {
std::cout << '\n';
x = 0;
++y;
}
else {
++x;
}
}
}
bool isItATie(char grid[][sizeY]) {
for (short x = 0, y = 0; y != sizeY;) {
if (grid[x][y] == 45) {
return false;
}
if (x == sizeX - 1) {
x = 0;
++y;
}
else {
++x;
}
}
return true;
}
void initGrid(char grid[][sizeY]) {
for (short x = 0, y = 0; y != sizeY;) {
grid[x][y] = 45;
if (x == sizeX - 1) {
x = 0;
++y;
}
else {
++x;
}
}
}
move getBestMove(bool maxTurn, char grid[][sizeY], char player) {
// this function uses the minimax algorithm
// these are low, so that the first move is always better
static int maxScore = -2;
static int minScore = 2;
int bestMoveX, bestMoveY;
// check if it is the maximizers turn (maximizer picks the move that gets the most points) (points mean who wins (1 point = max wins) (-1 point = min wins) (0 points = nobody wins))
if (maxTurn) {
// for every move
for (short x = 0, y = 0; y != sizeY;) {
if (grid[x][y] == 45) {
// do this
// make grid with new move
char newGrid[sizeX][sizeY];
std::copy(&grid[0][0], &grid[0][0] + sizeX * sizeY, &newGrid[0][0]);
newGrid[x][y] = player;
// if the move wins, return 1
if (isThisMoveWinner(newGrid, x, y)) {
move thisMove = { x, y, 1 };
return thisMove;
}
// if its a tie, return 0
if (isItATie(newGrid)) {
move thisMove = { x, y, 0 };
return thisMove;
}
// if the move doesnt win or tie recursively go through all moves possible, until you get a move that results in a tie or a win
move thisMove = getBestMove(!maxTurn, newGrid, (player == 'x' ? 'o' : 'x'));
// if the move is better than some other move, update bestMove
if (maxScore < thisMove.score) {
maxScore = thisMove.score;
bestMoveX = x;
bestMoveY = y;
}
}
if (x == sizeX - 1) {
x = 0;
++y;
}
else {
++x;
}
}
//return the bestMove
move bestMove = { bestMoveX, bestMoveY, maxScore };
return bestMove;
}
// it is the minimizers turn (minimizer picks the move that gets the least points because more point = good for max) (points mean who wins (1 point = max wins) (-1 point = min wins) (0 points = nobody wins))
else {
// for every move
for (short x = 0, y = 0; y != sizeY;) {
if (grid[x][y] == 45) {
// do this
// make grid with new move
char newGrid[sizeX][sizeY];
std::copy(&grid[0][0], &grid[0][0] + sizeX * sizeY, &newGrid[0][0]);
newGrid[x][y] = player;
// if the move wins, return -1 because it is minimizers win
if (isThisMoveWinner(newGrid, x, y)) {
move thisMove = { x, y, -1 };
return thisMove;
}
// if its a tie, return 0
if (isItATie(newGrid)) {
move thisMove = { x, y, 0 };
return thisMove;
}
// if the move doesnt win recursively go through all moves possible, until you get a move that results in a tie or a win
move thisMove = getBestMove(!maxTurn, newGrid, (player == 'x' ? 'o' : 'x'));
// if the move is better than some other move, update bestMove ( remember minimizer wants least points)
if (minScore > thisMove.score) {
minScore = thisMove.score;
bestMoveX = x;
bestMoveY = y;
}
}
if (x == sizeX - 1) {
x = 0;
++y;
}
else {
++x;
}
}
//return the bestMove
move bestMove = { bestMoveX, bestMoveY, minScore };
return bestMove;
}
}
bool isThisMoveWinner(char grid[][sizeY], short iX, short iY) {
char moveP = grid[iX][iY];
//following code from stackoverflow
//check col
for (int i = 0; i < n; i++) {
if (grid[iX][i] != moveP)
break;
if (i == n - 1) {
return true;
}
}
//check row
for (int i = 0; i < n; i++) {
if (grid[i][iY] != moveP)
break;
if (i == n - 1) {
return true;
}
}
//check diag
if (iX == iY) {
//we're on a diagonal
for (int i = 0; i < n; i++) {
if (grid[i][i] != moveP)
break;
if (i == n - 1) {
return true;
}
}
}
//check anti diag
if (iX + iY == n - 1) {
for (int i = 0; i < n; i++) {
if (grid[i][(n - 1) - i] != moveP)
break;
if (i == n - 1) {
return true;
}
}
}
// end code from stackoverflow
return false;
}
int main()
{
char grid[sizeX][sizeY];
initGrid(grid);
bool xTurn = true;
char curP;
while (true) {
curP = (xTurn ? 'x' : 'o');
move thisMove = getBestMove(true, grid, curP);
grid[thisMove.x][thisMove.y] = curP;
printGrid(grid);
std::cout << '\n';
if (isThisMoveWinner(grid, thisMove.x, thisMove.y)) {
std::cout << "The winner is " << curP;
break;
}
else if (isItATie(grid)) {
std::cout << "It's a tie";
}
xTurn = !xTurn;
}
}
[根据我的大脑,最好没有初始化bestMoveX,因为如果有一个填充网格的动作,它将不会传递到getBestMove的下一层,因为isItATie将在此之前退出该函数。] >
我制作了一个游戏,其中2个井字游戏AI在3x3网格上互相对抗。但是当我运行代码时,它说bestMoveX正在使用而未初始化。问题可能非常...
我不知道为什么将STATIC放在minScore和maxScore中。移除STATIC即可解决。