Wrote python script to simulate a round
[progcomp2012.git] / manager / main.cpp
index 4f203d9..01a7fab 100644 (file)
 #include <stdlib.h>
 #include <stdio.h>
 
-#include "common.h"
-
-#include "controller.h"
-#include "stratego.h"
-
-using namespace std;
 
 
 
-#define theBoard Board::theBoard
 
-#ifdef GRAPHICS
-       bool CheckForQuitWhilstWaiting(int wait);
-#endif //GRAPHICS
 
-Controller * red;
-Controller * blue;
-Colour turn;
+#include "game.h"
 
-void cleanup();
+using namespace std;
 
-void BrokenPipe(int sig);
+void CreateGame(int argc, char ** argv);
+void DestroyGame();
+void PrintResults(const MovementResult & result);
 
 int main(int argc, char ** argv)
 {
-       assert(argc == 3);
        
-       for (int y = 5; y < 9; ++y)
-       {
-               for (int x = 3; x < 5; ++x)
-               {
-                       theBoard.AddPiece(x,y,Piece::BOULDER, Piece::NONE);
-               }
-               for (int x = 9; x < 11; ++x)
-               {
-                       theBoard.AddPiece(x,y,Piece::BOULDER, Piece::NONE);
-               }
-       }
 
-       red = new Controller(Piece::RED, argv[1]);
-       blue = new Controller(Piece::BLUE, argv[2]);
-       atexit(cleanup);
-       signal(SIGPIPE, BrokenPipe);
 
-       MovementResult redSetup = red->Setup(argv[2]);
-       MovementResult blueSetup = blue->Setup(argv[1]);
-       if (redSetup != MovementResult::OK)
+       if (argc == 1)
        {
-               fprintf(stderr, "Blue wins by DEFAULT!\n");
-               red->SendMessage("ILLEGAL");
-               blue->SendMessage("DEFAULT");
+               fprintf(stderr, "Usage: stratego [options] red blue\n");
+               fprintf(stderr, "       stratego --help\n");
                exit(EXIT_SUCCESS);
+               
        }
-       if (blueSetup != MovementResult::OK)
+       CreateGame(argc, argv);
+       if (Game::theGame == NULL)
        {
-               fprintf(stderr, "Red wins by DEFAULT!\n");
-               red->SendMessage("DEFAULT");
-               blue->SendMessage("ILLEGAL");
-               exit(EXIT_SUCCESS);
+               fprintf(stderr, "ERROR: Couldn't create a game!\n");
+               exit(EXIT_FAILURE);
        }
 
-       MovementResult result(MovementResult::OK);
-       system("clear");
-       int count = 1;
+       MovementResult result = Game::theGame->Play();
+       Game::theGame->PrintEndMessage(result);
+       PrintResults(result);
 
-       #ifdef GRAPHICS
-               if (!Graphics::Initialised())
-                       Graphics::Initialise("Stratego", theBoard.Width()*32, theBoard.Height()*32);
-               
-       #endif //GRAPHICS
-
-       string buffer;
+       exit(EXIT_SUCCESS);
+       return 0;
+}
 
