Game* Game::theGame = NULL;
bool Game::gameCreated = false;
-Game::Game(const char * redPath, const char * bluePath, const bool enableGraphics, double newStallTime, const bool allowIllegal, FILE * newLog, const Piece::Colour & newReveal, int newMaxTurns, bool newPrintBoard, double newTimeoutTime) : red(NULL), blue(NULL), turn(Piece::RED), theBoard(10,10), graphicsEnabled(enableGraphics), stallTime(newStallTime), allowIllegalMoves(allowIllegal), log(newLog), reveal(newReveal), turnCount(0), input(NULL), maxTurns(newMaxTurns), printBoard(newPrintBoard), timeoutTime(newTimeoutTime)
+Game::Game(const char * redPath, const char * bluePath, const bool enableGraphics, double newStallTime, const bool allowIllegal, FILE * newLog, const Piece::Colour & newReveal, int newMaxTurns, bool newPrintBoard, double newTimeoutTime, const char * newImageOutput) : red(NULL), blue(NULL), turn(Piece::RED), theBoard(10,10), graphicsEnabled(enableGraphics), stallTime(newStallTime), allowIllegalMoves(allowIllegal), log(newLog), reveal(newReveal), turnCount(0), input(NULL), maxTurns(newMaxTurns), printBoard(newPrintBoard), timeoutTime(newTimeoutTime), imageOutput(newImageOutput)
{
gameCreated = false;
if (gameCreated)
Graphics::Initialise("Stratego", theBoard.Width()*32, theBoard.Height()*32);
#endif //BUILD_GRAPHICS
- if (strcmp(redPath, "human") == 0)
- red = new Human_Controller(Piece::RED, graphicsEnabled);
- else
- red = new AI_Controller(Piece::RED, redPath, timeoutTime);
-
-
- if (strcmp(bluePath, "human") == 0)
- blue = new Human_Controller(Piece::BLUE, graphicsEnabled);
- else
- blue = new AI_Controller(Piece::BLUE, bluePath, timeoutTime);
+ MakeControllers(redPath, bluePath);
+
+ if (red == NULL || blue == NULL)
+ {
+ fprintf(stderr, "Game::Game - Error creating controller: ");
+ if (red == NULL)
+ {
+ if (blue == NULL)
+ fprintf(stderr, " BOTH! (red: \"%s\", blue: \"%s\"\n", redPath, bluePath);
+ else
+ fprintf(stderr, " RED! (red: \"%s\")\n", redPath);
+ }
+ else
+ fprintf(stderr, "BLUE! (blue: \"%s\")\n", bluePath);
+ exit(EXIT_FAILURE);
+ }
+// logMessage("Game initialised.\n");
}
-Game::Game(const char * fromFile, const bool enableGraphics, double newStallTime, const bool allowIllegal, FILE * newLog, const Piece::Colour & newReveal, int newMaxTurns, bool newPrintBoard, double newTimeoutTime) : red(NULL), blue(NULL), turn(Piece::RED), theBoard(10,10), graphicsEnabled(enableGraphics), stallTime(newStallTime), allowIllegalMoves(allowIllegal), log(newLog), reveal(newReveal), turnCount(0), input(NULL), maxTurns(newMaxTurns), printBoard(newPrintBoard), timeoutTime(newTimeoutTime)
+Game::Game(const char * fromFile, const bool enableGraphics, double newStallTime, const bool allowIllegal, FILE * newLog, const Piece::Colour & newReveal, int newMaxTurns, bool newPrintBoard, double newTimeoutTime,const char * newImageOutput) : red(NULL), blue(NULL), turn(Piece::RED), theBoard(10,10), graphicsEnabled(enableGraphics), stallTime(newStallTime), allowIllegalMoves(allowIllegal), log(newLog), reveal(newReveal), turnCount(0), input(NULL), maxTurns(newMaxTurns), printBoard(newPrintBoard), timeoutTime(newTimeoutTime), imageOutput(newImageOutput)
{
gameCreated = false;
if (gameCreated)
if (wait <= 0)
return;
- TimerThread timer(wait*1000000); //Wait in seconds
- timer.Start();
+
+
#ifdef BUILD_GRAPHICS
+
+
if (!graphicsEnabled)
{
- while (!timer.Finished());
- timer.Stop();
+ usleep(1000000*wait); //Wait in seconds
return;
}
- #endif //BUILD_GRAPHICS
+ TimerThread timer(wait*1000000); //Wait in seconds
+ timer.Start();
while (!timer.Finished())
{
- #ifdef BUILD_GRAPHICS
+
SDL_Event event;
while (SDL_PollEvent(&event))
{
break;
}
}
- #endif //BUILD_GRAPHICS
}
timer.Stop();
+
+ #else
+ usleep(wait*1000000); //Wait in seconds
+ #endif //BUILD_GRAPHICS
}
-
+// logMessage("Messaging red with \"START\"\n");
red->Message("START");
-
+ int moveCount = 0;
while (!Board::HaltResult(result) && (turnCount < maxTurns || maxTurns < 0))
{
#ifdef BUILD_GRAPHICS
if (graphicsEnabled)
+ {
theBoard.Draw(toReveal);
+ if (imageOutput != "")
+ {
+ string imageFile = "" + imageOutput + "/"+ itostr(moveCount) + ".bmp";
+ Graphics::ScreenShot(imageFile.c_str());
+ }
+
+ }
#endif //BUILD_GRAPHICS
turn = Piece::RED;
theBoard.PrintPretty(stdout, toReveal);
fprintf(stdout, "\n\n");
}
+
+ ++moveCount;
#ifdef BUILD_GRAPHICS
if (graphicsEnabled)
+ {
theBoard.Draw(toReveal);
+ if (imageOutput != "")
+ {
+ string imageFile = "" + imageOutput + "/" + itostr(moveCount) + ".bmp";
+ Graphics::ScreenShot(imageFile.c_str());
+ }
+ }
#endif //BUILD_GRAPHICS
else
ReadUserCommand();
-
+ ++moveCount;
++turnCount;
}
return buffer.size();
}
+/**
+ * Creates Controller baseds off strings. Takes into account controllers other than AI_Controller.
+ * @param redPath - Either the path to an AI_Controller compatable executable, or one of %human or %network or %network:[IP_ADDRESS]
+ * @param bluePath - Ditto
+ * Sets this->red to a controller using redPath, and this->blue to a controller using bluePath
+ * TODO: Make nicer (this function should be ~half the length)
+ */
+void Game::MakeControllers(const char * redPath, const char * bluePath)
+{
+ Network * redNetwork = NULL;
+ Network * blueNetwork = NULL;
+ //To allow for running two network controllers (I don't know why you would, but beside the point...) use two ports
+ static const int port1 = 4560;
+ static const int port2 = 4561;
+
+ if (redPath[0] == '@')
+ {
+ if (strcmp(redPath, "@human") == 0)
+ red = new Human_Controller(Piece::RED, graphicsEnabled);
+ else
+ {
+ const char * network = strstr(redPath, "@network");
+ if (network == NULL)
+ {
+ red = NULL;
+ return;
+ }
+ network = strstr(network, ":");
+
+ if (network == NULL)
+ {
+ logMessage("Creating server for red AI... ");
+ redNetwork = new Server(port1);
+ logMessage("Successful!\n");
+
+ }
+ else
+ {
+ network = (const char*)(network+1);
+ logMessage("Creating client for red AI... ");
+ redNetwork = new Client(network, port2);
+ logMessage("Connected to address %s\n", network);
+ }
+
+ logMessage(" (Red's responses will be received over the connection)\n");
+ red = new NetworkReceiver(Piece::RED, redNetwork);
+ }
+ }
+ else
+ red = new AI_Controller(Piece::RED, redPath, timeoutTime);
+
+ if (bluePath[0] == '@')
+ {
+ if (strcmp(bluePath, "@human") == 0)
+ blue = new Human_Controller(Piece::BLUE, graphicsEnabled);
+ else
+ {
+ const char * network = strstr(bluePath, "@network");
+ if (network == NULL)
+ {
+ blue = NULL;
+ return;
+ }
+ network = strstr(network, ":");
+
+ if (network == NULL)
+ {
+ logMessage("Creating server for blue AI... ");
+ blueNetwork = new Server(port2);
+ logMessage("Successful!\n");
+
+ }
+ else
+ {
+ network = (const char*)(network+1);
+ logMessage("Creating client for blue AI... ");
+ blueNetwork = new Client(network, port1);
+ logMessage("Connected to address %s\n", network);
+ }
+ logMessage(" (Blue's responses will be received over the connection)\n");
+ blue = new NetworkReceiver(Piece::BLUE, blueNetwork);
+ }
+ }
+ else
+ blue = new AI_Controller(Piece::BLUE, bluePath, timeoutTime);
+
+ if (redNetwork != NULL)
+ {
+
+ blue = new NetworkSender(Piece::BLUE,blue, redNetwork);
+ logMessage(" (Blue's responses will be copied over the connection)\n");
+ }
+ if (blueNetwork != NULL)
+ {
+
+ red = new NetworkSender(Piece::RED, red, blueNetwork);
+ logMessage(" (Red's responses will be copied over the connection)\n");
+ }
+
+ red->FixName(); blue->FixName();
+
+}
+
+string itostr(int i)
+{
+ stringstream s;
+ s << i;
+ return s.str();
+}