Huge refactor, pulling server and local out into their own binaries

This commit is contained in:
mdiluzio 2015-01-10 16:55:30 +00:00
parent 1b2010faba
commit 0ead12c7dd
16 changed files with 165 additions and 247 deletions

View file

@ -4,44 +4,20 @@ project( ttrts-client )
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
../system
../ttrts
)
# Add the sources
set( SOURCES
main.cpp
client.cpp
server.cpp
net.cpp
filesystem.cpp
)
# Set defaults for ttrts variables
set( TTRTS_MAPS "/usr/local/share/ttrts/maps/" )
set( TTRTS_GAMES "/tmp/" )
set( TTRTS_PORT 11715 )
# define these defaults in code
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DTTRTS_MAPS=${TTRTS_MAPS}" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DTTRTS_GAMES=${TTRTS_GAMES}" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DTTRTS_PORT=${TTRTS_PORT}" )
# Add the executable
add_executable( ${PROJECT_NAME} ${SOURCES} )
# Set our output name to ttrts
set_target_properties( ${PROJECT_NAME} PROPERTIES OUTPUT_NAME ttrts )
# dependent on main ttrts libary
target_link_libraries( ${PROJECT_NAME} ttrts pthread )
target_link_libraries( ${PROJECT_NAME} ttrts ttrts-system )
# Installation target
install( TARGETS ${PROJECT_NAME} DESTINATION bin )
# Run the gen_usage script to generate our usage header
add_custom_target(
ttrts-client-usage
cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_SOURCE_DIR}/scripts/gen_usage.sh "${CMAKE_CURRENT_BINARY_DIR}/usage.h"
)
add_dependencies(${PROJECT_NAME} ttrts-client-usage)

View file

@ -1,98 +0,0 @@
# NAME
ttrts - Tiny Terminal RTS
# SYNOPSIS
ttrts MAPFILE
# DESCRIPTION
ttrts is a tiny terminal based RTS that uses text files as order lists to control the units
This means that any user, program or cat that can read and write to text files can play the game
# RETURN VALUE
ttrts will return -1 on error, or the winning player on completion
# OPTIONS
MAPFILE - File to read in the initial game state. Local or in ${TTRTS_MAPS}
# USAGE
When invoked, ttrts will set up the game in a directory within ${TTRTS_GAMES} by the name of the map
The files in this directory can be read and interpreted by human, robot or cat
ttrts will then await order files from each participant
Once all order files have been received ttrts will calculate the turn and output a new gamestate file
This process repeats until the game is over
# ENVIRONMENT
${TTRTS_MAPS} - Map file lookup location, defaults to `/usr/share/ttrts/maps/`
${TTRTS_GAMES} - Game directory for I/O, defaults to `/tmp/`
-----------------------------------------------------------
# FILES
`/usr/share/ttrts/maps/` holds a sample set of maps
## Gamestate File
Turn_{TURNNUMBER}.txt
### Contents
===== ttrts v{MAJOR}.{MINOR}.{PATCH} =====
NAME:{GAMENAME}
SIZE:[{X},{Y}]
TURN:{TURNNUMBER}
WALL:[{X},{Y}][{X},{Y}][{X},{Y}]...{repeat for all walls}
~~~~
UNIT:{ID} pl:{PLAYER} vs:{VIS} dr:{DIR(NESW)} ps:[{X},{Y}]
... {continue for all units}
END
## Order File
Player_{PLAYER_ID}_Turn_{TURN_NUMBER}.txt
### Contents
ORDER:{ORDER_CHAR} id:{UNIT_ID}
... {continue for all orders}
END
-----------------------------------------------------------
# GAMEPLAY
The game takes place in a series of simultaneous turns on an arbitrarily sized 2D board
Each turn, the client outputs a gamestate file and waits for an order file from each player
All commands are evaluated simultaneously with friendly fire enabled by default
The game is over when any of three conditions are met -
* All remaining units are controlled by a single player
* No units are left (draw)
* All units left are unable to move (draw)
# UNITS
Each unit occupies a single tile on the board, facing in a compass direction (NESW)
Units will only accept orders from their owner
Units can receive only a single order each turn
Units cannot occupy the same tile as other units/walls
# ORDERS
### F - Move unit [F]orward one space, leaving a wall
This wall will remain until the end of the game, blocking movement to that tile
Movement orders have no effect if impossible, eg.
* Attempting to move outside of map
* Attempting to move on to tile occupied by unit/wall
### L/R - Rotate unit [L]eft or [R]ight
Unit will rotate clockwise or counter-clockwise, this order cannot fail
### A - [A]ttack in straight line in front of unit
Attack will continue forward until unit can't progress, all units within the path of the attack are destroyed.

