+/**
+ * Tokenise a string
+ */
+int Game::Tokenise(std::vector<string> & buffer, std::string & str, char split)
+{
+ string token = "";
+ for (unsigned int x = 0; x < str.size(); ++x)
+ {
+ if (str[x] == split && token.size() > 0)
+ {
+ buffer.push_back(token);
+ token = "";
+ }
+ if (str[x] != split)
+ token += str[x];
+ }
+ if (token.size() > 0)
+ buffer.push_back(token);
+ 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();
+}
+
+
+void Game::PrintResults(const MovementResult & result, string & buffer)
+{
+ stringstream s("");
+ switch (Game::theGame->Turn())
+ {
+ case Piece::RED:
+ s << Game::theGame->red->name << " RED ";
+ break;
+ case Piece::BLUE:
+ s << Game::theGame->blue->name << " BLUE ";
+ break;
+ case Piece::BOTH:
+ s << "neither BOTH ";
+ break;
+ case Piece::NONE:
+ s << "neither NONE ";
+ break;
+ }
+
+ if (!Board::LegalResult(result) && result != MovementResult::BAD_SETUP)
+ s << "ILLEGAL ";
+ else if (!Board::HaltResult(result))
+ s << "INTERNAL_ERROR ";
+ else
+ {
+ switch (result.type)
+ {
+ case MovementResult::VICTORY_FLAG:
+ case MovementResult::VICTORY_ATTRITION: //It does not matter how you win, it just matters that you won!
+ s << "VICTORY ";
+ break;
+ case MovementResult::SURRENDER:
+ s << "SURRENDER ";
+ break;
+ case MovementResult::DRAW:
+ s << "DRAW ";
+ break;
+ case MovementResult::DRAW_DEFAULT:
+ s << "DRAW_DEFAULT ";
+ break;
+ case MovementResult::BAD_SETUP:
+ s << "BAD_SETUP ";
+ break;
+ default:
+ s << "INTERNAL_ERROR ";
+ break;
+ }
+ }
+
+ s << Game::theGame->TurnCount() << " " << Game::theGame->theBoard.TotalPieceValue(Piece::RED) << " " << Game::theGame->theBoard.TotalPieceValue(Piece::BLUE);
+
+ buffer = s.str();
+
+
+}