-       red->SendMessage("START");
-       turn = Piece::RED;
-       while (Board::LegalResult(result))
+void CreateGame(int argc, char ** argv)
+{
+       char * red = NULL; char * blue = NULL; double timeout = 0.00001; bool graphics = false; bool allowIllegal = false; FILE * log = NULL;
+       Piece::Colour reveal = Piece::BOTH; char * inputFile = NULL; int maxTurns = 5000; bool printBoard = false;
+       for (int ii=1; ii < argc; ++ii)
        {
-
-               
-               turn = Piece::RED;
-               fprintf(stderr, "%d RED: ", count);
-               result = red->MakeMove(buffer);
-               red->SendMessage(buffer);
-               blue->SendMessage(buffer);
-               fprintf(stderr, "%s\n", buffer.c_str());
-               if (!Board::LegalResult(result))
-                       break;
-               #ifdef GRAPHICS
-                       Board::theBoard.Draw();
-                       if (CheckForQuitWhilstWaiting(0.2))
+               if (argv[ii][0] == '-')
+               {
+                       switch (argv[ii][1])
                        {
-                               red->SendMessage("QUIT");
-                               blue->SendMessage("QUIT");
-                               exit(EXIT_SUCCESS);
-                       }
-               #endif //GRAPHICS
-               
-               turn = Piece::BLUE;
-               fprintf(stderr, "%d BLU: ", count);
-               result = blue->MakeMove(buffer);
-               blue->SendMessage(buffer);
-               red->SendMessage(buffer);
-               fprintf(stderr, "%s\n", buffer.c_str());
-
-               if (!Board::LegalResult(result))
-                       break;
-
-               
+                               case 't':
+                                       if (argc - ii <= 1)
+                                       {
+                                               fprintf(stderr, "Expected timeout value after -t switch!\n");
+                                               exit(EXIT_FAILURE);
+                                       }
+                                       timeout = atof(argv[ii+1]);
+                                       ++ii;
+                                       break;
+                               case 'g':
+                                       graphics = !graphics;
+                                       break;
+                               case 'p':
+                                       printBoard = !printBoard;
+                                       break;
+                               case 'i':
+                                       allowIllegal = !allowIllegal;
+                                       break;
 
-               #ifdef GRAPHICS
-                       Board::theBoard.Draw();
-                       if (CheckForQuitWhilstWaiting(0.2))
-                       {
-                               red->SendMessage("QUIT");
-                               blue->SendMessage("QUIT");
-                               exit(EXIT_SUCCESS);
+                               case 'o':
+                                       if (argc - ii <= 1)
+                                       {
+                                               fprintf(stderr, "Expected filename or \"stdout\" after -o switch!\n");
+                                               exit(EXIT_FAILURE);
+                                       }
+                                       if (log != NULL)
+                                       {
+                                               fprintf(stderr, "Expected at most ONE -o switch!\n");
+                                               exit(EXIT_FAILURE);
+                                       }
+                                       if (strcmp(argv[ii+1], "stdout") == 0)
+                                               log = stdout;
+                                       else
+                                               log = fopen(argv[ii+1], "w");
+                                       setbuf(log, NULL);
+                               
+                                       ++ii;
+                                       break;  
+
+                               case 'r':
+                                       if (reveal == Piece::BOTH)
+                                               reveal = Piece::BLUE;
+                                       else
+                                               reveal = Piece::NONE;
+                                       break;                  
+                               case 'b':
+                                       if (reveal == Piece::BOTH)
+                                               reveal = Piece::RED;
+                                       else
+                                               reveal = Piece::NONE;
+                                       break;
+                               case 'm':
+                                       if (argc - ii <= 1)
+                                       {
+                                               fprintf(stderr, "Expected max_turns value after -m switch!\n");
+                                               exit(EXIT_FAILURE);
+                                       }
+                                       if (strcmp(argv[ii+1], "inf"))
+                                               maxTurns = -1;
+                                       else
+                                               maxTurns = atoi(argv[ii+1]);
+                                       ++ii;
+                                       break;
+                               case 'f':
+                                       if (argc - ii <= 1)
+                                       {
+                                               fprintf(stderr, "Expected filename after -f switch!\n");
+                                               exit(EXIT_FAILURE);
+                                       }
+                                       if (log != NULL)
+                                       {
+                                               fprintf(stderr, "Expected at most ONE -f switch!\n");
+                                               exit(EXIT_FAILURE);
+                                       }
+                                       red = (char*)("file");
+                                       blue = (char*)("file");
+                                       inputFile = argv[ii+1];
+                                       ++ii;
+                                       break;
+                               case 'h':
+                                       system("clear");        
+                                       system("less manual.txt");
+                                       exit(EXIT_SUCCESS);
+                                       break;
+                               case '-':
+                                       if (strcmp(argv[ii]+2, "help") == 0)
+                                       {
+                                               system("clear");        
+                                               system("less manual.txt");
+                                               exit(EXIT_SUCCESS);
+                                       }
+                                       else
+                                       {
+                                               fprintf(stderr, "Unrecognised switch \"%s\"...\n", argv[ii]);
+                                               exit(EXIT_FAILURE);
+                                       }
                        }
-               #else
-                       Board::theBoard.Print(stderr);
-                       sleep(1);
-                       system("clear");
-               #endif //GRAPHICS
-               
-               ++count;
-       }
-
-       printf("Final board state\n");
-       #ifdef GRAPHICS
-                       Board::theBoard.Draw();
-                       if (CheckForQuitWhilstWaiting(4))
+                       
+               }
+               else
+               {
+                       if (red == NULL)
+                               red = argv[ii];
+                       else if (blue == NULL)
+                               blue = argv[ii];
+                       else
                        {
-                               red->SendMessage("QUIT");
-                               blue->SendMessage("QUIT");
-                               exit(EXIT_SUCCESS);
+                               fprintf(stderr, "Unexpected argument \"%s\"...\n", argv[ii]);
+                               exit(EXIT_FAILURE);
                        }
-       #else
-               Board::theBoard.Print(stderr);
-       #endif //GRAPHICS
-       sleep(2);
-
-
-       if (turn == Piece::RED)
-       {
-               fprintf(stderr,"Game ends on RED's turn - REASON: ");   
+               }
        }
-       else if (turn == Piece::BLUE)
+
+       if (inputFile == NULL)
        {
-               fprintf(stderr,"Game ends on BLUE's turn - REASON: ");
+               Game::theGame = new Game(red,blue, graphics, timeout, allowIllegal,log, reveal,maxTurns, printBoard);
        }
        else
        {
-               fprintf(stderr,"Game ends on ERROR's turn - REASON: ");
-                       
+               Game::theGame = new Game(inputFile, graphics, timeout, allowIllegal,log, reveal,maxTurns, printBoard);
        }
-       switch (result.type)
+       if (!Game::theGame->Setup(red, blue))
        {
-               case MovementResult::NO_BOARD:
-                       fprintf(stderr,"Board does not exit?!\n");
-                       break;
-               case MovementResult::INVALID_POSITION:
-                       fprintf(stderr,"Coords outside board\n");
-                       break;
-               case MovementResult::NO_SELECTION:
-                       fprintf(stderr,"Move does not select a piece\n");
-                       break;
-               case MovementResult::NOT_YOUR_UNIT:
-                       fprintf(stderr,"Selected piece belongs to other player\n");
-                       break;
-               case MovementResult::IMMOBILE_UNIT:
-                       fprintf(stderr,"Selected piece is not mobile (FLAG or BOMB)\n");
-                       break;
-               case MovementResult::INVALID_DIRECTION:
-                       fprintf(stderr,"Selected unit cannot move that way\n");
-                       break;
-               case MovementResult::POSITION_FULL:
-                       fprintf(stderr,"Attempted move into square occupied by allied piece\n");
-                       break;
-               case MovementResult::VICTORY:
-                       fprintf(stderr,"Captured the flag\n");
-                       break;
-               case MovementResult::BAD_RESPONSE:
-                       fprintf(stderr,"Unintelligable response\n");
-                       break;
-               case MovementResult::NO_MOVE:
-                       fprintf(stderr,"Did not make a move (may have exited)\n");
-                       break;
+               fprintf(stdout, "NONE %d\n",Game::theGame->TurnCount());
+               exit(EXIT_SUCCESS);
        }
-
-
-
-       exit(EXIT_SUCCESS);
        
-       return 0;
-}
+       atexit(DestroyGame);
 