View file

@ -1,17 +1,15 @@
#include "client.h"
#include <iostream>
#include "net.h"
#include "game.h"
#include "error.h"
#include "filesystem.h"
int runClient(int argc, char* argv[])
int main(int argc, char* argv[])
{
// must provide information
if (argc < 2)
fatal_error("Usage: ttrts client HOST");
fatal_error("Usage: ttrts-client HOST");
std::string hostname = argv[1];

View file

@ -1,6 +0,0 @@
#ifndef _TTRTS_CLIENT_H_
#define _TTRTS_CLIENT_H_
int runClient(int argc, char* argv[]);
#endif

View file

@ -1,34 +0,0 @@
#include "game.h"
#include "filesystem.h"
#include "server.h"
#include "client.h"
#include <iostream>
static const char* sk_usage =
#include "usage.h"
;
// Main program entry point
int main(int argc, char* argv[])
{
// If no args, print usage
if ( argc == 1 )
{
std::cout<<sk_usage<<std::endl;
return -1;
}
// Attempt to open the game file
std::string arg1 = argv[1];
// Either run the client, the server, or from local filesystem
if( arg1 == "client" )
return runClient(argc-1,argv+1);
else if ( arg1 == "server" )
return runServer(argc-1,argv+1);
else
return runFromFilesystem(argc,argv);
};

View file

@ -1,6 +0,0 @@
#ifndef _TTRTS_SERVER_H_
#define _TTRTS_SERVER_H_
int runServer(int argc, char* argv[]);
#endif

View file

@ -0,0 +1,23 @@
# ====================== ttrts =======================
# Project name
project( ttrts-local )
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
../system
../ttrts
)
# Add the sources
set( SOURCES
local.cpp
)
# Add the executable
add_executable( ${PROJECT_NAME} ${SOURCES} )
# dependent on main ttrts libary
target_link_libraries( ${PROJECT_NAME} ttrts ttrts-system pthread )
# Installation target
install( TARGETS ${PROJECT_NAME} DESTINATION bin )

62
source/local/local.cpp Normal file
View file

@ -0,0 +1,62 @@
#include "game.h"
#include "filesystem.h"
#include "error.h"
#include "net.h"
#include <iostream>
// =====================================================================================================================
int main(int argc, char* argv[])
{
// must provide information
if (argc < 2)
fatal_error("Usage: ttrts-local MAPFILE");
std::string gamefile = argv[1];
std::cout<<"TTRTS: Launching with "<<gamefile<<std::endl;
CTTRTSGame game = GetGameFromFile(gamefile);
// Grab the players involved
auto players = game.GetPlayers();
// Default for games
std::string ttrts_games_dir = getGamesDir();
// Empty the current game directory
if ( CreateAndCleanGameDir(game.GetName()) < 0)
return -1;
// While the game isn't finished
while ( ! game.GameOver() )
{
std::cout<<"TTRTS: Starting turn "<<game.GetTurn()<<std::endl;
// Create a turn file
if( !OutputGameStateFile(game))
fatal_error("Error: Failed to output new turn file");
// Wait for order files
for( player_t player : players)
{
// Construct the player order filename
std::string orders = GetOrdersFromPlayerFile(game, player);
// Issue the orders to the game
if( game.IssueOrders(player, orders) )
std::cerr<<"Warning: Orders for player "<<(int) player <<" failed to correctly parse"<<std::endl;
}
// Simulate turn
std::cout<<"TTRTS: Simulating this turn!"<<std::endl;
if ( game.SimulateToNextTurn() )
fatal_error("Failed to simulate game turn");
}
// Output final gamestate
OutputGameStateFile(game);
return OutputGameEnd( game );
}

View file

