Here comes my code. (it's a bit messy)
board.cpp
[syntax="cpp"]# include "board.h"
# include <iostream>
Board :: Board () {
board = 0;
}
int Board :: at (int x, int y) {
return (board & (1<<(5-x)<<5*(3-y)));
}
void Board :: clear () {
board = 0;
}
void Board :: add (int x, int y) {
board |= (1<<(5-x)<<5*(3-y));
}
void Board :: remove (int x, int y) {
board &= ~(1<<(5-x)<<5*(3-y));
}
[/syntax]
board.h
[syntax="cpp"]#ifndef BOARD_H_
#define BOARD_H_
class Board {
private :
int board;
public :
Board ();
int at (int, int);
void clear ();
void add (int, int);
void remove (int, int);
int getBoard () { return board; }
};
#endif
[/syntax]
player.cpp
[syntax="cpp"]# include "player.h"
# include <iostream>
Player :: Player () {
board = new Board ();
}
void Player :: addPiece (int x, int y) {
board -> add (y, x);
}
void Player :: removePiece (int x, int y) {
board -> remove (y, x);
}
bool Player :: hasPiece (int x, int y) {
return board -> at (y, x) != 0;
}
void Player :: clear () {
delete board;
board = new Board ();
}
Player :: ~Player () {
delete board;
}
[/syntax]
player.h
[syntax="cpp"]# ifndef PLAYER_H_
# define PLAYER_H_
# include "board.h"
class Player {
private:
Board * board;
public:
Player ();
void addPiece (int, int);
void removePiece(int, int);
bool hasPiece (int, int);
int getBoard () { return board -> getBoard (); }
void clear ();
~Player ();
};
# endif
[/syntax]
tictactoe.cpp
[syntax="cpp"]# include <iostream>
# include <string>
# include <exception>
# include <cstdio>
# include <stdexcept>
# include "board.h"
# include "player.h"
bool hasWon (Player *);
void printBoard (Player **);
bool emptySpot (Player **, int, int);
void resetGame (Player **);
void bestMove (Player **, int);
void undoMove (Player **, int, int, int);
int winChance (Player **, int, int);
bool computerPlay (Player ** players, int turn);
bool humanPlay (Player ** players, int turn);
int evalute (Player **, int);
int main () {
Player * players[2];
players [0] = new Player ();
players [1] = new Player ();
std :: cout << "Enter \"1\" to become player 1: ";
int numOfemptySlots = 9;
int n, turn = 1;
std :: cin >> n;
if (n != 1)
turn = 0;
bool cont = true;
while (true) {
std :: cout << "Enter: (q = quit) (xy)" << std :: endl;
if (!cont)
break;
if (numOfemptySlots == 0) {
std :: string n;
std :: cout << "Game Over. It was a Tie! Enter: (q = quit) (else: a new game will be started)";
std :: cin >> n;
if (n == "q")
break;
resetGame(players);
numOfemptySlots = 9;
}
if (turn == 0)
cont = humanPlay (players, 0);
else
cont = computerPlay (players, 1);
system ("clear");
printBoard (players);
if (hasWon (players [turn])) {
std :: cout << "You " << (turn == 0 ? "win!" : "loose!");
std :: cout << " Press q to quit (or start a new game): ";
std :: string n;
getline (std :: cin, n);
if (n == "q")
break;
resetGame(players);
turn = 0;
numOfemptySlots = 9;
continue;
}
numOfemptySlots--;
turn ^= 1;
}
delete players[0];
delete players[1];
return 0;
}
bool computerPlay (Player ** players, int turn) {
bestMove (players, turn);
//players [turn] -> addPiece (move/10, move%10);
return true;
}
bool humanPlay (Player ** players, int turn) {
std :: string input;
int x, y;
std :: cin >> input;
if (input == "q")
return false;
x = atoi (input.substr(0,1).c_str());
y = atoi (input.substr(1).c_str());
//A non-empty spot was entered
if (!emptySpot(players, y, x)) {
while (!emptySpot(players, x, y)) {
std :: cout << "Enter an empty spot: ";
std :: cin >> input;
if (input == "q")
return false;
x = atoi (input.substr(0,1).c_str());
y = atoi (input.substr(1).c_str());
}
}
players [turn] -> addPiece (x, y);
return true;
}
//Checks if a player has won
bool hasWon (Player * p) {
int v = p -> getBoard (), l = p -> getBoard (), d1 = p -> getBoard (), d2 = p -> getBoard ();
v &= v << 1; v &= v << 1;
l &= l << 5; l &= l << 5;
d1 &= d1 << 4; d1 &= d1 << 4;
d2 &= d2 << 6; d2 &= d2 << 6;
return (v | l | d1 | d2) != 0;
}
//Writes the board
void printBoard (Player ** players) {
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
std :: cout << " XO"[int(players [0] ->hasPiece(j,i)) + 2*int(players [1] ->hasPiece(j,i))] << " | ";
}
std :: cout << std :: endl;
}
}
//Checks a spot and returns true if it's empty
bool emptySpot (Player ** players, int x, int y) {
return (players [0] -> hasPiece(x,y) != true && players [1] -> hasPiece(x, y) != true);
}
void resetGame (Player ** players) {
players [0] -> clear ();
players [1] -> clear ();
}
void bestMove (Player ** players, int computer) {
int best = -2;
int x = 0, y = 0;
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
if (!emptySpot(players, j, i))
continue;
players [computer] -> addPiece (j, i);
int chance = -winChance(players, computer, int(!computer));
undoMove (players, computer, j, i);
if (chance > best) {
best = chance;
x = j;
y = i;
}
}
}
players [computer] -> addPiece (x, y);
}
void undoMove (Player ** players, int player, int x, int y) {
players [player] -> removePiece (x, y);
}
int winChance (Player ** players, int computer, int turn) {
int node_value = (turn == computer ? -1: 1);
if (hasWon (players [computer])) { //compuer wins
return 1;
}
if (hasWon (players [int(!computer)])) { // human wins
return -1;
}
if (~(players [0] -> getBoard() | players [1] -> getBoard())) { //checks if there's still empty spots left
for (int j = 1; j <= 3; j++) {
for (int i = 1; i <= 3; i++) {
if (!emptySpot(players, j, i))
continue;
players [turn] -> addPiece (j, i);
int data = -winChance (players, computer, int(!turn));
undoMove (players, turn, j, i);
if (data > node_value)
node_value = data;
/*else if (turn != computer && data < node_value)
node_value = data;*/
}
}
}
else {
return 0; //draw
}
return node_value;
}
[/syntax]
You enter "xy"