#LIBRARIES = -lSDL -lGL -lpthread
#Use this to build without graphics
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 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 thread_util.o stratego.o graphics.o game.o
BIN = stratego
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, 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)
{
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);
+
+ if (client)
+ {
+ red = new Client(Piece::RED, "server", redPath); //TODO: Retrieve server address
+ }
else
- red = new AI_Controller(Piece::RED, redPath, timeoutTime);
+ {
+ 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 (strcmp(bluePath, "human") == 0)
- blue = new Human_Controller(Piece::BLUE, graphicsEnabled);
+ if (server)
+ {
+ blue = new Server(Piece::BLUE, "client");
+ }
else
- blue = new AI_Controller(Piece::BLUE, bluePath, timeoutTime);
+ {
+ assert(bluePath != NULL);
+ if (strcmp(bluePath, "human") == 0)
+ blue = new Human_Controller(Piece::BLUE, graphicsEnabled);
+ else
+ blue = new AI_Controller(Piece::BLUE, bluePath, timeoutTime);
+ }
}
#include "stratego.h"
#include "ai_controller.h"
#include "human_controller.h"
+#include "network_controller.h"
#include <cstring>
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);
+ 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 * 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();
{
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] == '-')
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]);
if (inputFile == NULL)
{
- if (red == NULL || blue == NULL) //Not enough arguments
+ if (server)
+ {
+ 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
{
fprintf(stderr, "ARGUMENT_ERROR - Did not recieve enough players (did you mean to use the -f switch?)\n");
exit(EXIT_FAILURE);
}
- Game::theGame = new Game(red,blue, graphics, stallTime, allowIllegal,log, reveal,maxTurns, printBoard, timeoutTime);
+
+ if (client)
+ {
+ blue = red; red = NULL;
+ }
+
+ Game::theGame = new Game(red,blue, graphics, stallTime, allowIllegal,log, reveal,maxTurns, printBoard, timeoutTime, server, client);
}
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);
}
--- /dev/null
+#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, tcp->p_proto);
+ if (sfd == -1)
+ {
+ fprintf(stderr, "NetworkController::NetworkController - couldn't create a TCP socket!");
+ return;
+ }
+}
+
+NetworkController::~NetworkController()
+{
+ if (Valid())
+ {
+ if (shutdown(sfd, SHUT_RDWR) == -1)
+ {
+ fprintf(stderr, "NetworkController::~NetworkController - Can't shutdown socket %d!", sfd);
+ close(sfd);
+ sfd = -1;
+ }
+ }
+ close(sfd);
+}
+
+Server::Server(const Piece::Colour & newColour, const char * newName) : NetworkController(newColour, newName)
+{
+ struct sockaddr_in ipa;
+ ipa.sin_family = AF_INET;
+ ipa.sin_port = htons(NetworkController::port);
+ ipa.sin_addr.s_addr = INADDR_ANY;
+ memset(&ipa,0, sizeof ipa);
+
+ if (bind(sfd, (struct sockaddr*)&sfd, sizeof sfd) == -1)
+ {
+ fprintf(stderr, "Server::Server - Couldn't bind to socket! Abort\n");
+ close(sfd);
+ sfd = -1;
+ return;
+ }
+
+ //Listen for at most 1 connection
+ if (listen(sfd, 1) == -1)
+ {
+ fprintf(stderr, "Server::Server - listening failed.\n");
+ close(sfd);
+ sfd = -1;
+ return;
+ }
+
+ //Accept the connection
+ sfd = accept(sfd, NULL, NULL);
+ if (sfd < 0)
+ {
+ fprintf(stderr, "Server::Server - couldn't accept connection.\n");
+ close(sfd);
+ sfd = -1;
+ return;
+ }
+
+ //We are now ready to play!
+}
+
+
+Client::Client(const Piece::Colour & newColour, const char * newName, const char * server) : NetworkController(newColour, newName)
+{
+ struct sockaddr_in ipa;
+ ipa.sin_family = AF_INET;
+ ipa.sin_port = htons(NetworkController::port);
+ int Res = inet_pton(AF_INET, server, &ipa.sin_addr);
+
+ if (Res < 0)
+ {
+ fprintf(stderr, "Client::Client - First parameter is not a valid address family!\n");
+ close(sfd);
+ sfd = -1;
+ return;
+ }
+ else if (Res == 0)
+ {
+ fprintf(stderr, "Client::Client - Second parameter does not contain a valid IP Address!\n");
+ close(sfd);
+ sfd = -1;
+ return;
+ }
+
+ if (connect(sfd, (struct sockaddr*)&sfd, sizeof sfd) == -1)
+ {
+ fprintf(stderr, "Client::Client - Connection to server at \"%s\" failed.\n", server);
+ close(sfd);
+ sfd = -1;
+ return;
+ }
+
+ //We are now ready to play!
+}
+//EOF
+
+
--- /dev/null
+#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 "controller.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();
+
+ virtual bool Valid() {return sfd != -1;}
+
+ virtual void Message(const char * string) {fprintf(stderr, "NetworkController unimplemented!\n"); assert(false);}
+ 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);}
+
+ protected:
+ int sfd; int cfd;
+ static const int port = 666;
+};
+
+class Server : public NetworkController
+{
+ public:
+ Server(const Piece::Colour & newColour, const char * newName = "no-name");
+ virtual ~Server() {}
+};
+
+class Client : public NetworkController
+{
+ public:
+ Client(const Piece::Colour & newColour, const char * newName = "no-name", const char * server="127.0.0.1");
+ virtual ~Client() {}
+};
+
+#endif //NETWORK_CONTROLLER_H
+
+//EOF