diff --git a/judge/manager/Makefile b/judge/manager/Makefile index 199a3afda0d975e50e71472d941a25d78292f2eb..e06e1810c2667599266dea70288d75c2ad8643b6 100644 --- a/judge/manager/Makefile +++ b/judge/manager/Makefile @@ -1,13 +1,13 @@ #Makefile for Stratego #Use this to build with graphics -#LIBRARIES = -lSDL -lGL -lpthread +LIBRARIES = -lSDL -lGL -lpthread #Use this to build without graphics -LIBRARIES = -lpthread +#LIBRARIES = -lpthread #Use this on Mac OSX (Thanks spartan) #LIBRARIES = -I/opt/local/include/ -L/opt/local/lib/ -lSDL -framework OpenGL -lpthread CPP = g++ -Wall -pedantic -g -OBJ = main.o controller.o network_controller.o ai_controller.o human_controller.o program.o thread_util.o stratego.o graphics.o game.o +OBJ = main.o controller.o network_controller.o ai_controller.o human_controller.o program.o network.o thread_util.o stratego.o graphics.o game.o BIN = stratego diff --git a/judge/manager/ai_controller.h b/judge/manager/ai_controller.h index f4682eb2de00bda227f8952e77a4690d6083c2bd..0a4baeb7cbbb66730f39d9d6271484a45c8d2c0d 100644 --- a/judge/manager/ai_controller.h +++ b/judge/manager/ai_controller.h @@ -19,7 +19,11 @@ class AI_Controller : public Controller, private Program virtual MovementResult QuerySetup(const char * opponentName,std::string setup[]); virtual MovementResult QueryMove(std::string & buffer); - virtual void Message(const char * message) {Program::SendMessage(message);} + virtual void Message(const char * message) + { + //fprintf(stderr, "Sending message \"%s\" to AI program...\n", message); + Program::SendMessage(message); + } virtual void Pause() {Program::Pause();} //Hack wrapper virtual void Continue() {Program::Continue();} //Hack wrapper diff --git a/judge/manager/game.cpp b/judge/manager/game.cpp index 92dc71ab349c96d0bad905ee9ae82926a1f8c176..f25c9f381cfcc62f25eaa951b3928bd34e44468d 100644 --- a/judge/manager/game.cpp +++ b/judge/manager/game.cpp @@ -7,7 +7,7 @@ using namespace std; 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, bool server, bool client) : 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) : 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) { gameCreated = false; if (gameCreated) @@ -26,34 +26,24 @@ Game::Game(const char * redPath, const char * bluePath, const bool enableGraphic #endif //BUILD_GRAPHICS - if (client) - { - red = new Client(Piece::RED, "server", redPath); //TODO: Retrieve server address - } - else - { - assert(redPath != NULL); - if (strcmp(redPath, "human") == 0) - red = new Human_Controller(Piece::RED, graphicsEnabled); - else - red = new AI_Controller(Piece::RED, redPath, timeoutTime); - } - - - if (server) - { - blue = new Server(Piece::BLUE, "client"); - } - else + + MakeControllers(redPath, bluePath); + + if (red == NULL || blue == NULL) { - assert(bluePath != NULL); - if (strcmp(bluePath, "human") == 0) - blue = new Human_Controller(Piece::BLUE, graphicsEnabled); + 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 - blue = new AI_Controller(Piece::BLUE, bluePath, timeoutTime); + 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) @@ -489,7 +479,7 @@ MovementResult Game::Play() - + logMessage("Messaging red with \"START\"\n"); red->Message("START"); @@ -770,4 +760,101 @@ int Game::Tokenise(std::vector<string> & buffer, std::string & str, char split) 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; + + 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(); + logMessage("Successful!\n"); + + } + else + { + network = (const char*)(network+1); + logMessage("Creating client for red AI... "); + redNetwork = new Client(network); + 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(); + logMessage("Successful!\n"); + + } + else + { + network = (const char*)(network+1); + logMessage("Creating client for blue AI... "); + blueNetwork = new Client(network); + 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"); + } + +} diff --git a/judge/manager/game.h b/judge/manager/game.h index cc79e656bd278be678ebc1b4467c314836eb9551..3f46abb43ff8a4c5d4f3151a6a60bbcc44281d87 100644 --- a/judge/manager/game.h +++ b/judge/manager/game.h @@ -15,7 +15,7 @@ class Game { public: - Game(const char * redPath, const char * bluePath, const bool enableGraphics, double newStallTime = 1.0, const bool allowIllegal=false, FILE * newLog = NULL, const Piece::Colour & newRevealed = Piece::BOTH, int maxTurns = 5000, const bool printBoard = false, double newTimeoutTime = 2.0, bool server=false, bool client=false); + Game(const char * redPath, const char * bluePath, const bool enableGraphics, double newStallTime = 1.0, const bool allowIllegal=false, FILE * newLog = NULL, const Piece::Colour & newRevealed = Piece::BOTH, int maxTurns = 5000, const bool printBoard = false, double newTimeoutTime = 2.0); Game(const char * fromFile, const bool enableGraphics, double newStallTime = 1.0, const bool allowIllegal=false, FILE * newLog = NULL, const Piece::Colour & newRevealed = Piece::BOTH, int maxTurns = 5000, const bool printBoard = false, double newTimeoutTime = 2.0); virtual ~Game(); @@ -38,6 +38,9 @@ class Game static Game * theGame; static int Tokenise(std::vector<std::string> & buffer, std::string & str, char split = ' '); //Helper - Split a string into tokens + + private: + void MakeControllers(const char * redPath, const char * bluePath); //Create a controller based off a path public: int logMessage(const char * format, ...); FILE * GetLogFile() const {return log;} diff --git a/judge/manager/graphics.h b/judge/manager/graphics.h index 2a969327d8a14790564067c76e9426ce8ee76083..caa57c69e49c3df05631a792c4bbff060aa3e1e9 100644 --- a/judge/manager/graphics.h +++ b/judge/manager/graphics.h @@ -1,4 +1,4 @@ -//#define BUILD_GRAPHICS +#define BUILD_GRAPHICS #ifdef BUILD_GRAPHICS #ifndef GRAPHICS_H diff --git a/judge/manager/main.cpp b/judge/manager/main.cpp index 08c381ce9492421599ed02e6b73ac6128fcb46e7..e65ef0d1b6a142781f821fc076a2d42b21b0d29d 100644 --- a/judge/manager/main.cpp +++ b/judge/manager/main.cpp @@ -64,7 +64,7 @@ Piece::Colour SetupGame(int argc, char ** argv) { char * red = NULL; char * blue = NULL; double stallTime = 0.0; bool graphics = false; bool allowIllegal = false; FILE * log = NULL; Piece::Colour reveal = Piece::BOTH; char * inputFile = NULL; int maxTurns = 5000; bool printBoard = false; double timeoutTime = 2.0; - bool server = false; bool client = false; + for (int ii=1; ii < argc; ++ii) { if (argv[ii][0] == '-') @@ -185,26 +185,6 @@ Piece::Colour SetupGame(int argc, char ** argv) system("less manual.txt"); exit(EXIT_SUCCESS); } - else if (strcmp(argv[ii]+2, "server") == 0) - { - if (client == true) - { - fprintf(stderr, "ARGUMENT_ERROR - Can't be both a server and a client!\n"); - exit(EXIT_FAILURE); - } - server = true; - - } - else if (strcmp(argv[ii]+2, "client") == 0) - { - if (server == true) - { - fprintf(stderr, "ARGUMENT_ERROR - Can't be both a server and a client!\n"); - exit(EXIT_FAILURE); - } - client = true; - - } else { fprintf(stderr, "ARGUMENT_ERROR - Unrecognised switch \"%s\"...\n", argv[ii]); @@ -232,37 +212,16 @@ Piece::Colour SetupGame(int argc, char ** argv) if (inputFile == NULL) { - if (server) + if (red == NULL || blue == NULL) //Not enough players { - if (red != NULL && blue != NULL) - { - fprintf(stderr, "ARGUMENT_ERROR - When using the --server switch, only supply ONE (1) player.\n"); - exit(EXIT_FAILURE); - } - } - else if (red == NULL || blue == NULL) //Not enough players - { - if (client) - fprintf(stderr, "ARGUMENT_ERROR - When using the --client switch, supply an IP for the Red player.\n"); - else - fprintf(stderr, "ARGUMENT_ERROR - Did not recieve enough players (did you mean to use the -f switch?)\n"); + fprintf(stderr, "ARGUMENT_ERROR - Did not recieve enough players (did you mean to use the -f switch?)\n"); exit(EXIT_FAILURE); } - - if (client) - { - blue = red; red = NULL; - } - Game::theGame = new Game(red,blue, graphics, stallTime, allowIllegal,log, reveal,maxTurns, printBoard, timeoutTime, server, client); + Game::theGame = new Game(red,blue, graphics, stallTime, allowIllegal,log, reveal,maxTurns, printBoard, timeoutTime); } else { - if (server || client) - { - fprintf(stderr, "ARGUMENT_ERROR - The -f switch is incompatable with the --server or --client switches!\n"); - exit(EXIT_FAILURE); - } Game::theGame = new Game(inputFile, graphics, stallTime, allowIllegal,log, reveal,maxTurns, printBoard, timeoutTime); } diff --git a/judge/manager/network.cpp b/judge/manager/network.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e349fea4cabfb85749929a7918cd0951189105a3 --- /dev/null +++ b/judge/manager/network.cpp @@ -0,0 +1,186 @@ +#include "network.h" +#include <stdarg.h> + +using namespace std; + +Network::Network(int newPort) : sfd(-1), port(newPort), file(NULL) +{ + sfd = socket(PF_INET, SOCK_STREAM, 0); + if (sfd < 0) + { + perror("Network::Network - Error creating TCP socket"); + exit(EXIT_FAILURE); + } +} + +Network::~Network() +{ + if (Valid()) + { + if (shutdown(sfd, SHUT_RDWR) == -1) + { + perror("Network::~Network - shutting down socket... "); + close(sfd); + sfd = -1; + } + } + close(sfd); +} + +Server::Server(int newPort) : Network(newPort) +{ + struct sockaddr_in name; +// char buf[1024]; +// int cc; + + + name.sin_family = AF_INET; + name.sin_addr.s_addr = htonl(INADDR_ANY); + name.sin_port = htons(port); + + if (bind( sfd, (struct sockaddr *) &name, sizeof(name) ) < 0) + { + perror("Server::Server - Error binding socket"); + close(sfd); sfd = -1; + exit(EXIT_FAILURE); + } + + if (listen(sfd,1) < 0) + { + perror("Server::Server - Error listening on socket"); + close(sfd); sfd = -1; + exit(EXIT_FAILURE); + } + int psd = accept(sfd, 0, 0); + close(sfd); + sfd = psd; + if (sfd < 0) + { + perror("Server::Server - Error accepting connection"); + close(sfd); sfd = -1; + exit(EXIT_FAILURE); + } + + + + /* + for(;;) + { + cc=recv(sfd,buf,sizeof(buf), 0) ; + if (cc == 0) exit (0); + buf[cc] = '\0'; + printf("message received: %s\n", buf); + } + */ +} + +Client::Client(const char * serverAddress, int newPort) : Network(newPort) +{ + struct sockaddr_in server; + struct hostent *hp; + + + server.sin_family = AF_INET; + hp = gethostbyname(serverAddress); + bcopy ( hp->h_addr, &(server.sin_addr.s_addr), hp->h_length); + server.sin_port = htons(port); + + if (connect(sfd, (struct sockaddr *) &server, sizeof(server)) < 0) + { + fprintf(stderr, "Client::Client - Error connecting to server at address %s: ", serverAddress); + perror(""); + close(sfd); sfd = -1; + exit(EXIT_FAILURE); + } + + + + + /* + for (;;) { + send(sfd, "HI", 2,0 ); + sleep(2); + } + */ +} + +/** + * Sends a message accross the network + * WARNING: Always terminates the message with a newline '\n' + * @returns true if the message was successfully sent; false if it was not (ie: the network was not connected!) + */ +bool Network::SendMessage(const char * print, ...) +{ + if (!Valid()) //Is the process running... + return false; + + if (file == NULL) + { + file = fdopen(sfd, "r+"); + setbuf(file, NULL); + } + + va_list ap; + va_start(ap, print); + + if (vfprintf(file, print, ap) < 0 || fprintf(file, "\n") < 0) + { + va_end(ap); + return false; + } + va_end(ap); + + return true; +} + +/** + * Retrieves a message from the network, waiting a maximum amount of time + * @param buffer - C++ string to store the resultant message in + * @param timeout - Maximum amount of time to wait before failure. If timeout <= 0, then GetMessage will wait indefinately. + * @returns true if the response was recieved within the specified time, false if it was not, or an EOF was recieved, or the process was not running. + */ +bool Network::GetMessage(string & buffer, double timeout) +{ + if (!Valid() || timeout == 0) + return false; + + if (file == NULL) + { + file = fdopen(sfd, "r+"); + setbuf(file, NULL); + } + + assert(&buffer != NULL); + GetterThread getterThread(file, buffer); + assert(&(getterThread.buffer) != NULL); + + TimerThread timerThread(timeout*1000000); + + getterThread.Start(); + if (timeout > 0) + timerThread.Start(); + + + while (!getterThread.Finished()) + { + if (timeout > 0 && timerThread.Finished()) + { + getterThread.Stop(); + timerThread.Stop(); + return false; + } + } + + getterThread.Stop(); + if (timeout > 0) + timerThread.Stop(); + + + + if (buffer.size() == 1 && buffer[0] == EOF) + return false; + return true; + + +} + diff --git a/judge/manager/network.h b/judge/manager/network.h new file mode 100644 index 0000000000000000000000000000000000000000..1cd0a11fd7c45b0cf2b48886760b49fc5809cb1c --- /dev/null +++ b/judge/manager/network.h @@ -0,0 +1,53 @@ +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <netdb.h> +#include <fcntl.h> +#include <errno.h> + +#include <string> +#include "thread_util.h" + +#ifndef NETWORK_H +#define NETWORK_H + + +class Network +{ + public: + Network(int newPort = 666); + virtual ~Network(); + bool Valid() const {return sfd != -1;} + + bool SendMessage(const char * print, ...); //Sends a formated message (NOTE: Prints a newline) + bool SendMessage(const std::string & buffer) {return SendMessage(buffer.c_str());} //Sends a C++ string message + bool GetMessage(std::string & buffer, double timeout=-1); //Retrieves a message, or waits for a timeout (if positive) + + protected: + int sfd; + int port; + FILE * file; + +}; + +class Server : public Network +{ + public: + Server(int newPort = 4560); + virtual ~Server() {} + +}; + +class Client : public Network +{ + public: + Client(const char * server = "127.0.0.1", int newPort = 4560); + virtual ~Client() {} +}; + +#endif //NETWORK_H diff --git a/judge/manager/network_controller.cpp b/judge/manager/network_controller.cpp index 9d14676309feb47ca6b6ae90586ea3b06119cbc0..fcca84e619b9616248617eac6184db14ef4787e0 100644 --- a/judge/manager/network_controller.cpp +++ b/judge/manager/network_controller.cpp @@ -1,102 +1,39 @@ #include "network_controller.h" -NetworkController::NetworkController(const Piece::Colour & newColour, const char * newName) : Controller(newColour, newName), sfd(-1) -{ - //struct protoent * tcp = getprotobyname("tcp"); - - sfd = socket(PF_INET, SOCK_STREAM, 0); - if (sfd < 0) - { - perror("NetworkController::NetworkController - Error creating TCP socket"); - return; - } -} - -NetworkController::~NetworkController() -{ - if (Valid()) - { - if (shutdown(sfd, SHUT_RDWR) == -1) - { - perror("NetworkController::~NetworkController - shutting down socket... "); - close(sfd); - sfd = -1; - } - } - close(sfd); -} +using namespace std; -void NetworkController::Message(const char * string) +MovementResult NetworkSender::QuerySetup(const char * opponentName, string setup[]) { + //fprintf(stderr," NetworkSender::QuerySetup... "); + MovementResult result = controller->QuerySetup(opponentName, setup); + for (int ii=0; ii < 4; ++ii) + assert(network->SendMessage("%s",setup[ii].c_str())); //TODO: Proper error check + + //fprintf(stderr,"Done!\n"); + return result; } -Server::Server(const Piece::Colour & newColour, const char * newName) : NetworkController(newColour, newName) +MovementResult NetworkReceiver::QuerySetup(const char * opponentName, string setup[]) { - struct sockaddr_in name; - char buf[1024]; - int cc; - - - name.sin_family = AF_INET; - name.sin_addr.s_addr = htonl(INADDR_ANY); - name.sin_port = htons(NetworkController::port); - - if (bind( sfd, (struct sockaddr *) &name, sizeof(name) ) < 0) + //fprintf(stderr," NetworkReceiver::QuerySetup... "); + for (int ii=0; ii < 4; ++ii) { - perror("Server::Server - Error binding socket"); - close(sfd); sfd = -1; return; - } - - if (listen(sfd,1) < 0) - { - perror("Server::Server - Error listening on socket"); - close(sfd); sfd = -1; return; - } - int psd = accept(sfd, 0, 0); - close(sfd); - sfd = psd; - if (sfd < 0) - { - perror("Server::Server - Error accepting connection"); - close(sfd); sfd = -1; return; - } - - - for(;;) - { - cc=recv(sfd,buf,sizeof(buf), 0) ; - if (cc == 0) exit (0); - buf[cc] = '\0'; - printf("message received: %s\n", buf); + assert(network->GetMessage(setup[ii], 20)); } + //fprintf(stderr,"Done!\n"); + return MovementResult::OK; } - -Client::Client(const Piece::Colour & newColour, const char * newName, const char * address) : NetworkController(newColour, newName) +MovementResult NetworkSender::QueryMove(string & buffer) { - struct sockaddr_in server; - struct hostent *hp; - - - server.sin_family = AF_INET; - hp = gethostbyname("127.0.0.1"); - bcopy ( hp->h_addr, &(server.sin_addr.s_addr), hp->h_length); - server.sin_port = htons(NetworkController::port); - - if (connect(sfd, (struct sockaddr *) &server, sizeof(server)) < 0) - { - perror("Client::Client - Error connecting to server at address %s"); - close(sfd); sfd = -1; - return; - } - - for (;;) { - send(sfd, "HI", 2,0 ); - sleep(2); - } - + MovementResult result = controller->QueryMove(buffer); + network->SendMessage("%s", buffer.c_str()); + return result; } -//EOF - +MovementResult NetworkReceiver::QueryMove(string & buffer) +{ + assert(network->GetMessage(buffer, 20)); + return MovementResult::OK; +} diff --git a/judge/manager/network_controller.h b/judge/manager/network_controller.h index 7b9af300f35910f7d0dcf3a8e6c7ca23f68dd3e1..31b0c92b06e69ac292daeb566abca14a4427d95a 100644 --- a/judge/manager/network_controller.h +++ b/judge/manager/network_controller.h @@ -1,51 +1,57 @@ -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <netdb.h> -#include <fcntl.h> -#include <errno.h> - - #include "controller.h" +#include "ai_controller.h" +#include "human_controller.h" +#include "network.h" #ifndef NETWORK_CONTROLLER_H #define NETWORK_CONTROLLER_H - class NetworkController : public Controller { public: - NetworkController(const Piece::Colour & newColour, const char * newName = "no-name"); - virtual ~NetworkController(); + NetworkController(const Piece::Colour & colour, Network * newNetwork) : Controller(colour), network(newNetwork) {} + virtual ~NetworkController() {} - virtual bool Valid() {return sfd != -1;} - - virtual void Message(const char * string); - virtual MovementResult QuerySetup(const char * opponentName, std::string setup[]) {fprintf(stderr, "NetworkController unimplemented!\n"); assert(false);} - virtual MovementResult QueryMove(std::string & buffer) {fprintf(stderr, "NetworkController unimplemented!\n"); assert(false);} + //virtual void Message(const char * message) = 0; + virtual bool Valid() const {return network->Valid();} protected: - int sfd; int cfd; - static const int port = 4950; + Network * network; }; -class Server : public NetworkController +class NetworkSender : public NetworkController { public: - Server(const Piece::Colour & newColour, const char * newName = "no-name"); - virtual ~Server() {} + NetworkSender(const Piece::Colour & colour, Controller * newController, Network * newNetwork) : NetworkController(colour, newNetwork), controller(newController) {} + virtual ~NetworkSender() {delete controller;} + + virtual bool Valid() const {return NetworkController::Valid() && controller->Valid();} + + virtual void Message(const char * message) + { + //fprintf(stderr,"NetworkSender sending message %s to underlying controller\n", message); + controller->Message(message); + } + + virtual MovementResult QuerySetup(const char * opponentName, std::string setup[]); + virtual MovementResult QueryMove(std::string & buffer); + + private: + Controller * controller; + }; -class Client : public NetworkController +class NetworkReceiver : public NetworkController { public: - Client(const Piece::Colour & newColour, const char * newName = "no-name", const char * server="127.0.0.1"); - virtual ~Client() {} + NetworkReceiver(const Piece::Colour & colour, Network * newNetwork) : NetworkController(colour, newNetwork) {} + virtual ~NetworkReceiver() {} + + virtual void Message(const char * message) {} //Do nothing (Counter intuitive much) + virtual MovementResult QuerySetup(const char * opponentName, std::string setup[]); + virtual MovementResult QueryMove(std::string & buffer); + + }; #endif //NETWORK_CONTROLLER_H