-#ifdef GRAPHICS
+}
 
-bool CheckForQuitWhilstWaiting(int wait)
+void PrintResults(const MovementResult & result)
 {
-
-
-       TimerThread timer(wait*1000000); //Wait in seconds
-       timer.Start();
-       while (!timer.Finished())
+       Piece::Colour winner = Game::theGame->Turn();
+       if (Board::LegalResult(result))
        {
-               SDL_Event  event;
-               while (SDL_PollEvent(&event))
+               if (winner == Piece::BOTH)
+                       winner = Piece::NONE;
+               else
                {
-                       switch (event.type)
-                       {
-                               case SDL_QUIT:
-                                       timer.Stop();
-                                       return true;
-                                       break;
-                       }
+                       if (winner == Piece::RED)
+                               winner = Piece::BLUE;
+                       else
+                               winner = Piece::RED;
                }
        }
-       timer.Stop();
-       return false;
-}
+       
 
-void cleanup()
-{
-       delete red;
-       delete blue;
+       switch (winner)
+       {
+               case Piece::RED:
+                       fprintf(stdout, "%s RED %d\n", Game::theGame->red->name.c_str(),Game::theGame->TurnCount());    
+                       Game::theGame->logMessage("%s RED %d\n", Game::theGame->red->name.c_str(),Game::theGame->TurnCount());
+                       break;
+               case Piece::BLUE:
+                       fprintf(stdout, "%s BLUE %d\n", Game::theGame->blue->name.c_str(),Game::theGame->TurnCount());  
+                       Game::theGame->logMessage("%s BLUE %d\n", Game::theGame->blue->name.c_str(),Game::theGame->TurnCount());
+                       break;
+               case Piece::BOTH:
+                       fprintf(stdout, "DRAW %d\n",Game::theGame->TurnCount());
+                       Game::theGame->logMessage("DRAW %d\n",Game::theGame->TurnCount());      
+                       break;
+               case Piece::NONE:
+                       fprintf(stdout, "NONE %d\n",Game::theGame->TurnCount());        
+                       Game::theGame->logMessage("NONE %d\n",Game::theGame->TurnCount());
+                       break;
+
+       }
 }
 
-void BrokenPipe(int sig)
+void DestroyGame()
 {
-       if (turn == Piece::RED)
-       {
-               fprintf(stderr,"Game ends on RED's turn - REASON: Broken pipe\n");
-               blue->SendMessage("DEFAULT");   
-       }
-       else if (turn == Piece::BLUE)
-       {
-               fprintf(stderr,"Game ends on BLUE's turn - REASON: Broken pipe\n");
-               red->SendMessage("DEFAULT");
-       }
-       else
-       {
-               fprintf(stderr,"Game ends on ERROR's turn - REASON: Broken pipe\n");
-                       
-       }
-       exit(EXIT_SUCCESS);
+       delete Game::theGame;
+       Game::theGame = NULL;
 }
-       
-#endif //GRAPHICS

UCC git Repository :: git.ucc.asn.au