I see what you mean now, but I don't yet see how I'm going to fix it. Here's the whole code and errors.
*edit* I know I put the externs in the wrong place. Discard that and related errors *edit*
Errors:
Code:
In file included from board.h:4,
from main.cpp:3:
cell.h:36: warning: `CENTER' initialized and declared `extern' cell.h:37: warning: `TOP_LEFT' initialized and declared `extern'
cell.h:38: warning: `TOP_RIGHT' initialized and declared `extern'
cell.h:39: warning: `TOP_CENTER' initialized and declared `extern'
cell.h:40: warning: `BOTTOM_LEFT' initialized and declared `extern'
cell.h:41: warning: `BOTTOM_RIGHT' initialized and declared `extern' cell.h:42: warning: `BOTTOM_CENTER' initialized and declared `extern'
cell.h:43: warning: `LEFT_CENTER' initialized and declared `extern'
cell.h:44: warning: `RIGHT_CENTER' initialized and declared `extern' g++.exe board.o cell.o coordinates.o main.o record.o -o "ttt.exe" -L"C:/DEV-CPP/lib" cell.o(.bss+0x0):cell.cpp: multiple definition of `cellspace::positions::CENTER'
board.o(.bss+0x0):board.cpp: first defined here
cell.o(.bss+0xc):cell.cpp: multiple definition of `cellspace::positions::TOP_LEFT'
board.o(.bss+0xc):board.cpp: first defined here
cell.o(.bss+0x18):cell.cpp: multiple definition of `cellspace::positions::TOP_RIGHT'
board.o(.bss+0x18):board.cpp: first defined here
cell.o(.bss+0x24):cell.cpp: multiple definition of `cellspace::positions::TOP_CENTER'
board.o(.bss+0x24):board.cpp: first defined here
cell.o(.bss+0x30):cell.cpp: multiple definition of `cellspace::positions::BOTTOM_LEFT'
board.o(.bss+0x30):board.cpp: first defined here
cell.o(.bss+0x3c):cell.cpp: multiple definition of `cellspace::positions::BOTTOM_RIGHT'
board.o(.bss+0x3c):board.cpp: first defined here
cell.o(.bss+0x48):cell.cpp: multiple definition of `cellspace::positions::BOTTOM_CENTER'
board.o(.bss+0x48):board.cpp: first defined here
cell.o(.bss+0x54):cell.cpp: multiple definition of `cellspace::positions::LEFT_CENTER'
board.o(.bss+0x54):board.cpp: first defined here
cell.o(.bss+0x60):cell.cpp: multiple definition of `cellspace::positions::RIGHT_CENTER'
board.o(.bss+0x60):board.cpp: first defined here
main.o(.bss+0x0):main.cpp: multiple definition of `cellspace::positions::CENTER'
board.o(.bss+0x0):board.cpp: first defined here
main.o(.bss+0xc):main.cpp: multiple definition of `cellspace::positions::TOP_LEFT'
board.o(.bss+0xc):board.cpp: first defined here
main.o(.bss+0x18):main.cpp: multiple definition of `cellspace::positions::TOP_RIGHT'
board.o(.bss+0x18):board.cpp: first defined here
main.o(.bss+0x24):main.cpp: multiple definition of `cellspace::positions::TOP_CENTER'
board.o(.bss+0x24):board.cpp: first defined here
main.o(.bss+0x30):main.cpp: multiple definition of `cellspace::positions::BOTTOM_LEFT'
board.o(.bss+0x30):board.cpp: first defined here
main.o(.bss+0x3c):main.cpp: multiple definition of `cellspace::positions::BOTTOM_RIGHT' board.o(.bss+0x3c):board.cpp: first defined here
main.o(.bss+0x48):main.cpp: multiple definition of `cellspace::positions::BOTTOM_CENTER'
board.o(.bss+0x48):board.cpp: first defined here
main.o(.bss+0x54):main.cpp: multiple definition of `cellspace::positions::LEFT_CENTER'
board.o(.bss+0x54):board.cpp: first defined here
main.o(.bss+0x60):main.cpp: multiple definition of `cellspace::positions::RIGHT_CENTER'
board.o(.bss+0x60):board.cpp: first defined here
collect2: ld returned 1 exit status
coordinates.h
Code:
#ifndef COORDINATES_H
#define COORDINATES_H
#include <vector>
namespace coordinates
{
class coord
{
public:
coord();
coord(int x_in, int y_in);
~coord();
const int getx();
const int gety();
const bool is_defined();
bool operator > (coord other);
bool operator > (int other);
bool operator < (coord other);
bool operator < (int other);
bool operator == (coord other);
bool operator == (int other);
bool operator >= (coord other);
bool operator >= (int other);
bool operator <= (coord other);
bool operator <= (int other);
coord operator = (coord other);
operator int ();
coord assign(int x_in, int y_in);
void clear();
protected:
int x;
int y;
bool defined;
};
namespace exception
{
class undefined{};
}
}
#endif
coordinates.cpp
Code:
#include "coordinates.h"
using namespace coordinates;
coord::coord() {defined = false;}
coord::coord(int x_in, int y_in) {x = x_in; y = y_in; defined = true;}
coord::~coord(){}
const int coord::getx() {
if(!defined) throw exception::undefined();
return x;
}
const int coord::gety() {
if(!defined) throw exception::undefined();
return y;
}
const bool coord::is_defined() {return defined;}
bool coord::operator > (coord other) {
if(!defined || !other.is_defined()) throw exception::undefined();
return ( (other.getx() + other.gety()) <= (x + y)) ? false : true;}
bool coord::operator > (int other) {
return (other <= (x + y)) ? false : true;}
bool coord::operator < (coord other) {
return ( (other.getx() + other.gety()) >= (x + y)) ? false : true;}
bool coord::operator < (int other) {
return (other <= (x + y)) ? false : true;}
bool coord::operator == (coord other) {
return (other.getx() == x && other.gety() == y) ? true : false;}
bool coord::operator == (int other) {
return (other == (x + y)) ? true : false;}
bool coord::operator >= (coord other) {
return ( (other.getx() + other.gety()) > (x + y)) ? false : true;}
bool coord::operator >= (int other) {
return (other > (x + y)) ? false : true;}
bool coord::operator <= (coord other) {
return ( (other.getx() + other.gety()) < (x + y)) ? false : true;}
bool coord::operator <= (int other) {
return (other < (x + y)) ? false : true;}
coord coord::operator = (coord other)
{
if(!other.is_defined()) throw exception::undefined();
else {
x = other.getx();
y = other.gety();
if(!defined) defined = true;
}
return *this;
}
coord coord::assign(int x_in, int y_in)
{
coord val(x,y);
x = x_in;
y = y_in;
if(!defined) defined = true;
return val;
}
void coord::clear () {defined = false;}
coord::operator int () {
if(!defined) throw exception::undefined();
return x + y;
}
cell.h:
Code:
#ifndef CELL_H
#define CELL_H
#include "coordinates.h"
#include <sstream>//for print()
#include <string>//also for print()
using namespace std;
namespace cellspace
{
enum POS_TYPE {POS_TYPE_ZERO, CENTER, CORNER, OTHER};
class cell : public coordinates::coord
{
private:
bool occupied;
char symbol;// usually X or O or universal skip character '-'
public:
cell();
cell(int x_in, int y_in);
cell(int x_in, int y_in, char symbol_in);
~cell(){}
const bool is_occupied();
const char get_symbol();
cell operator = (cell other);
cell operator = (coord other);
bool operator == (POS_TYPE other);
bool operator == (coord other);
const coord opposite(bool apply_to_this);
cell assign(int x_in, int y_in, char symbol_in);
cell assign(char symbol_in);
string print();
void wipe();
};
namespace positions
{
extern coordinates::coord CENTER(1,1);
extern coordinates::coord TOP_LEFT(0,2);
extern coordinates::coord TOP_RIGHT(2,2);
extern coordinates::coord TOP_CENTER(1,2);
extern coordinates::coord BOTTOM_LEFT(0,0);
extern coordinates::coord BOTTOM_RIGHT(2,0);
extern coordinates::coord BOTTOM_CENTER(1,0);
extern coordinates::coord LEFT_CENTER(0,1);
extern coordinates::coord RIGHT_CENTER(2,1);
}
}
#endif
cell.cpp:
Code:
#include "cell.h"
using namespace std;
using namespace coordinates;
using namespace cellspace;
cell::cell()
{
symbol = '\0';
defined = false;
occupied = false;
}
cell::cell(int x_in, int y_in)
{
x = x_in;
y = y_in;
defined = true;
symbol = '\0';
occupied = false;
}
cell::cell(int x_in, int y_in, char symbol_in)
{
x = x_in;
y = y_in;
defined = true;
symbol = symbol_in;
occupied = (symbol_in == '\0') ? false : true;
}
const bool cell::is_occupied()
{
if(!defined) throw coordinates::exception::undefined();
return occupied;
}
const char cell::get_symbol()
{
if(!occupied) return '\0';
return symbol;
}
const coord cell::opposite(bool apply_to_this = true)
{
coord val;
if(apply_to_this == false)
val.assign( (-(x) + 2), (-(y) + 2) );
else {
if(!defined) throw coordinates::exception::undefined();
x = -(x) + 2;
y = -(y) + 2;
}
return val;
}
cell cell::operator = (coord other)
{
if(!other.is_defined()) throw coordinates::exception::undefined();
else {
x = other.getx();
y = other.gety();
if(!defined) defined = true;
}
return *this;
}
cell cell::operator = (cell other)
{
if(!other.is_defined()) throw coordinates::exception::undefined();
else {
if(other.is_occupied())
{
occupied = true;
symbol = other.get_symbol();
x = other.getx();
y = other.gety();
if(!defined) defined = true;
}
else
{
occupied = false;
symbol = '\0';
x = other.getx();
y = other.gety();
if(!defined) defined = true;
}
}
return *this;
}
cell cell::assign(int x_in, int y_in, char symbol_in = '\0')
{
coord::assign(x_in,y_in);
occupied = (symbol_in == '\0') ? false : true;
symbol = symbol_in;
return *this;
}
cell cell::assign(char symbol_in)
{
if(!defined) throw coordinates::exception::undefined();
occupied = (symbol_in == '\0') ? false : true;
symbol = symbol_in;
return *this;
}
string cell::print()
{
ostringstream strm;
strm << '(' << x << ',' << y << ')';
return strm.str();
}
bool cell::operator == (POS_TYPE other)
{
switch(other)
{
case CENTER: return (x == y == 1);
case CORNER: return ( ((int)*this == 2 || (int)*this == 4 || (int)*this == 0) && !(x == y == 1) );
case OTHER: return ( (int)*this == 1 || (int)*this == 3 );
default: break;
}
return false;
}
bool cell::operator == (coord other)
{
if(!defined) throw coordinates::exception::undefined();
return (coord)(*this) == other;
}
void cell::wipe()
{
symbol = '\0';
occupied = false;
clear();
}
board.h:
Code:
#ifndef BOARD_H
#define BOARD_H
#include "cell.h"
//#include "record.h"
#include <vector>
using namespace cellspace;
using namespace coordinates;
namespace boardspace
{
class record;//prototype
class is_player;//prototype of a predicate
enum MOVE_MESSAGE {MOVE_MESSAGE_ZERO, SUCCESS, UNKNOWN_ERROR, NO_VACANCY, OUT_OF_BOUNDS}; //TODO: Add as needed.
enum PLAYER {PLAYER_ZERO, PLAYER1, PLAYER2};
enum WIN_STATE {WIN_STATE_ZERO, P1_WIN, P2_WIN, KATZ};
/*char* MessageString(MOVE_MESSAGE msg);*/
class board
{
cell cells[3][3];
cell win_set[3];
vector <record> history;
char P1_symbol;
char P2_symbol;
cell * access(coord pos);//for class to read/write itself in reg (x,y) plane style
cell * access(int x_in, int y_in);
PLAYER switch_player(PLAYER& p);//for internal use
bool won;
bool empty;
int curr_turn;
public:
board();
board(char P1_in, char P2_in);
void initialize(char P1_in, char P2_in);
~board();
//cell get_cell(coord pos);
cell get_cell(int x_in, int y_in);
cell get_cell(coord pos);
char get_P1() {return P1_symbol;}
char get_P2() {return P2_symbol;}
bool is_empty() {return empty;}
bool get_won() {return won;}
int get_curr_turn() {return curr_turn;}
cell* get_win_set(int index);
vector <record>::iterator get_history_begin() {return history.begin();}
vector <record>::iterator get_history_end() {return history.end();}
bool is_history_empty() {return history.empty();}
record get_entry(int index);
vector <record> get_history() {return history;}
board operator = (board other);
MOVE_MESSAGE move(PLAYER which_player, int x_in, int x_out, board* out, MOVE_MESSAGE* msg_out);
MOVE_MESSAGE move(PLAYER which_player, coord pos, board* out, MOVE_MESSAGE* msg_out);
WIN_STATE CheckForWin(bool just_check, WIN_STATE* msg_out, vector <coord> skips);
vector <record> FindHotSpots();
void wipe();
};//class board
class record
{
PLAYER player;
cell * spot;
int move_num;
public:
record(int move_num_in, cell* spot_in, PLAYER player_in);
cell* get_spot() {return spot;}
int get_move_num() {return move_num;}
PLAYER get_player() {return player;}
record operator = (record other);
};//class record
class is_player //a predicate
{
PLAYER p;
public:
is_player() { p = PLAYER_ZERO; }
is_player(PLAYER p_in) { p = p_in; }
~is_player() {}
bool operator () (record rec) { return (rec.get_player() == p); }
};//class is_player
namespace exception
{
class OUT_OF_BOUNDS {};
}//namespace exception
}//namespace boardspace
#endif
board.cpp:
Code:
#include "coordinates.h"
#include "cell.h"
#include "board.h"
#include <algorithm>
#include <iostream>
using namespace std;
using namespace cellspace;
using namespace boardspace;
board::board(char P1_in, char P2_in)
{
initialize(P1_in, P2_in);
}
board::board()
{
initialize('X','O');
}
void board::initialize(char P1_in = 'X', char P2_in = '0')
{
curr_turn = 1;
empty = true;
won = false;
P1_symbol = P1_in;
P2_symbol = P2_in;
for(int a = 0; a < 3; a++)
{
for(int b = 0; b < 3; b++) cells[a][b].coord::assign(b, -(a) + 2);
}
}
board::~board()
{
/*delete [] cells;*/ //caused TREMENDOUS SLOWDOWNS in destruction of all instances of board.
//because, I suppose, "delete" can be used only with data that was allocated dynamically,
//or even only via "new".
}
cell board::get_cell(int x_in, int y_in)
{
if(x_in > 2 || x_in < 0 || y_in > 2 || y_in < 0) { throw boardspace::exception::OUT_OF_BOUNDS(); }
return cells[-(y_in) + 2][x_in];
}
cell board::get_cell(coord pos)
{
if(pos.getx() > 2 || pos.getx() < 0 || pos.gety() > 2 || pos.gety() < 0) { throw boardspace::exception::OUT_OF_BOUNDS(); }
return cells[-(pos.gety()) + 2][pos.getx()];
}
inline cell * board::access(int x_in, int y_in)//returns a reference pointing to that part of the board array.
{
return &cells[-(y_in) + 2][x_in];
}
inline cell * board::access(coord pos)//returns a reference pointing to that part of the board array.
{
return &cells[-(pos.gety()) + 2][pos.getx()];
}
board board::operator = (board other)
{
empty = other.is_empty();
P1_symbol = other.get_P1();
P2_symbol = other.get_P2();
for(int a = 0; a < 3; a++)
{
for(int b = 0; b < 3; b++) *access(a,b) = other.get_cell(a,b);
}
if(other.is_history_empty()) history.clear();
else history = other.get_history();
return *this;
}
MOVE_MESSAGE board::move(PLAYER which_player, int x_in, int y_in, board* out, MOVE_MESSAGE* msg_out)
{
MOVE_MESSAGE ret_val = SUCCESS;
board * temp_board;
record* temp_rec = NULL;
if(x_in > 2 || y_in > 2 || x_in < 0 || y_in < 0 || which_player < PLAYER_ZERO) ret_val = OUT_OF_BOUNDS;
else if(get_cell(x_in,y_in).is_occupied()) ret_val = NO_VACANCY;
else if(out == NULL)//standard with output
{
if(empty) empty = false;
access(x_in, y_in)->assign((which_player == PLAYER1) ? P1_symbol : (which_player == PLAYER2) ? P2_symbol : '\0');
temp_rec = new record(curr_turn, access(x_in,y_in), which_player);
}
else//standard without output
{
temp_board = new board;
*temp_board = *this;
temp_board->move(which_player, x_in, y_in, NULL, NULL);
*out = *temp_board;
delete temp_board;
}//end if else-if(s)
if(msg_out != NULL) *msg_out = ret_val;
if(temp_rec != NULL)
{
history.push_back(*temp_rec);
curr_turn++;
delete temp_rec;
}
return ret_val;
}
MOVE_MESSAGE board::move(PLAYER which_player, coord pos, board* out, MOVE_MESSAGE* msg_out)
{
MOVE_MESSAGE ret_val = SUCCESS;
board * temp_board;
record* temp_rec = NULL;
if(pos.getx() > 2 || pos.gety() > 2 || pos.getx() < 0 || pos.gety() < 0 || which_player < PLAYER_ZERO) ret_val = OUT_OF_BOUNDS;
else if(get_cell(pos).is_occupied()) ret_val = NO_VACANCY;
else if(out == NULL)//standard with output
{
if(empty) empty = false;
access(pos)->assign((which_player == PLAYER1) ? P1_symbol : (which_player == PLAYER2) ? P2_symbol : '\0');
temp_rec = new record(curr_turn, access(pos), which_player);
}
else//standard without output
{
temp_board = new board;
*temp_board = *this;
temp_board->move(which_player, pos, NULL, NULL);
*out = *temp_board;
delete temp_board;
}//end if else-if(s)
if(msg_out != NULL) *msg_out = ret_val;
if(temp_rec != NULL)
{
history.push_back(*temp_rec);
curr_turn++;
delete temp_rec;
}
return ret_val;
}
cell* board::get_win_set(int index)
{
if(!won || index < 0 || index > 2) return NULL;
return &win_set[index];
}
record board::get_entry(int index)
{
if(index < 1) throw boardspace::exception::OUT_OF_BOUNDS();
return history[index - 1];
}
WIN_STATE board::CheckForWin(bool just_check = false, WIN_STATE* msg_out = NULL,vector <coord> skips = vector <coord> ())//This is a poorly designed function
{
WIN_STATE win_msg = WIN_STATE_ZERO;
int out_loop, in_loop, a = 0, b = 2;
bool a_skip = false;
//won = true;//DEBUG
if(won)
{
win_msg = (win_set[0].get_symbol() == P1_symbol) ? P1_WIN : P2_WIN;
goto CHECKFORWIN_END;
}
won = true;
for(out_loop = 0; out_loop < 3; out_loop++)//Checks rows
{
if((access(0,out_loop)->is_occupied()) && (access(0,out_loop)->get_symbol() == access(1,out_loop)->get_symbol()) && (access(0,out_loop)->get_symbol() == access(2,out_loop)->get_symbol()) && (access(1,out_loop)->get_symbol() == access(2,out_loop)->get_symbol()))
{
//BEGIN SKIP CODE
if(!skips.empty())
{
for(int q = 0; q < skips.size(); q++)
{
if((*access(0,out_loop) == skips[q]) || (*access(1,out_loop) == skips[q]) || (*access(2,out_loop) == skips[q]))
{
a_skip = true;
break;
}
}
}//if(!skips.empty())
if(a_skip)
{
a_skip = false;
continue;
}//END SKIP CODE
if(!just_check)
{
for(in_loop = 0; in_loop < 3; in_loop++) win_set[in_loop] = *access(in_loop,out_loop);
}
else won = false;
win_msg = (access(1,out_loop)->get_symbol() == P1_symbol) ? P1_WIN : P2_WIN;
goto CHECKFORWIN_END;
}
}
for(out_loop = 0; out_loop < 3; out_loop++)//Checks columns
{
if((access(out_loop,0)->is_occupied()) && (access(out_loop,0)->get_symbol() == access(out_loop,1)->get_symbol()) && (access(out_loop,0)->get_symbol() == access(out_loop,0)->get_symbol()) && (access(out_loop,1)->get_symbol() == access(out_loop,2)->get_symbol()))
{
//BEGIN SKIP CODE
if(!skips.empty())
{
for(int q = 0; q < skips.size(); q++)
{
if((*access(out_loop,0) == skips[q]) || (*access(out_loop,1) == skips[q]) || (*access(out_loop,2) == skips[q]))
{
a_skip = true;
break;
}
}
}//if(!skips.empty())
if(a_skip)
{
a_skip = false;
continue;
}//END SKIP CODE
if(!just_check)
{
for(in_loop = 0; in_loop < 3; in_loop++) win_set[in_loop] = *access(out_loop,in_loop);
}
else won = false;
win_msg = (access(out_loop,1)->get_symbol() == P1_symbol) ? P1_WIN : P2_WIN;
goto CHECKFORWIN_END;
}
}//Checks '\' diagonal
if((access(1,1)->is_occupied()) && (access(0,2)->get_symbol() == access(1,1)->get_symbol()) && (access(0,2)->get_symbol() == access(2,0)->get_symbol()) && (access(1,1)->get_symbol() == access(2,0)->get_symbol()))
{
//BEGIN SKIP CODE
if(!skips.empty())
{
for(int q = 0; q < skips.size(); q++)
{
if((*access(1,1) == skips[q]) || (*access(0,2) == skips[q]) || (*access(2,0) == skips[q]))
{
a_skip = true;
break;
}
}
}//if(!skips.empty())
if(a_skip)
{
a_skip = false;
}//END SKIP CODE
else
{
if(!just_check)
{
win_set[0] = *access(0,2);
win_set[1] = *access(1,1);
win_set[2] = *access(2,0);
}
else won = false;
win_msg = (access(1,1)->get_symbol() == P1_symbol) ? P1_WIN : P2_WIN;
goto CHECKFORWIN_END;
}
}//Checks '/' diagonal
else if((access(1,1)->is_occupied()) && (access(0,0)->get_symbol() == access(1,1)->get_symbol()) && (access(0,0)->get_symbol() == access(2,2)->get_symbol()) && (access(1,1)->get_symbol() == access(2,2)->get_symbol()))
{
//BEGIN SKIP CODE
if(!skips.empty())
{
for(int q = 0; q < skips.size(); q++)
{
if((*access(1,1) == skips[q]) || (*access(0,0) == skips[q]) || (*access(2,2) == skips[q]))
{
a_skip = true;
break;
}
}
}//if(!skips.empty())
if(a_skip)
{
a_skip = false;
}//END SKIP CODE
else
{
if(!just_check)
{
win_set[0] = *access(0,0);
win_set[1] = *access(1,1);
win_set[2] = *access(2,2);
}
else won = false;
win_msg = (access(1,1)->get_symbol() == P1_symbol) ? P1_WIN : P2_WIN;
goto CHECKFORWIN_END;
}
}//end '/' diagonal check
win_msg = KATZ;
for(out_loop = 0; out_loop < 3; out_loop++)// Checks for katz game
{
for(in_loop = 0; in_loop < 3; in_loop++)
{
//BEGIN SKIP CODE
if(!skips.empty())
{
for(int q = 0; q < skips.size(); q++)
{
if(*access(in_loop,out_loop) == skips[q])
{
a_skip = true;
continue;
}
}
}
if(a_skip)
{
a_skip = false;
continue;
}//END SKIP CODE
if(!access(in_loop,out_loop)->is_occupied())
{
win_msg = WIN_STATE_ZERO;
break;
}
}
}//for loop checking for katz
CHECKFORWIN_END://AHH GOTO REFERENCE! AUUGHHH!!!!
if(win_msg == WIN_STATE_ZERO) won = false;
if(msg_out != NULL) *msg_out = win_msg;
return win_msg;
}
void board::wipe()
{
int x;
for(x = 0; x < 3; x++)
{
for(int y = 0; y < 3; y++) access(x,y)->wipe();
}
for(x = 0; x < 3; x++) win_set[x].wipe();
history.clear();
won = false;
empty = true;
curr_turn = 0;
P1_symbol = P2_symbol = '\0';
}
record::record(int move_num_in, cell* spot_in, PLAYER player_in)
{
move_num = move_num_in;
spot = spot_in;
player = player_in;
}
record record::operator = (record other)
{
move_num = other.get_move_num();
spot = other.get_spot();
player = other.get_player();
return *this;
}
vector <record> board::FindHotSpots()
{
vector <record> hot_spots;
record* temp_rec = NULL;
PLAYER the_player = PLAYER1;
board checker;
WIN_STATE win_msg;
MOVE_MESSAGE move_msg;
for(int loop1 = 0; loop1 < 3; loop1++)
{
for(int loop2 = 0; loop2 < 3; loop2++)
{
for(int loop3 = 0; loop3 < 2; loop3++)
{
if(move(the_player,loop1,loop2,&checker,&move_msg) == SUCCESS)
{
checker.CheckForWin(true,&win_msg,vector<coord>());
switch(win_msg)
{
case P1_WIN: {
temp_rec = new record(-1,access(loop1,loop2),PLAYER1);
hot_spots.push_back(*temp_rec);
delete temp_rec;
temp_rec = NULL;
break;
}
case P2_WIN: {
temp_rec = new record(-1,access(loop1,loop2),PLAYER2);
hot_spots.push_back(*temp_rec);
delete temp_rec;
temp_rec = NULL;
break;
}
case KATZ: {
//cout << "KATZ game coming?\n the_player = " << the_player << endl;
break;
}
}//switch
}//if
else if(move_msg == NO_VACANCY) break;
switch_player(the_player);
}//loop3
}//loop2
}//loop1
return hot_spots;
}
PLAYER board::switch_player(PLAYER& p)
{
PLAYER ret = ((p == PLAYER1) ? PLAYER2 : (p == PLAYER_ZERO) ? PLAYER_ZERO : PLAYER1);
p = ret;
return ret;
}
main.cpp:
Code:
#include <cstdlib>
#include <iostream>
#include "board.h"
#include "cell.h"
#include "coordinates.h"
using namespace std;
using namespace cellspace;
using namespace boardspace;
char* MessageString(MOVE_MESSAGE msg);
void proto_test();
int vital_checks(PLAYER p, board& the_board);//returns 0 if NO move is made, nonzero otherwise
int auto_move(PLAYER p, board& the_board);
PLAYER other_player(PLAYER p);
void print_board(board& ttt);
void print_record(record in);//to be used in STL algorithms
int main(int argc, char *argv[])
{
try {
proto_test();
}//try
catch(coordinates::exception::undefined)
{ cout << "\"UNDEFINED\" exception" << endl; }
catch(boardspace::exception::OUT_OF_BOUNDS)
{ cout << "\"OUT_OF_BOUNDS\" exception" << endl; }
catch(...)
{ cout << "UNKNOWN EXCEPTION" << endl; }
system("PAUSE");
return EXIT_SUCCESS;
}
char* MessageString(MOVE_MESSAGE msg)
{
switch(msg)
{
case SUCCESS: return "SUCCESS";
case UNKNOWN_ERROR: return "UNKNOWN ERROR";
case NO_VACANCY: return "NO VACANCY";
case OUT_OF_BOUNDS: return "OUT OF BOUNDS";
default: return NULL;
}
return NULL;
}
void proto_test()
{
vector <record> hot_spots;
board ttt;
board checker;
MOVE_MESSAGE move_msg;
WIN_STATE win_msg;
int inx = 0,iny = 0;
PLAYER p = PLAYER2;
char resp;
while(cin >> inx >> iny)
{
if(inx == 33)
{
cout << "Log" << endl;
for_each(ttt.get_history_begin(),ttt.get_history_end(),print_record);
continue;
}
p = other_player(p);
if(vital_checks(p,ttt))//if the checks made a move
{
cout << "The vital checker overrided your move" << endl;
print_board(ttt);
if(ttt.CheckForWin(false,&win_msg,vector<coord>()) != WIN_STATE_ZERO)
{
switch(win_msg)
{
case P1_WIN: { cout << "Player 1 won." << endl; break; }
case P2_WIN: { cout << "Player 2 won." << endl; break; }
case KATZ: { cout << "Katz game: draw." << endl; break; }
default: { cout << "ERROR: Unexpected CheckForWin() result -- win_msg = " << win_msg << endl; break; }
}
ttt.wipe();
checker.wipe();
ttt.initialize('X','O');
}
continue;
}
ttt.move(p,inx,iny,NULL,&move_msg);//apply move on ttt to itself
print_board(ttt);
cout << MessageString(move_msg) << endl;
if(ttt.CheckForWin(false,&win_msg,vector<coord>()) != WIN_STATE_ZERO)
{
switch(win_msg)
{
case P1_WIN: { cout << "Player 1 won." << endl; break; }
case P2_WIN: { cout << "Player 2 won." << endl; break; }
case KATZ: { cout << "Katz game: draw." << endl; break; }
default: { cout << "ERROR: Unexpected CheckForWin() result -- win_msg = " << win_msg << endl; break; }
}
ttt.wipe();
checker.wipe();
ttt.initialize('X','O');
}
}//while(cin)
}//void proto_function()
void print_record(record in)
{
cout << "Move number: " << in.get_move_num() << '\n'
<< "Player: " << in.get_player() << '\n'
<< "Cell coord: " << in.get_spot()->print()/**/ << endl;
}
void print_board(board& ttt)
{
cout << ttt.get_cell(0,2).print() << ttt.get_cell(0,2).get_symbol() << ' ' << ttt.get_cell(1,2).print() << ttt.get_cell(1,2).get_symbol() << ' ' << ttt.get_cell(2,2).print() << ttt.get_cell(2,2).get_symbol() << '\n'
<< ttt.get_cell(0,1).print() << ttt.get_cell(0,1).get_symbol() << ' ' << ttt.get_cell(1,1).print() << ttt.get_cell(1,1).get_symbol() << ' ' << ttt.get_cell(2,1).print() << ttt.get_cell(2,1).get_symbol() << '\n'
<< ttt.get_cell(0,0).print() << ttt.get_cell(0,0).get_symbol() << ' ' << ttt.get_cell(1,0).print() << ttt.get_cell(1,0).get_symbol() << ' ' << ttt.get_cell(2,0).print() << ttt.get_cell(2,0).get_symbol() << endl;
}
PLAYER other_player(PLAYER p)
{
return ((p == PLAYER1) ? PLAYER2 : (p == PLAYER_ZERO) ? PLAYER_ZERO : PLAYER1);
}
int vital_checks(PLAYER p, board& the_board)
{
vector<record> finds(the_board.FindHotSpots());
vector<record>::iterator iter;
if(finds.empty()) return 0;
else
{
iter = find_if(finds.begin(),finds.end(),is_player(p));
if(iter != finds.end())
{
the_board.move(p,iter->get_spot()->getx(),iter->get_spot()->gety(),NULL,NULL);
return 1;
}
else
{
iter = find_if(finds.begin(),finds.end(),is_player(other_player(p)));
if(iter != finds.end())
{
the_board.move(p,iter->get_spot()->getx(),iter->get_spot()->gety(),NULL,NULL);
return 1;
}
}
}
return 0;
}
int auto_move(PLAYER p, board& the_board)
{
MOVE_MESSAGE move_msg;
if(vital_checks(p,the_board)) return 0;
else
{
the_board.move(p,positions::CENTER,NULL,&move_msg);
if(move_msg == SUCCESS) return 1;
}
//TODO: finish function!
return 0;
}