@ -0,0 +1,23 @@
# ====================== ttrts =======================
# Project name
project( ttrts-server )
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
../system
../ttrts
)
# Add the sources
set( SOURCES
server.cpp
)
# Add the executable
add_executable( ${PROJECT_NAME} ${SOURCES} )
# dependent on main ttrts libary
target_link_libraries( ${PROJECT_NAME} ttrts ttrts-system pthread )
# Installation target
install( TARGETS ${PROJECT_NAME} DESTINATION bin )

View file

@ -1,4 +1,4 @@
#include "server.h"
#include "error.h"
#include <thread>
#include <vector>
@ -80,11 +80,11 @@ void RunServerForGame(CTTRTSGame &game)
SendGamestateToClients(myClients, game, gameMutex);
}
int runServer(int argc, char* argv[])
int main(int argc, char* argv[])
{
// argv[1] needs to be a valid game file
if( argc < 2 )
fatal_error("must provide game file argument");
fatal_error("Usage: ttrts-server MAPFILE");
// Set up game
CTTRTSGame game = GetGameFromFile(argv[1]);

View file

@ -0,0 +1,21 @@
cmake_minimum_required(VERSION 2.8.7)
# Main ttrts library
project( ttrts-system )
# Include the maths
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
../ttrts
)
# Add our sources
set( SOURCES
net.cpp
filesystem.cpp
)
# Add this library
add_library( ${PROJECT_NAME} ${SOURCES} )
target_link_libraries( ${PROJECT_NAME} ttrts pthread )

25
source/system/error.h Normal file
View file

@ -0,0 +1,25 @@
#ifndef _TTRTS_ERROR_H_
#define _TTRTS_ERROR_H_
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
//======================================================================================================================
// Error functions
// For local fatal errors
inline void fatal_error(const char *msg)
{
std::cerr<<msg<<std::endl;
exit(1);
}
// For system fatal errors (ie. functions that set errno)
inline void fatal_perror(const char *msg)
{
perror(msg);
exit(1);
}
#endif

View file

@ -1,5 +1,6 @@
#include "filesystem.h"
#include "net.h"
#include "error.h"
#include <iostream>
@ -245,54 +246,3 @@ int OutputgameEnd(const CTTRTSGame &game) {
return (int)winningPlayer;
}
// =====================================================================================================================
int runFromFilesystem(int argc, char* argv[])
{
std::string gamefile = argv[1];
std::cout<<"TTRTS: Launching with "<<gamefile<<std::endl;
CTTRTSGame game = GetGameFromFile(gamefile);
// Grab the players involved
auto players = game.GetPlayers();
// Default for games
std::string ttrts_games_dir = getGamesDir();
// Empty the current game directory
if ( CreateAndCleanGameDir(game.GetName()) < 0)
return -1;
// While the game isn't finished
while ( ! game.GameOver() )
{
std::cout<<"TTRTS: Starting turn "<<game.GetTurn()<<std::endl;
// Create a turn file
if( !OutputGameStateFile(game))
fatal_error("Error: Failed to output new turn file");
// Wait for order files
for( player_t player : players)
{
// Construct the player order filename
std::string orders = GetOrdersFromPlayerFile(game, player);
// Issue the orders to the game
if( game.IssueOrders(player, orders) )
std::cerr<<"Warning: Orders for player "<<(int) player <<" failed to correctly parse"<<std::endl;
}
// Simulate turn
std::cout<<"TTRTS: Simulating this turn!"<<std::endl;
if ( game.SimulateToNextTurn() )
fatal_error("Failed to simulate game turn");
}
// Output final gamestate
OutputGameStateFile(game);
return OutputGameEnd( game );
}

View file

@ -1,4 +1,5 @@
#include "net.h"
#include "error.h"
#include <netdb.h>

View file

@ -74,23 +74,6 @@ std::string WaitForGamestateMessage(int sockfd);
// Send orders to the server
int SendOrdersToServer(int sockfd, const std::string &orders);
//======================================================================================================================
// Error functions
// For local fatal errors
inline void fatal_error(const char *msg)
{
std::cerr<<msg<<std::endl;
exit(1);
}
// For system fatal errors (ie. functions that set errno)
inline void fatal_perror(const char *msg)
{
perror(msg);
exit(1);
}
//======================================================================================================================
// Other functions
int OutputGameEnd( CTTRTSGame& game );