#include #include using std::string; #define PLAYERA 'A' #define PLAYERB 'B' #include "Game.h" #include "Output.h" /**************************************/ void ParseCommandLine(int argc, char** argv); void generateMove(char player, int c, int r, SquareId& s, Game& g, int l); void generateComputerMove(char player, Game& g, char type_of_move, int search_depth); void generateComputerMove_MiniMax(char player, Game& g, int depth, char heuristic); void generateComputerMove_Random(char player, Game& g); void generateComputerMove_playToLoss(char player, Game& g, int depth); bool gameOver(Game& g, int length); /**************************************/ /** variables that store command line options **/ vector dimensionSizes; vector openFaces; int runLength; int cutoff; char playerADisposition; char playerBDisposition; /**************************************/ int main(int argc, char** argv) { ParseCommandLine(argc,argv); OUTPUT("--------------------------- GAME DEFINITION\n"); OUTPUT("dimensions: "); for (int i = 0; i < (int) dimensionSizes.size(); i++) { OUTPUT("%d ", dimensionSizes[i]); } OUTPUT("\n"); OUTPUT("open faces: "); for (int i = 0; i < (int) openFaces.size(); i++) { OUTPUT("%d ", openFaces[i]); } OUTPUT("\n"); OUTPUT("winning run length: %d\n", runLength); OUTPUT("cutoff depth: %d\n", cutoff); OUTPUT("player A: %c\n", playerADisposition); OUTPUT("player B: %c\n", playerBDisposition); OUTPUT("--------------------------- \n"); Game game(dimensionSizes.size(), runLength); for (int i = 0; i < (int) dimensionSizes.size(); i++) { game.board.SetDimensionSize(i,dimensionSizes[i]); } for (int i = 0; i < (int) openFaces.size(); i++) { game.board.SetOpenFace(openFaces[i]); } game.board.Print(); int moves = 0; while(!(gameOver(game,runLength))) { generateComputerMove(PLAYERA, game, playerADisposition, cutoff); moves++; if(!(gameOver(game,runLength))) { generateComputerMove(PLAYERB, game, playerBDisposition, cutoff); moves++; } } // declare outcome if (game.board.IsDraw()) { OUTPUT("draw "); } else if (game.board.IsWin(runLength, PLAYERA)) { OUTPUT("A wins "); } else if (game.board.IsWin(runLength, PLAYERB)) { OUTPUT("B wins "); } OUTPUT("in %d moves\n", moves); return 0; } /**************************************/ void ParseCommandLine(int argc, char** argv) { bool parsingDims = false; bool parsingFaces = false; bool parsingRun = false; bool parsingPlayerADisp = false; bool parsingPlayerBDisp = false; bool parsingCutoff = false; for (int i = 1; i < argc; i++) { string key(argv[i]); if (key == "-dimensions") { parsingDims = true; parsingFaces = false; parsingRun = false; parsingPlayerADisp = false; parsingPlayerBDisp = false; parsingCutoff = false; } else if (key == "-openFaces") { parsingDims = false; parsingFaces = true; parsingRun = false; parsingPlayerADisp = false; parsingPlayerBDisp = false; parsingCutoff = false; } else if (key == "-winLength") { parsingDims = false; parsingFaces = false; parsingRun = true; parsingPlayerADisp = false; parsingPlayerBDisp = false; parsingCutoff = false; } else if (key == "-playerA") { parsingDims = false; parsingFaces = false; parsingRun = false; parsingPlayerADisp = true; parsingPlayerBDisp = false; parsingCutoff = false; } else if (key == "-playerB") { parsingDims = false; parsingFaces = false; parsingRun = false; parsingPlayerADisp = false; parsingPlayerBDisp = true; parsingCutoff = false; } else if (key == "-cutoff") { parsingDims = false; parsingFaces = false; parsingRun = false; parsingPlayerADisp = false; parsingPlayerBDisp = false; parsingCutoff = true; } else if (parsingDims) { int sz = atoi(argv[i]); dimensionSizes.push_back(sz); } else if (parsingFaces) { int f = atoi(argv[i]); openFaces.push_back(f); } else if (parsingRun) { runLength = atoi(argv[i]); } else if (parsingPlayerADisp) { playerADisposition = argv[i][0]; } else if (parsingPlayerBDisp) { playerBDisposition = argv[i][0]; } else if (parsingCutoff) { cutoff = atoi(argv[i]); } else if (parsingRun) { runLength = atoi(argv[i]); } else { CRASH("Unable to parse command line"); } } } void generateMove(char player, int c, int r, SquareId& s, Game& g, int l) { OUTPUT("--------------------------- MOVE\n"); s[0] = c; s[1] = r; Move move(player,2,s); move.Print(); g.board.MakeMove(move); g.board.Print(); OUTPUT("--------------------------- CHECK WIN A "); g.board.IsWin(l, PLAYERA); OUTPUT("\n--------------------------- CHECK WIN B "); g.board.IsWin(l, PLAYERB); OUTPUT("\n"); } bool gameOver(Game& g, int length) { if(g.board.IsWin(length,PLAYERA)) return true; if(g.board.IsWin(length,PLAYERB)) return true; if(g.board.fullBoard()) return true; return false; } void generateComputerMove(char player, Game& g, char type_of_move, int depth) { if((type_of_move == OPTIMISTIC) || (type_of_move == PESSIMISTIC) || (type_of_move == UNCERTAIN)) generateComputerMove_MiniMax(player, g, depth, type_of_move); if(type_of_move == RANDOM) generateComputerMove_Random(player, g); if(type_of_move == LOSER) generateComputerMove_playToLoss(player, g, depth); } void generateComputerMove_MiniMax(char player, Game& g, int depth, char heuristic) { OUTPUT("--------------------------- MOVE by %c NORMAL\n", player); Move bmove = g.MiniMax(player, g.board, depth, heuristic); bmove.Print(); g.board.MakeMove(bmove); g.board.Print(); } void generateComputerMove_Random(char player, Game& g) { OUTPUT("--------------------------- MOVE by %c RANDOM\n", player); Move bmove = g.Random(player, g.board); bmove.Print(); g.board.MakeMove(bmove); g.board.Print(); } void generateComputerMove_playToLoss(char player, Game& g, int depth) { OUTPUT("--------------------------- MOVE by %c LOSER\n", player); Move bmove = g.playToLoss(player, g.board, depth); bmove.Print(); g.board.MakeMove(bmove); g.board.Print(); }