Tic-Tac-Toe
Mar 9, 2014 at 10:48am UTC
Hello, I've been working on an AI program that has two AIs going against each other in tic-tac-toe. I've been working on translating it from Java to C++ because I don't work well with Java. I should get output like this:
UPDATE: I found a little typo in the program, but it is still having issues... Here is the updated output now:
| |
-----------
| |
-----------
| |
X | |
-----------
| |
-----------
| |
X | |
-----------
| O |
-----------
| |
X | X |
-----------
| O |
-----------
| |
X | X | O
-----------
| O |
-----------
| |
X | X | O
-----------
X | O |
-----------
| |
X | X | O
-----------
X | O |
-----------
O | |
X | X | O
-----------
X | O |
-----------
O | | X
X | X | O
-----------
X | O | O
-----------
O | | X
X | X | O
-----------
X | O | O
-----------
O | X | X
But, I get this:
| |
-----------
| |
-----------
| |
X | |
-----------
| |
-----------
| |
X | O |
-----------
| |
-----------
| |
X | O | X
-----------
| |
-----------
| |
X | O | X
-----------
O | |
-----------
| |
X | O | X
-----------
O | X |
-----------
| |
X | O | X
-----------
O | X | O
-----------
| |
X | O | X
-----------
O | X | O
-----------
| | X
Any ideas on why it would be different? The code will be posted after this post.
Last edited on Mar 9, 2014 at 1:22pm UTC
Mar 9, 2014 at 10:49am UTC
AIPlayer.hpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
#ifndef AIPLAYER_HPP_INCLUDED
#define AIPLAYER_HPP_INCLUDED
#include <string>
#include <vector>
#include <limits>
#include <algorithm>
#include "Game.hpp"
using namespace std;
class AIPlayer
{
private :
string name;
int playerNumber;
int minValue(Game game);
int maxValue(Game game);
public :
AIPlayer(string name, int playerNumber);
string getName();
Game Move(Game game);
};
int AIPlayer::minValue(Game game)
{
if (game.terminalTest())
return game.getHeuristic(playerNumber);
else
{
vector<Game> possibleMoves = game.Moves(-playerNumber);
int v = std::numeric_limits<int >::max();
for (unsigned int i = 0; i < possibleMoves.size(); i++)
{
v = std::min(v, maxValue(possibleMoves[i]));
}
return v;
}
}
int AIPlayer::maxValue(Game game)
{
if (game.terminalTest())
return game.getHeuristic(playerNumber);
else
{
vector<Game> possibleMoves = game.Moves(playerNumber);
int v = std::numeric_limits<int >::min();
for (unsigned int i = 0; i < possibleMoves.size(); i++)
{
v = std::max(v, minValue(possibleMoves[i]));
}
return v;
}
}
AIPlayer::AIPlayer(string name, int playerNumber)
{
this ->name = name;
this ->playerNumber = playerNumber;
}
string AIPlayer::getName()
{
return name;
}
Game AIPlayer::Move(Game game)
{
vector<Game> possibleMoves = game.Moves(playerNumber);
int moveUtility[possibleMoves.size()];
unsigned int array_size = sizeof (moveUtility)/sizeof (moveUtility[0]);
for (unsigned int i = 0; i < array_size; i++)
{
Game thisMove = possibleMoves[i];
moveUtility[i] = minValue(thisMove);
}
int bestMoveIndex = 0;
for (unsigned int i = 1; i < array_size; i++)
{
if (moveUtility[i] > moveUtility[bestMoveIndex])
{
bestMoveIndex = i;
}
}
Game bestMove = possibleMoves[bestMoveIndex];
return bestMove;
}
#endif // AIPLAYER_HPP_INCLUDED
Game.hpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
#ifndef GAME_HPP_INCLUDED
#define GAME_HPP_INCLUDED
#include <iostream>
#include <vector>
using namespace std;
class Game
{
private :
int board[3][3];
char boardChar(int n);
int boardValue();
public :
Game();
Game(const Game& game);
Game(const Game* otherGame);
vector<Game> Moves(int toPlay);
bool terminalTest();
int getHeuristic(int playerNumber);
bool checkForDraw();
void printBoard();
};
char Game::boardChar(int n)
{
if (n == 1)
{
return 'X' ;
}
else if (n == -1)
{
return 'O' ;
}
else
{
return ' ' ;
}
}
int Game::boardValue()
{
for (int i = 0; i < 3; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != 0)
return board[i][0];
}
for (int i = 0; i < 3; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != 0)
return board[0][i];
}
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != 0)
return board[0][0];
if (board[0][2] == board[1][1] && board[1][1] == board[2][2] && board[2][0] != 0)
return board[0][2];
return 0;
}
Game::Game()
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
this ->board[i][j] = 0;
}
}
}
Game::Game(const Game& game)
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
board[i][j] = game.board[i][j];
}
}
}
Game::Game(const Game* otherGame)
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
this ->board[i][j] = otherGame->board[i][j];
}
}
}
vector<Game> Game::Moves(int toPlay)
{
vector<Game> children;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (board[i][j] == 0)
{
Game child(this );
child.board[i][j] = toPlay;
// cout << "child: " << endl;
// printBoard();
// cout << endl;
children.push_back(child);
}
}
}
return children;
}
bool Game::terminalTest()
{
return (boardValue() != 0 || checkForDraw());
}
int Game::getHeuristic(int playerNumber)
{
return playerNumber * boardValue();
}
bool Game::checkForDraw()
{
bool allFilledIn = true ;
for (int i = 0; i < 9; i++)
{
int row = i/3;
int col = i - (3 * row);
if (board[row][col] == 0)
{
allFilledIn = false ;
break ;
}
}
bool isDraw = (allFilledIn && boardValue() == 0);
return isDraw;
}
void Game::printBoard()
{
string topRow;
topRow = std::string(" " ) + boardChar(board[0][0]) + " | "
+ boardChar(board[0][1]) + " | " + boardChar(board[0][2]) + " " ;
string line = "-----------" ;
string midRow = std::string(" " ) + boardChar(board[1][0]) + " | "
+ boardChar(board[1][1]) + " | " + boardChar(board[1][2]) + " " ;
string botRow = std::string(" " ) + boardChar(board[2][0]) + " | "
+ boardChar(board[2][1]) + " | " + boardChar(board[2][2]) + " " ;
cout << topRow << endl;
cout << line << endl;
cout << midRow << endl;
cout << line << endl;
cout << botRow << endl;
}
#endif // GAME_HPP_INCLUDED
PlayGame.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
#include <iostream>
#include <string>
#include "Game.hpp"
#include "AIPlayer.hpp"
using namespace std;
int main()
{
AIPlayer Cross("Cross" , 1);
AIPlayer Naught("Naught" , -1);
Game game;
int toPlay = 1;
game.printBoard();
cout << endl;
bool gameOver = false ;
while (!gameOver)
{
if (toPlay == 1)
game = Cross.Move(game);
else
game = Naught.Move(game);
game.printBoard();
cout << endl;
gameOver = game.terminalTest();
toPlay = -toPlay;
}
}
I'll give the java code if it is necessary for anything.
Last edited on Mar 9, 2014 at 1:23pm UTC
Topic archived. No new replies allowed.