From 469e3ffa8a775e8a6dd731b99a37582b521be9e4 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Sat, 20 Dec 2014 15:35:19 +0000 Subject: [PATCH 01/95] Add a Random player, simply does random commands on each turn Remove simplePlayer in favor of new randomPlayer, which uses new ttrts.pm module --- ttrts.pm | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 ttrts.pm diff --git a/ttrts.pm b/ttrts.pm new file mode 100644 index 0000000..7e9fdbf --- /dev/null +++ b/ttrts.pm @@ -0,0 +1,179 @@ +#! /usr/bin/perl +use strict; +use warnings; + +# Get information about a unit from it's descriptor +sub getUnit +{ + return ($_[0] =~ /UNIT:(\d+) tm:(\d+) vs:([^ ]+) dr:([^ ]+) ps:\[(\d+),(\d+)\]/); +} + +# Get the units from a turn file +sub GetUnitsForTurn +{ + my $turnFile = shift; + + # Open the turn file + open (my $TURNHANDLE, '<', $turnFile) or die "Could not open '$turnFile' $!"; + + # Skip the header information + my $headerLine = <$TURNHANDLE>; + my $sizeLine = <$TURNHANDLE>; + my $turnLine = <$TURNHANDLE>; + ( <$TURNHANDLE> =~ /~~~~/ ) or die "Gamestate file did not match expected format"; + + my @units; + while( my $unitLine = <$TURNHANDLE> ) + { + chomp $unitLine; + push(@units,$unitLine); + } + + close $TURNHANDLE; + + return @units; +} + +# Get information from the header for this turn +sub GetHeaderForTurn +{ + my $turnFile = shift; + + # Open the turn file + open (my $TURNHANDLE, '<', $turnFile) or die "Could not open '$turnFile' $!"; + + # Pull in the header information + my $headerLine = <$TURNHANDLE>; + chomp $headerLine; + my $sizeLine = <$TURNHANDLE>; + chomp $sizeLine; + my $turnLine = <$TURNHANDLE>; + chomp $turnLine; + + my ($gameName) = ( $headerLine =~ /===== ([^ ]+) =====/ ); + my ($gameX,$gameY) = ( $sizeLine =~ /SIZE:\[(\d+),(\d+)\]/ ); + + ( <$TURNHANDLE> =~ /~~~~/ ) or die "Gamestate file did not match expected format"; + + close $TURNHANDLE; + + return ($gameName,$gameX,$gameY); +} + +# Get units from a specific team +sub getUnitsOnTeam +{ + my $theTeam = shift; + my @allUnits = @_; + my @myUnits; + + for my $unit (@allUnits) + { + my ($unitTeam) = $unit =~ /tm:(\d+)/; + if ( $unitTeam == $theTeam ) + { + push(@myUnits,$unit); + } + } + + return @myUnits; +} + +sub GetTurnFile +{ + my $turn = shift; + my $turnFile = "Turn_TURN.txt"; + $turnFile =~ s/TURN/$turn/; + return $turnFile; +} + +sub GetCommandFile +{ + my $turn = shift; + my $team = shift; + my $cmdFileName = "Turn_TURN_Team_TEAM.txt"; + $cmdFileName =~ s/TURN/$turn/; + $cmdFileName =~ s/TEAM/$team/; + return $cmdFileName; +} + +# Output the commands file +sub OutputCommandsFile +{ + my $turn = shift; + my $team = shift; + my $commands = shift; + + # Get output file + our $cmdFileName = GetCommandFile($turn,$team); + + if (! -e $cmdFileName) + { + open(my $cmdFile, '>', $cmdFileName) or die "Couldn't open '$cmdFileName' $!"; + print $cmdFile $commands; + close $cmdFile; + + printf "Outputted $cmdFileName\n"; + printf "$commands"; + } + else + { + open(my $cmdFile, '<', $cmdFileName) or die "Couldn't open '$cmdFileName' $!"; + my $old_commands = do { <$cmdFile> }; + + printf "Replaying $cmdFileName\n"; + printf "$old_commands"; + } +} + +# Print a game map +sub PrintGameMap +{ + my $gameX = shift; + my $gameY = shift; + my @units = @_; + + my @map; + + # Fill with blanks + for my $x (0 .. $gameX-1) + { + for my $y (0 .. $gameY-1) + { + $map[$x][$y] = "-"; + } + } + + # Fill with units + for my $unit (@units) + { + my ($id,$tm,$vs,$dr,$psx,$psy) = getUnit($unit); + + $tm += 31; + $vs = "\e[".$tm."m".$vs."\e[0m"; + + $map[$psx][$psy] = $vs; + } + + # Print whole map bottom left is 0,0 + for my $y ( reverse 0 .. $gameY-1 ) + { + for my $x (0 .. $gameX-1) + { + printf($map[$x][$y]); + } + printf("\n"); + } +} + +# Wait for a file to exist +sub WaitForFile +{ + my $file = $_[0]; + while( ! -e $file ) + { + select(undef, undef, undef, 0.01); + } +} + +return 1; \ No newline at end of file From b0af969b2968d5330e908ac92699cc8384b2d620 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Sat, 20 Dec 2014 17:17:04 +0000 Subject: [PATCH 02/95] Update to 0.0.1 version system for main ttrts client and check versions --- ttrts.pm | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/ttrts.pm b/ttrts.pm index 7e9fdbf..9479e9c 100644 --- a/ttrts.pm +++ b/ttrts.pm @@ -2,6 +2,9 @@ use strict; use warnings; +our $ttrts_perlai_versioncompat_major = 0; +our $ttrts_perlai_versioncompat_minor = 0; + # Get information about a unit from it's descriptor sub getUnit { @@ -17,16 +20,21 @@ sub GetUnitsForTurn open (my $TURNHANDLE, '<', $turnFile) or die "Could not open '$turnFile' $!"; # Skip the header information - my $headerLine = <$TURNHANDLE>; - my $sizeLine = <$TURNHANDLE>; - my $turnLine = <$TURNHANDLE>; - ( <$TURNHANDLE> =~ /~~~~/ ) or die "Gamestate file did not match expected format"; + my $num = 0; + while( !( <$TURNHANDLE> =~ /~~~~/ ) ) + { + $num++; + $num > 20 and die "gamestate file did not reach ~~~~ line within 10 lines"; + } my @units; while( my $unitLine = <$TURNHANDLE> ) { chomp $unitLine; - push(@units,$unitLine); + if( !($unitLine eq "END") ) + { + push(@units,$unitLine); + } } close $TURNHANDLE; @@ -34,6 +42,19 @@ sub GetUnitsForTurn return @units; } +# Check version numbers against ttrts.pm version +sub checkVersion +{ + my $version_major = shift; + my $version_minor = shift; + if( ($version_major != $ttrts_perlai_versioncompat_major) + or ($version_minor != $ttrts_perlai_versioncompat_minor) ) + { + printf "ttrts.pm version does not match with this ttrts version\n"; + die "ttrts.pm = v$ttrts_perlai_versioncompat_minor.$ttrts_perlai_versioncompat_major ttrts = v$version_major.$version_minor"; + } +} + # Get information from the header for this turn sub GetHeaderForTurn { @@ -45,15 +66,18 @@ sub GetHeaderForTurn # Pull in the header information my $headerLine = <$TURNHANDLE>; chomp $headerLine; + my $nameLine = <$TURNHANDLE>; + chomp $nameLine; my $sizeLine = <$TURNHANDLE>; chomp $sizeLine; my $turnLine = <$TURNHANDLE>; chomp $turnLine; - my ($gameName) = ( $headerLine =~ /===== ([^ ]+) =====/ ); - my ($gameX,$gameY) = ( $sizeLine =~ /SIZE:\[(\d+),(\d+)\]/ ); + my ($version_major,$version_minor) = ( $headerLine =~ /==== ttrts v(\d+)\.(\d+)\.\d+ ====/ ); + checkVersion $version_major,$version_minor; - ( <$TURNHANDLE> =~ /~~~~/ ) or die "Gamestate file did not match expected format"; + my ($gameName) = ( $nameLine =~ /NAME:(.+)/ ); + my ($gameX,$gameY) = ( $sizeLine =~ /SIZE:\[(\d+),(\d+)\]/ ); close $TURNHANDLE; @@ -111,6 +135,7 @@ sub OutputCommandsFile { open(my $cmdFile, '>', $cmdFileName) or die "Couldn't open '$cmdFileName' $!"; print $cmdFile $commands; + print $cmdFile "END"; close $cmdFile; printf "Outputted $cmdFileName\n"; From 19623c67119cc90cc2156430a0feb85b162b12f9 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Sat, 20 Dec 2014 17:33:36 +0000 Subject: [PATCH 03/95] Update version to match with compatible ttrts version --- ttrts.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ttrts.pm b/ttrts.pm index 9479e9c..eb588ba 100644 --- a/ttrts.pm +++ b/ttrts.pm @@ -3,7 +3,7 @@ use strict; use warnings; our $ttrts_perlai_versioncompat_major = 0; -our $ttrts_perlai_versioncompat_minor = 0; +our $ttrts_perlai_versioncompat_minor = 1; # Get information about a unit from it's descriptor sub getUnit From f68d16b8b943143134e1f44eae0b3229bcbe43e0 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Sat, 20 Dec 2014 17:37:49 +0000 Subject: [PATCH 04/95] Add link to my ttrts-players repository to README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index be67d0d..ce9a37d 100644 --- a/README.md +++ b/README.md @@ -25,3 +25,5 @@ TTRTS was is from the ground up designed to be a fun way to practice programming ## Further Information See [the ttrts binary readme](source/ttrts/README.md) for full usage and game rules + +See [my ttrts-players repository](https://github.com/mdiluz/ttrts-players) for examples of players From 321690faaa2577ff4cde5dea2d3afcc638392e22 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Sat, 20 Dec 2014 17:47:10 +0000 Subject: [PATCH 05/95] Add link to issue #9 to readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ce9a37d..279f0d7 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ TTRTS was is from the ground up designed to be a fun way to practice programming #### Requirements * cmake - our build system uses cmake -* Linux/OSX - currently no support for Windows +* Linux/OSX - currently no support for Windows, tracked with [Issue #9](https://github.com/mdiluz/ttrts/issues/9) #### To Build $ git clone https://github.com/mdiluz/ttrts.git From 24c8b6a5b89c07d3c75d9658df19615ca09bc1b2 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Sat, 20 Dec 2014 21:45:44 +0000 Subject: [PATCH 06/95] Fix a some bad grammar --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 279f0d7..1771eae 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ ## Introduction A simple terminal based RTS game that uses text files to communicate game state and unit commands. -TTRTS was is from the ground up designed to be a fun way to practice programming. Any programming language than can handle file I/O can be used to make an AI for TTRTS, and this extensibility allows for any type of programmer to have fun and enjoy designing and playing against their friends. +TTRTS is from the ground up designed to be a fun way to practice programming. Any programming language than can handle file I/O can be used to make an AI for TTRTS, and this extensibility allows for any type of programmer to enjoy designing and playing against their friends. ----------------------------------------------------------- ## Building TTRTS From 9551560bc00094398bfd26b7c2071281e3db286c Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Sun, 21 Dec 2014 10:31:00 +0000 Subject: [PATCH 07/95] OrderUnitPair -> SOrderUnitPair --- source/game/game.cpp | 40 ++++++++++++++++++++-------------------- source/game/game.h | 12 ++++++------ 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/source/game/game.cpp b/source/game/game.cpp index 9b9ab6b..3bede2a 100644 --- a/source/game/game.cpp +++ b/source/game/game.cpp @@ -78,7 +78,7 @@ int CTTRTSGame::IssueOrder( Team team, const COrder& order ) return 1; // Get the right unit for the order - for ( OrderUnitPair& pair : m_OrderUnitPairs ) + for ( SOrderUnitPair & pair : m_OrderUnitPairs ) { if ( pair.unit.getID() == order.unit ) { @@ -106,7 +106,7 @@ int CTTRTSGame::VerifyPos(uvector2 vec) const // Get a units new position -uvector2 CTTRTSGame::GetNewPosition( const OrderUnitPair& pair ) const +uvector2 CTTRTSGame::GetNewPosition( const SOrderUnitPair & pair ) const { // Grab the order switch ( pair.order.command) @@ -127,7 +127,7 @@ int CTTRTSGame::SimulateToNextTurn() int error = 0; // Attempt all movement orders - for ( OrderUnitPair& pair : m_OrderUnitPairs ) + for ( SOrderUnitPair & pair : m_OrderUnitPairs ) { switch ( pair.order.command) { @@ -142,7 +142,7 @@ int CTTRTSGame::SimulateToNextTurn() if ( possible ) { // If any unit is in this spot, or moving unit moving to said spot, reject this - for ( const OrderUnitPair& pair2 : m_OrderUnitPairs ) + for ( const SOrderUnitPair & pair2 : m_OrderUnitPairs ) { // Skip myself if( pair.unit.getID() == pair2.unit.getID() ) continue; @@ -168,7 +168,7 @@ int CTTRTSGame::SimulateToNextTurn() } // Turn all units that need turning - for ( OrderUnitPair& pair : m_OrderUnitPairs ) + for ( SOrderUnitPair & pair : m_OrderUnitPairs ) { switch ( pair.order.command) { @@ -196,7 +196,7 @@ int CTTRTSGame::SimulateToNextTurn() // Assume no more charging charging = false; // Initially move all units - for ( OrderUnitPair& pair : m_OrderUnitPairs ) + for ( SOrderUnitPair & pair : m_OrderUnitPairs ) { if ( pair.order.command == command_c::A ) { @@ -215,9 +215,9 @@ int CTTRTSGame::SimulateToNextTurn() std::vector< unit_id_t > toKill; // Vector to store which units to kill // Initially move all units to check for pass through - for ( OrderUnitPair& pair1 : m_OrderUnitPairs ) + for ( SOrderUnitPair & pair1 : m_OrderUnitPairs ) if ( pair1.order.command == command_c::A ) - for ( OrderUnitPair& pair2 : m_OrderUnitPairs ) + for ( SOrderUnitPair & pair2 : m_OrderUnitPairs ) if ( pair1.unit.getID() != pair2.unit.getID() // Don't check the same units && pair2.order.command == command_c::A ) { @@ -233,8 +233,8 @@ int CTTRTSGame::SimulateToNextTurn() toKill.clear(); // Check for all matching spots - for ( OrderUnitPair& pair1 : m_OrderUnitPairs ) - for ( OrderUnitPair& pair2 : m_OrderUnitPairs ) + for ( SOrderUnitPair & pair1 : m_OrderUnitPairs ) + for ( SOrderUnitPair & pair2 : m_OrderUnitPairs ) { if( pair1.unit.getID() == pair2.unit.getID() ) continue; // Don't check the same units @@ -258,7 +258,7 @@ int CTTRTSGame::SimulateToNextTurn() } // Clear all orders - for ( OrderUnitPair& pair : m_OrderUnitPairs ) + for ( SOrderUnitPair & pair : m_OrderUnitPairs ) pair.order = COrder(); // Increment the current turn @@ -336,14 +336,14 @@ int CTTRTSGame::AddUnit( CUnit&& unit ) return 2; // If any unit's position matches, reject this - for ( const OrderUnitPair& pair: m_OrderUnitPairs ) + for ( const SOrderUnitPair & pair: m_OrderUnitPairs ) { if( pair.unit.getPos() == unit.getPos() ) return 3; } // Add the unit with a blank order - m_OrderUnitPairs.push_back( OrderUnitPair(std::move(unit), COrder()) ); + m_OrderUnitPairs.push_back( SOrderUnitPair(std::move(unit), COrder()) ); return 0; @@ -374,7 +374,7 @@ int CTTRTSGame::VerifyOrder( Team team, const COrder& order ) const const unit_id_t unitID = order.unit; // Attempt to find the unit - for ( const OrderUnitPair& pair : m_OrderUnitPairs ) + for ( const SOrderUnitPair & pair : m_OrderUnitPairs ) { // Accept if we have the unit if ( pair.unit.getID() == unitID @@ -392,7 +392,7 @@ int CTTRTSGame::VerifyOrder( Team team, const COrder& order ) const // Get unit by unit ID const CUnit& CTTRTSGame::GetUnitByIDConst( unit_id_t id ) const { - for ( const OrderUnitPair& pair : m_OrderUnitPairs ) + for ( const SOrderUnitPair & pair : m_OrderUnitPairs ) { // Attempt the unit add if ( pair.unit.getID() == id ) @@ -407,7 +407,7 @@ const CUnit& CTTRTSGame::GetUnitByIDConst( unit_id_t id ) const // Get an order by unit ID const COrder& CTTRTSGame::GetOrderByIDConst( unit_id_t id ) const { - for ( const OrderUnitPair& pair : m_OrderUnitPairs ) + for ( const SOrderUnitPair & pair : m_OrderUnitPairs ) { // Attempt the unit add if ( pair.unit.getID() == id ) @@ -422,7 +422,7 @@ const COrder& CTTRTSGame::GetOrderByIDConst( unit_id_t id ) const // Get unit by unit ID CUnit& CTTRTSGame::GetUnitByID( unit_id_t id ) { - for ( OrderUnitPair& pair : m_OrderUnitPairs ) + for ( SOrderUnitPair & pair : m_OrderUnitPairs ) { // Attempt the unit add if ( pair.unit.getID() == id ) @@ -441,7 +441,7 @@ std::vector CTTRTSGame::GetTeams() const teams.reserve(GetNumUnits()); // Grab all teams - for ( const OrderUnitPair& pair : m_OrderUnitPairs ) + for ( const SOrderUnitPair & pair : m_OrderUnitPairs ) { teams.push_back(pair.unit.getTeam()); } @@ -461,7 +461,7 @@ Team CTTRTSGame::CheckForWin() const memset(units,0,sizeof(units)); // Count up all the units for each Team - for ( const OrderUnitPair& pair : m_OrderUnitPairs ) + for ( const SOrderUnitPair & pair : m_OrderUnitPairs ) { const int team = (int)pair.unit.getTeam(); units[team] += 1; @@ -499,7 +499,7 @@ std::string CTTRTSGame::GetStateAsString() const // Gather unit information std::string units; - for ( const OrderUnitPair& pair : m_OrderUnitPairs ) + for ( const SOrderUnitPair & pair : m_OrderUnitPairs ) { units += CUnit::GetStringFromUnit(pair.unit); units += '\n'; diff --git a/source/game/game.h b/source/game/game.h index 4662776..7272ffd 100644 --- a/source/game/game.h +++ b/source/game/game.h @@ -9,22 +9,22 @@ #define GAME_HEADER_DELIMITER "~~~~\n" // Type for order and unit pairs -struct OrderUnitPair +struct SOrderUnitPair { // Straight up move constructor - OrderUnitPair( OrderUnitPair&& other ) + SOrderUnitPair( SOrderUnitPair && other ) : unit ( std::move(other.unit) ) , order ( other.order ) {} // Multi parameter constructor - OrderUnitPair( CUnit&& u, COrder o ) + SOrderUnitPair( CUnit&& u, COrder o ) : unit ( std::move(u) ) , order ( o ) {} // Move assignment operator - inline OrderUnitPair& operator=( OrderUnitPair&& rhs ) + inline SOrderUnitPair & operator=( SOrderUnitPair && rhs ) { this->unit = std::move(rhs.unit); this->order = std::move(rhs.order); @@ -36,7 +36,7 @@ struct OrderUnitPair }; // Typedef for a vector of these unit pairs -typedef std::vector< OrderUnitPair > OrderUnitPairVector; +typedef std::vector OrderUnitPairVector; // Full TTRTS Game class // Stores information about the game @@ -109,7 +109,7 @@ private: int VerifyPos( uvector2 vec ) const; // Get a units new position after an order - uvector2 GetNewPosition( const OrderUnitPair& pair ) const; + uvector2 GetNewPosition( const SOrderUnitPair & pair ) const; // Check for a pass through static bool CheckForPassThrough( const CUnit& one, const CUnit& two ); From ca1705ad4ab5ad69f1e3344fc26b8a83c4ee1222 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Sun, 21 Dec 2014 10:33:19 +0000 Subject: [PATCH 08/95] Pull SOrderUnitPair out of game header --- source/game/game.h | 31 +---------------------------- source/game/orderunitpair.h | 39 +++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 30 deletions(-) create mode 100644 source/game/orderunitpair.h diff --git a/source/game/game.h b/source/game/game.h index 7272ffd..e260d89 100644 --- a/source/game/game.h +++ b/source/game/game.h @@ -4,40 +4,11 @@ #include "unit.h" #include "gametypes.h" #include "order.h" +#include "orderunitpair.h" #define GAME_HEADER_FORMATTER "NAME:%s\nSIZE:[%u,%u]\nTURN:%u" #define GAME_HEADER_DELIMITER "~~~~\n" -// Type for order and unit pairs -struct SOrderUnitPair -{ - // Straight up move constructor - SOrderUnitPair( SOrderUnitPair && other ) - : unit ( std::move(other.unit) ) - , order ( other.order ) - {} - - // Multi parameter constructor - SOrderUnitPair( CUnit&& u, COrder o ) - : unit ( std::move(u) ) - , order ( o ) - {} - - // Move assignment operator - inline SOrderUnitPair & operator=( SOrderUnitPair && rhs ) - { - this->unit = std::move(rhs.unit); - this->order = std::move(rhs.order); - return *this; - } - - CUnit unit; // The unit - COrder order; // Order for this unit from this turn -}; - -// Typedef for a vector of these unit pairs -typedef std::vector OrderUnitPairVector; - // Full TTRTS Game class // Stores information about the game // Can convert from a string or to a string diff --git a/source/game/orderunitpair.h b/source/game/orderunitpair.h new file mode 100644 index 0000000..759f165 --- /dev/null +++ b/source/game/orderunitpair.h @@ -0,0 +1,39 @@ +#ifndef _TTRTS_ORDERUNITPAIR_H_ +#define _TTRTS_ORDERUNITPAIR_H_ + +#include "order.h" +#include "unit.h" + +#include + +// Type for order and unit pairs +struct SOrderUnitPair +{ + // Straight up move constructor + SOrderUnitPair( SOrderUnitPair && other ) + : unit ( std::move(other.unit) ) + , order ( other.order ) + {} + + // Multi parameter constructor + SOrderUnitPair( CUnit&& u, COrder o ) + : unit ( std::move(u) ) + , order ( o ) + {} + + // Move assignment operator + inline SOrderUnitPair & operator=( SOrderUnitPair && rhs ) + { + this->unit = std::move(rhs.unit); + this->order = std::move(rhs.order); + return *this; + } + + CUnit unit; // The unit + COrder order; // Order for this unit from this turn +}; + +// Typedef for a vector of these unit pairs +typedef std::vector OrderUnitPairVector; + +#endif // _TTRTS_ORDERUNITPAIR_H_ \ No newline at end of file From 755fe01bf52e295144ab6ddcf4737ad1f83022a0 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Sun, 21 Dec 2014 10:37:35 +0000 Subject: [PATCH 09/95] re-align CTRTSGame class --- source/game/game.h | 66 +++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/source/game/game.h b/source/game/game.h index e260d89..636b084 100644 --- a/source/game/game.h +++ b/source/game/game.h @@ -17,84 +17,84 @@ class CTTRTSGame public: // Get the game information as a string - static CTTRTSGame CreateFromString( const std::string& input ); + static CTTRTSGame CreateFromString( const std::string& input ); // Constructors CTTRTSGame( ucoord_t c, ucoord_t r ); CTTRTSGame(CTTRTSGame&& game); // move asignment operator - CTTRTSGame& operator=(CTTRTSGame&& game); + CTTRTSGame& operator=(CTTRTSGame&& game); // Simulate and progress to the next turn // Returns non-zero if simulation failed - int SimulateToNextTurn(); + int SimulateToNextTurn(); // Check for a win, returns invalid for no win state reached // Note: this function will return invalid a draw was reached // best practice would be to call with GetNumUnits() == 0 - Team CheckForWin() const; + Team CheckForWin() const; // Get the game information as a string - std::string GetStateAsString() const; + std::string GetStateAsString() const; // Issue orders to the game, returns non-zero if orders are incorrect - int IssueOrders( Team team, const std::string& orders ); - int IssueOrders( Team team, const COrderVector& orders ); - int IssueOrder( Team team, const COrder& order ); + int IssueOrders( Team team, const std::string& orders ); + int IssueOrders( Team team, const COrderVector& orders ); + int IssueOrder( Team team, const COrder& order ); // Add a units to the game, nonzero return value indicates error - int AddUnit( CUnit&& unit ); - int AddUnits( CUnitVector&& units ); + int AddUnit( CUnit&& unit ); + int AddUnits( CUnitVector&& units ); // Get the number of units - inline unsigned int GetNumUnits() const { return m_OrderUnitPairs.size(); } + inline unsigned int GetNumUnits() const { return m_OrderUnitPairs.size(); } // Get unit and orderby index as above (not unit ID) - inline const CUnit& GetUnitByIndex( unsigned int i ) const { return m_OrderUnitPairs[i].unit; } - inline const COrder& GetOrdersByIndex( unsigned int i ) const { return m_OrderUnitPairs[i].order; } + inline const CUnit& GetUnitByIndex( unsigned int i ) const { return m_OrderUnitPairs[i].unit; } + inline const COrder& GetOrdersByIndex( unsigned int i ) const { return m_OrderUnitPairs[i].order; } // Get a unit by it's ID - const CUnit& GetUnitByIDConst( unit_id_t id ) const; - const COrder& GetOrderByIDConst( unit_id_t id ) const; + const CUnit& GetUnitByIDConst( unit_id_t id ) const; + const COrder& GetOrderByIDConst( unit_id_t id ) const; // Get dimensions - inline const uvector2 &GetDimensions() const { return dimensions; } + inline const uvector2& GetDimensions() const { return dimensions; } // Set the game name // NOTE: Names with spaces not allowed - inline std::string SetName( const std::string& in ) { return (name = in); } - inline std::string GetName() const { return name; } + inline std::string SetName( const std::string& in ) { return (name = in); } + inline std::string GetName() const { return name; } // Set the turn of the game - inline int SetTurn( int in ) { return (turn = in); } - inline int GetTurn() const { return turn; } + inline int SetTurn( int in ) { return (turn = in); } + inline int GetTurn() const { return turn; } // Get a vector of the teams in the current game - std::vector GetTeams() const; + std::vector GetTeams() const; private: + // Check for a pass through + static bool CheckForPassThrough( const CUnit& one, const CUnit& two ); + // Verify any order or position - non-zero is error - int VerifyOrder( Team team, const COrder& order ) const; - int VerifyPos( uvector2 vec ) const; + int VerifyOrder( Team team, const COrder& order ) const; + int VerifyPos( uvector2 vec ) const; // Get a units new position after an order - uvector2 GetNewPosition( const SOrderUnitPair & pair ) const; - - // Check for a pass through - static bool CheckForPassThrough( const CUnit& one, const CUnit& two ); + uvector2 GetNewPosition( const SOrderUnitPair & pair ) const; // Kill all units in list - void KillAll( std::vector< unit_id_t >& vec ); + void KillAll( std::vector< unit_id_t >& vec ); // Get unit by unit ID - CUnit& GetUnitByID( unit_id_t id ); + CUnit& GetUnitByID( unit_id_t id ); - std::string name; // Game Name - unsigned int turn; // Int to store the current turn - uvector2 dimensions; // Dimensions of the game - OrderUnitPairVector m_OrderUnitPairs; // Vector to store all units and orders + std::string name; // Game Name + unsigned int turn; // Int to store the current turn + uvector2 dimensions; // Dimensions of the game + OrderUnitPairVector m_OrderUnitPairs; // Vector to store all units and orders }; From f63dc8462f92fb6cac6ce7d348b65053598b6d26 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Sun, 21 Dec 2014 10:39:39 +0000 Subject: [PATCH 10/95] COrder -> SOrder --- source/game/game.cpp | 14 +++++++------- source/game/game.h | 8 ++++---- source/game/order.cpp | 6 +++--- source/game/order.h | 16 ++++++++-------- source/test/test.cpp | 8 ++++---- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/source/game/game.cpp b/source/game/game.cpp index 3bede2a..e081858 100644 --- a/source/game/game.cpp +++ b/source/game/game.cpp @@ -48,7 +48,7 @@ int CTTRTSGame::IssueOrders( Team team, const std::string& _orders ) orders.erase(0,pos+1); // Create an order from the string and push it back - COrder order = GetOrderFromString( sorder ); + SOrder order = GetOrderFromString( sorder ); orderVector.push_back(order); } @@ -71,7 +71,7 @@ int CTTRTSGame::IssueOrders( Team team, const COrderVector& orders ) } // Issue a single order -int CTTRTSGame::IssueOrder( Team team, const COrder& order ) +int CTTRTSGame::IssueOrder( Team team, const SOrder & order ) { // Verify the order if ( VerifyOrder(team,order) ) @@ -259,7 +259,7 @@ int CTTRTSGame::SimulateToNextTurn() // Clear all orders for ( SOrderUnitPair & pair : m_OrderUnitPairs ) - pair.order = COrder(); + pair.order = SOrder(); // Increment the current turn turn++; @@ -343,7 +343,7 @@ int CTTRTSGame::AddUnit( CUnit&& unit ) } // Add the unit with a blank order - m_OrderUnitPairs.push_back( SOrderUnitPair(std::move(unit), COrder()) ); + m_OrderUnitPairs.push_back( SOrderUnitPair(std::move(unit), SOrder()) ); return 0; @@ -366,7 +366,7 @@ int CTTRTSGame::AddUnits( CUnitVector&& units ) } // Verify any order -int CTTRTSGame::VerifyOrder( Team team, const COrder& order ) const +int CTTRTSGame::VerifyOrder( Team team, const SOrder & order ) const { int ret = 1; @@ -405,7 +405,7 @@ const CUnit& CTTRTSGame::GetUnitByIDConst( unit_id_t id ) const } // Get an order by unit ID -const COrder& CTTRTSGame::GetOrderByIDConst( unit_id_t id ) const +const SOrder & CTTRTSGame::GetOrderByIDConst( unit_id_t id ) const { for ( const SOrderUnitPair & pair : m_OrderUnitPairs ) { @@ -415,7 +415,7 @@ const COrder& CTTRTSGame::GetOrderByIDConst( unit_id_t id ) const } // Return an invalid unit - static COrder invalid_order; + static SOrder invalid_order; return invalid_order; } diff --git a/source/game/game.h b/source/game/game.h index 636b084..9eeb76e 100644 --- a/source/game/game.h +++ b/source/game/game.h @@ -41,7 +41,7 @@ public: // Issue orders to the game, returns non-zero if orders are incorrect int IssueOrders( Team team, const std::string& orders ); int IssueOrders( Team team, const COrderVector& orders ); - int IssueOrder( Team team, const COrder& order ); + int IssueOrder( Team team, const SOrder & order ); // Add a units to the game, nonzero return value indicates error int AddUnit( CUnit&& unit ); @@ -52,11 +52,11 @@ public: // Get unit and orderby index as above (not unit ID) inline const CUnit& GetUnitByIndex( unsigned int i ) const { return m_OrderUnitPairs[i].unit; } - inline const COrder& GetOrdersByIndex( unsigned int i ) const { return m_OrderUnitPairs[i].order; } + inline const SOrder & GetOrdersByIndex( unsigned int i ) const { return m_OrderUnitPairs[i].order; } // Get a unit by it's ID const CUnit& GetUnitByIDConst( unit_id_t id ) const; - const COrder& GetOrderByIDConst( unit_id_t id ) const; + const SOrder & GetOrderByIDConst( unit_id_t id ) const; // Get dimensions inline const uvector2& GetDimensions() const { return dimensions; } @@ -79,7 +79,7 @@ private: static bool CheckForPassThrough( const CUnit& one, const CUnit& two ); // Verify any order or position - non-zero is error - int VerifyOrder( Team team, const COrder& order ) const; + int VerifyOrder( Team team, const SOrder & order ) const; int VerifyPos( uvector2 vec ) const; // Get a units new position after an order diff --git a/source/game/order.cpp b/source/game/order.cpp index 8bd95a9..8e0e82f 100644 --- a/source/game/order.cpp +++ b/source/game/order.cpp @@ -2,7 +2,7 @@ #include "order.h" // Convert an order to a string -std::string GetStringFromOrder(const COrder& order ) +std::string GetStringFromOrder(const SOrder & order ) { static char buff[128]; memset(buff,0,sizeof(buff)); @@ -15,9 +15,9 @@ std::string GetStringFromOrder(const COrder& order ) } // Convert a string to an order -COrder GetOrderFromString( const std::string& order ) +SOrder GetOrderFromString( const std::string& order ) { - COrder ret; + SOrder ret; char corder; unsigned int unit; diff --git a/source/game/order.h b/source/game/order.h index 1072515..845e27f 100644 --- a/source/game/order.h +++ b/source/game/order.h @@ -19,10 +19,10 @@ enum class command_c : char }; // Container for an order -struct COrder +struct SOrder { // Base constructor makes invalid order - COrder() + SOrder() : unit ( unit_id_invalid ) , command( command_c::NUM_INVALID ) {} @@ -34,21 +34,21 @@ struct COrder command_c command; // Basic operators - inline bool operator==( const COrder& rhs ) const; - inline bool operator!=( const COrder& rhs ) const { return !(*this==rhs); } + inline bool operator==( const SOrder & rhs ) const; + inline bool operator!=( const SOrder & rhs ) const { return !(*this==rhs); } }; // Simple == operator -inline bool COrder::operator== ( const COrder& rhs ) const +inline bool SOrder::operator== ( const SOrder & rhs ) const { return ( unit == rhs.unit ) && ( command == rhs.command); } // Typedef a vector of orders -typedef std::vector COrderVector; +typedef std::vector COrderVector; // string <--> order conversion functions -std::string GetStringFromOrder(const COrder& order ); -COrder GetOrderFromString( const std::string& order ); +std::string GetStringFromOrder(const SOrder & order ); +SOrder GetOrderFromString( const std::string& order ); #endif //_ORDERS_H_ diff --git a/source/test/test.cpp b/source/test/test.cpp index 1c8f38d..4ffb766 100644 --- a/source/test/test.cpp +++ b/source/test/test.cpp @@ -55,11 +55,11 @@ const char* tests() // Test if we can successfully convert orders back and forth { - COrder order; + SOrder order; order.command = command_c::F; order.unit = 10; std::string order_string = GetStringFromOrder(order); - COrder order2 = GetOrderFromString(order_string); + SOrder order2 = GetOrderFromString(order_string); if ( order2 != order ) return "failed order string conversion test"; @@ -106,7 +106,7 @@ const char* tests() CUnit unit = CUnit::GetUnitFromVis('>'); const unit_id_t id = unit.getID(); - COrder order; + SOrder order; unit.setPos( {2,2} ); unit.setTeam(Team::Red); @@ -137,7 +137,7 @@ const char* tests() { CUnit unit = CUnit::GetUnitFromVis('>'); id = unit.getID(); - COrder order; + SOrder order; unit.setPos( {0,0} ); unit.setTeam(Team::Blue); From c38fb3dd41dd178285050e3e7ab42bfa595346b3 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Sun, 21 Dec 2014 10:41:06 +0000 Subject: [PATCH 11/95] Realign unit.h --- source/game/unit.h | 47 ++++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/source/game/unit.h b/source/game/unit.h index b08a707..2a99fc9 100644 --- a/source/game/unit.h +++ b/source/game/unit.h @@ -18,24 +18,21 @@ class CUnit public: // Factory function for creating units from a visual - static CUnit GetUnitFromVis( unitVis_c vis ); + static CUnit GetUnitFromVis( unitVis_c vis ); // Unit <--> string conversion functions - static std::string GetStringFromUnit(const CUnit& unit ); - static CUnit GetUnitFromString(const std::string& unit ); + static std::string GetStringFromUnit(const CUnit& unit ); + static CUnit GetUnitFromString(const std::string& unit ); // Constructor CUnit(); // Move constructor and move assignment. CUnit cannot be copied CUnit(CUnit&& unit); - CUnit& operator=(CUnit&& unit); + CUnit& operator=(CUnit&& unit); - bool operator==(const CUnit& rhs); - bool operator!=(const CUnit& rhs) { return !(*this == rhs); } - - // Default dtor - ~CUnit() = default; + bool operator==(const CUnit& rhs); + bool operator!=(const CUnit& rhs) { return !(*this == rhs); } // Getters for all the members inline const unit_id_t& getID() const { return unit_id; } @@ -45,44 +42,44 @@ public: inline const uvector2& getPos() const { return pos; } // Set - inline Team setTeam(const Team & v) { return (team_id = v); } - inline unitVis_c setVisual(const unitVis_c& v) { return ( unit_vis = v ); } - inline dir_t setDir(const dir_t& v) { return (dir = v); } - inline void setPos(const uvector2& v) { pos = v; } + inline Team setTeam(const Team & v) { return (team_id = v); } + inline unitVis_c setVisual(const unitVis_c& v) { return ( unit_vis = v ); } + inline dir_t setDir(const dir_t& v) { return (dir = v); } + inline void setPos(const uvector2& v) { pos = v; } // Get the co-ordinate in front of the unit - uvector2 getInFront() const; + uvector2 getInFront() const; // Check unit is valid - inline bool valid() const; + inline bool valid() const; // Set a unit based solely on it's visual - bool setFromVisual( const unitVis_c& vis); + bool setFromVisual( const unitVis_c& vis); // Orientation methods - dir_t turnLeft(); - dir_t turnRight(); - dir_t turnAround(); + dir_t turnLeft(); + dir_t turnRight(); + dir_t turnAround(); private: // Update my visual must be called when setting direction - unitVis_c updateMyVisual(); + unitVis_c updateMyVisual(); // Unit ID - unit_id_t unit_id; + unit_id_t unit_id; // Visual - unitVis_c unit_vis; + unitVis_c unit_vis; // Team ID - Team team_id; + Team team_id; // Direction - dir_t dir; + dir_t dir; // Position - uvector2 pos; + uvector2 pos; }; // Typedef for a vector of units From f55bc5413aaef7e1e4b866d465ba24c5ddcddb48 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Sun, 21 Dec 2014 10:44:08 +0000 Subject: [PATCH 12/95] Correct case for all CUnit methods --- source/game/game.cpp | 62 ++++++++++++++++++++++---------------------- source/game/unit.cpp | 40 ++++++++++++++-------------- source/game/unit.h | 40 ++++++++++++++-------------- source/gen/gen.cpp | 6 ++--- source/test/test.cpp | 44 +++++++++++++++---------------- 5 files changed, 96 insertions(+), 96 deletions(-) diff --git a/source/game/game.cpp b/source/game/game.cpp index e081858..90cf422 100644 --- a/source/game/game.cpp +++ b/source/game/game.cpp @@ -80,7 +80,7 @@ int CTTRTSGame::IssueOrder( Team team, const SOrder & order ) // Get the right unit for the order for ( SOrderUnitPair & pair : m_OrderUnitPairs ) { - if ( pair.unit.getID() == order.unit ) + if (pair.unit.GetID() == order.unit ) { pair.order = order; return 0; @@ -113,10 +113,10 @@ uvector2 CTTRTSGame::GetNewPosition( const SOrderUnitPair & pair ) const { // For forward orders, grab in front case command_c::F: - return pair.unit.getInFront(); + return pair.unit.GetInFront(); // For all other orders, just grab the old position default: - return pair.unit.getPos(); + return pair.unit.GetPos(); } } @@ -145,7 +145,7 @@ int CTTRTSGame::SimulateToNextTurn() for ( const SOrderUnitPair & pair2 : m_OrderUnitPairs ) { // Skip myself - if( pair.unit.getID() == pair2.unit.getID() ) continue; + if(pair.unit.GetID() == pair2.unit.GetID() ) continue; if( GetNewPosition(pair2) == newpos ) { @@ -158,7 +158,7 @@ int CTTRTSGame::SimulateToNextTurn() // If the movement is still possible if ( possible ) { - pair.unit.setPos(newpos); + pair.unit.SetPos(newpos); } } break; @@ -175,13 +175,13 @@ int CTTRTSGame::SimulateToNextTurn() case command_c::L: { // Simply turn left - pair.unit.turnLeft(); + pair.unit.TurnLeft(); } break; case command_c::R: { // Simply turn right - pair.unit.turnRight(); + pair.unit.TurnRight(); } break; default: @@ -200,11 +200,11 @@ int CTTRTSGame::SimulateToNextTurn() { if ( pair.order.command == command_c::A ) { - uvector2 newpos = pair.unit.getInFront(); + uvector2 newpos = pair.unit.GetInFront(); // If move would be within the arena if ( ( newpos.x <= dimensions.x-1 ) && ( newpos.y <= dimensions.y-1 ) ) { - pair.unit.setPos(newpos); + pair.unit.SetPos(newpos); // Unit moved, so more charging needs to be done charging = true; @@ -218,13 +218,13 @@ int CTTRTSGame::SimulateToNextTurn() for ( SOrderUnitPair & pair1 : m_OrderUnitPairs ) if ( pair1.order.command == command_c::A ) for ( SOrderUnitPair & pair2 : m_OrderUnitPairs ) - if ( pair1.unit.getID() != pair2.unit.getID() // Don't check the same units + if (pair1.unit.GetID() != pair2.unit.GetID() // Don't check the same units && pair2.order.command == command_c::A ) { if( CheckForPassThrough(pair1.unit,pair2.unit) ) { - toKill.push_back(pair1.unit.getID()); - toKill.push_back(pair2.unit.getID()); + toKill.push_back(pair1.unit.GetID()); + toKill.push_back(pair2.unit.GetID()); } } @@ -236,18 +236,18 @@ int CTTRTSGame::SimulateToNextTurn() for ( SOrderUnitPair & pair1 : m_OrderUnitPairs ) for ( SOrderUnitPair & pair2 : m_OrderUnitPairs ) { - if( pair1.unit.getID() == pair2.unit.getID() ) continue; // Don't check the same units + if(pair1.unit.GetID() == pair2.unit.GetID() ) continue; // Don't check the same units - if( pair1.unit.getPos() == pair2.unit.getPos() ) + if(pair1.unit.GetPos() == pair2.unit.GetPos() ) { if( pair1.order.command == command_c::A ) { - toKill.push_back(pair2.unit.getID()); + toKill.push_back(pair2.unit.GetID()); } if( pair2.order.command == command_c::A ) { - toKill.push_back(pair1.unit.getID()); + toKill.push_back(pair1.unit.GetID()); } } } @@ -280,7 +280,7 @@ void CTTRTSGame::KillAll( std::vector< unit_id_t >& vec ) it != m_OrderUnitPairs.end(); it++ ) { - if( (*it).unit.getID() == id ) + if((*it).unit.GetID() == id ) { // Remove the unit from our alive unit pairs m_OrderUnitPairs.erase(it); @@ -294,10 +294,10 @@ void CTTRTSGame::KillAll( std::vector< unit_id_t >& vec ) // Check if two units passed through each other bool CTTRTSGame::CheckForPassThrough( const CUnit& one, const CUnit& two ) { - uvector2 pos1 = one.getPos(); - uvector2 pos2 = two.getPos(); - dir_t dir1 = one.getDir(); - dir_t dir2 = two.getDir(); + uvector2 pos1 = one.GetPos(); + uvector2 pos2 = two.GetPos(); + dir_t dir1 = one.GetDir(); + dir_t dir2 = two.GetDir(); if( pos1.x == pos2.x ) { // Same col if (pos1.y == (pos2.y + 1)) { @@ -327,18 +327,18 @@ bool CTTRTSGame::CheckForPassThrough( const CUnit& one, const CUnit& two ) int CTTRTSGame::AddUnit( CUnit&& unit ) { // Verify the unit - if( !unit.valid() ) + if( !unit.Valid() ) return 1; // Verify if the unit can be placed on the current board - const uvector2 pos = unit.getPos(); + const uvector2 pos = unit.GetPos(); if( (pos.x >= dimensions.x) || (pos.y >= dimensions.y) ) return 2; // If any unit's position matches, reject this for ( const SOrderUnitPair & pair: m_OrderUnitPairs ) { - if( pair.unit.getPos() == unit.getPos() ) + if(pair.unit.GetPos() == unit.GetPos() ) return 3; } @@ -377,8 +377,8 @@ int CTTRTSGame::VerifyOrder( Team team, const SOrder & order ) const for ( const SOrderUnitPair & pair : m_OrderUnitPairs ) { // Accept if we have the unit - if ( pair.unit.getID() == unitID - && pair.unit.getTeam() == team ) + if (pair.unit.GetID() == unitID + && pair.unit.GetTeam() == team ) { ret = 0; break; @@ -395,7 +395,7 @@ const CUnit& CTTRTSGame::GetUnitByIDConst( unit_id_t id ) const for ( const SOrderUnitPair & pair : m_OrderUnitPairs ) { // Attempt the unit add - if ( pair.unit.getID() == id ) + if (pair.unit.GetID() == id ) return pair.unit; } @@ -410,7 +410,7 @@ const SOrder & CTTRTSGame::GetOrderByIDConst( unit_id_t id ) const for ( const SOrderUnitPair & pair : m_OrderUnitPairs ) { // Attempt the unit add - if ( pair.unit.getID() == id ) + if (pair.unit.GetID() == id ) return pair.order; } @@ -425,7 +425,7 @@ CUnit& CTTRTSGame::GetUnitByID( unit_id_t id ) for ( SOrderUnitPair & pair : m_OrderUnitPairs ) { // Attempt the unit add - if ( pair.unit.getID() == id ) + if (pair.unit.GetID() == id ) return pair.unit; } @@ -443,7 +443,7 @@ std::vector CTTRTSGame::GetTeams() const // Grab all teams for ( const SOrderUnitPair & pair : m_OrderUnitPairs ) { - teams.push_back(pair.unit.getTeam()); + teams.push_back(pair.unit.GetTeam()); } // Remove dupes @@ -463,7 +463,7 @@ Team CTTRTSGame::CheckForWin() const // Count up all the units for each Team for ( const SOrderUnitPair & pair : m_OrderUnitPairs ) { - const int team = (int)pair.unit.getTeam(); + const int team = (int) pair.unit.GetTeam(); units[team] += 1; } diff --git a/source/game/unit.cpp b/source/game/unit.cpp index 24d02af..6121d9c 100644 --- a/source/game/unit.cpp +++ b/source/game/unit.cpp @@ -36,7 +36,7 @@ namespace } // force a reset of the unit ID value -void forceResetUnitId() +void __forceResetCUnitID() { unit_id_t i = 0; get_unique_unit_id(&i); @@ -46,7 +46,7 @@ void forceResetUnitId() CUnit CUnit::GetUnitFromVis( unitVis_c vis ) { CUnit unit; - unit.setFromVisual(vis); + unit.SetFromVisual(vis); return unit; } @@ -106,7 +106,7 @@ CUnit::CUnit() , dir ( dir_t::S ) , pos ( { ucoord_invalid, ucoord_invalid } ) { - updateMyVisual(); + UpdateMyVisual(); } // Move constructor @@ -117,7 +117,7 @@ CUnit::CUnit(CUnit&& unit) , dir ( std::move(unit.dir) ) , pos ( std::move(unit.pos) ) { - updateMyVisual(); + UpdateMyVisual(); } @@ -143,22 +143,22 @@ bool CUnit::operator==(const CUnit& rhs) } // Update the visual representation of the unit -unitVis_c CUnit::updateMyVisual() +unitVis_c CUnit::UpdateMyVisual() { // Start at invalid - setVisual(unitVis_invalid); + SetVisual(unitVis_invalid); dir_to_vis_map::const_iterator it = get_vis_map_V().find(dir); // If found set to new vis if( it != get_vis_map_V().end() ) - setVisual(it->second); + SetVisual(it->second); - return getVisual(); + return GetVisual(); } // Set the unit from visual -bool CUnit::setFromVisual( const unitVis_c& vis ) +bool CUnit::SetFromVisual(const unitVis_c &vis) { dir_to_vis_map::const_iterator it; @@ -167,7 +167,7 @@ bool CUnit::setFromVisual( const unitVis_c& vis ) if( it->second == vis ) { dir = it->first; - updateMyVisual(); + UpdateMyVisual(); return true; } } @@ -177,7 +177,7 @@ bool CUnit::setFromVisual( const unitVis_c& vis ) } // Turn unit left -dir_t CUnit::turnLeft() +dir_t CUnit::TurnLeft() { switch( dir ) { @@ -198,13 +198,13 @@ dir_t CUnit::turnLeft() break; } - updateMyVisual(); + UpdateMyVisual(); - return getDir(); + return GetDir(); } // Turn unit right -dir_t CUnit::turnRight() +dir_t CUnit::TurnRight() { switch( dir ) { @@ -225,13 +225,13 @@ dir_t CUnit::turnRight() break; } - updateMyVisual(); + UpdateMyVisual(); - return getDir(); + return GetDir(); } // Turn unit around -dir_t CUnit::turnAround() +dir_t CUnit::TurnAround() { switch( dir ) { @@ -252,13 +252,13 @@ dir_t CUnit::turnAround() break; } - updateMyVisual(); + UpdateMyVisual(); - return getDir(); + return GetDir(); } // Get the co-ordinate infront of the unit -uvector2 CUnit::getInFront() const +uvector2 CUnit::GetInFront() const { vector2 delta = vecFromDir(dir); return pos + delta; diff --git a/source/game/unit.h b/source/game/unit.h index 2a99fc9..87f1354 100644 --- a/source/game/unit.h +++ b/source/game/unit.h @@ -10,7 +10,7 @@ #define UNIT_FORMATTER "UNIT:%u tm:%u vs:%c dr:%c ps:[%u,%u]" // force a reset of the unit ID value -void forceResetUnitId(); +void __forceResetCUnitID(); // Base unit type class CUnit @@ -35,36 +35,36 @@ public: bool operator!=(const CUnit& rhs) { return !(*this == rhs); } // Getters for all the members - inline const unit_id_t& getID() const { return unit_id; } - inline const Team & getTeam() const { return team_id; } - inline const unitVis_c& getVisual() const { return unit_vis; } - inline const dir_t& getDir() const { return dir; } - inline const uvector2& getPos() const { return pos; } + inline const unit_id_t& GetID() const { return unit_id; } + inline const Team & GetTeam() const { return team_id; } + inline const unitVis_c& GetVisual() const { return unit_vis; } + inline const dir_t& GetDir() const { return dir; } + inline const uvector2& GetPos() const { return pos; } // Set - inline Team setTeam(const Team & v) { return (team_id = v); } - inline unitVis_c setVisual(const unitVis_c& v) { return ( unit_vis = v ); } - inline dir_t setDir(const dir_t& v) { return (dir = v); } - inline void setPos(const uvector2& v) { pos = v; } + inline Team SetTeam(const Team &v) { return (team_id = v); } + inline unitVis_c SetVisual(const unitVis_c &v) { return ( unit_vis = v ); } + inline dir_t SetDir(const dir_t &v) { return (dir = v); } + inline void SetPos(const uvector2 &v) { pos = v; } // Get the co-ordinate in front of the unit - uvector2 getInFront() const; + uvector2 GetInFront() const; // Check unit is valid - inline bool valid() const; + inline bool Valid() const; // Set a unit based solely on it's visual - bool setFromVisual( const unitVis_c& vis); + bool SetFromVisual(const unitVis_c &vis); // Orientation methods - dir_t turnLeft(); - dir_t turnRight(); - dir_t turnAround(); + dir_t TurnLeft(); + dir_t TurnRight(); + dir_t TurnAround(); private: // Update my visual must be called when setting direction - unitVis_c updateMyVisual(); + unitVis_c UpdateMyVisual(); // Unit ID unit_id_t unit_id; @@ -83,11 +83,11 @@ private: }; // Typedef for a vector of units -typedef std::vector< CUnit > CUnitVector; -typedef std::vector< unit_id_t > CUnitIDVector; +typedef std::vector< CUnit > CUnitVector; +typedef std::vector< unit_id_t > CUnitIDVector; // Simple validation -inline bool CUnit::valid() const +inline bool CUnit::Valid() const { return (unit_id != unit_id_invalid ) && (team_id != Team::NUM_INVALID ) diff --git a/source/gen/gen.cpp b/source/gen/gen.cpp index fd85b3c..25bde6f 100644 --- a/source/gen/gen.cpp +++ b/source/gen/gen.cpp @@ -6,8 +6,8 @@ void AddUnitToGame( Team team, char vis, uvector2 vec, CTTRTSGame& game ) { CUnit unit = CUnit::GetUnitFromVis(vis); - unit.setPos( vec ); - unit.setTeam(team); + unit.SetPos(vec); + unit.SetTeam(team); game.AddUnit(std::move(unit)); } @@ -18,7 +18,7 @@ void OutputGame( CTTRTSGame&& game ) output << game.GetStateAsString(); output.close(); - forceResetUnitId(); + __forceResetCUnitID(); } int main() diff --git a/source/test/test.cpp b/source/test/test.cpp index 4ffb766..4120df7 100644 --- a/source/test/test.cpp +++ b/source/test/test.cpp @@ -8,8 +8,8 @@ const char* tests() // Test if we can properly set a unit's visual { CUnit unit; - unit.setFromVisual('v'); - if( unit.getVisual() != 'v' ) + unit.SetFromVisual('v'); + if(unit.GetVisual() != 'v' ) return "failed to properly create V unit"; } @@ -17,7 +17,7 @@ const char* tests() { CUnit unit; CUnit unit2; - if( unit.getID() == unit2.getID() ) + if(unit.GetID() == unit2.GetID() ) return "Unit IDs the same"; } @@ -35,9 +35,9 @@ const char* tests() // Test custom unit conversion { CUnit unit1; - unit1.setFromVisual('v'); - unit1.setTeam(Team::Green); - unit1.setPos( uvector2(5,10) ); + unit1.SetFromVisual('v'); + unit1.SetTeam(Team::Green); + unit1.SetPos(uvector2(5, 10)); std::string unit1Desc = CUnit::GetStringFromUnit(unit1); CUnit unit2 = CUnit::GetUnitFromString(unit1Desc); @@ -49,7 +49,7 @@ const char* tests() // Test if we can successfully create a unit from a visual { CUnit unit = CUnit::GetUnitFromVis('v'); - if( unit.getVisual() != 'v' ) + if(unit.GetVisual() != 'v' ) return "failed to properly create V unit with factory"; } @@ -81,16 +81,16 @@ const char* tests() { CUnit unit = CUnit::GetUnitFromVis('^'); - unit.setPos( {2,2} ); - unit.setTeam(Team::Red); + unit.SetPos({2, 2}); + unit.SetTeam(Team::Red); game.AddUnit(std::move(unit)); } { CUnit unit = CUnit::GetUnitFromVis('^'); - unit.setPos( {2,2} ); - unit.setTeam(Team::Red); + unit.SetPos({2, 2}); + unit.SetTeam(Team::Red); if( !game.AddUnit(std::move(unit)) ) return "Game should have rejected unit placed on the same spot"; @@ -105,11 +105,11 @@ const char* tests() CTTRTSGame game( 5, 5 ); CUnit unit = CUnit::GetUnitFromVis('>'); - const unit_id_t id = unit.getID(); + const unit_id_t id = unit.GetID(); SOrder order; - unit.setPos( {2,2} ); - unit.setTeam(Team::Red); + unit.SetPos({2, 2}); + unit.SetTeam(Team::Red); if ( game.AddUnit(std::move(unit)) ) return "Game failed to add valid unit"; @@ -123,7 +123,7 @@ const char* tests() if (game.SimulateToNextTurn() ) return "Game failed to simulate valid turn"; - if( game.GetUnitByIDConst(id).getPos() != uvector2{3,2} ) + if(game.GetUnitByIDConst(id).GetPos() != uvector2{3,2} ) return "Simple movement order failed"; } @@ -136,11 +136,11 @@ const char* tests() unit_id_t id; { CUnit unit = CUnit::GetUnitFromVis('>'); - id = unit.getID(); + id = unit.GetID(); SOrder order; - unit.setPos( {0,0} ); - unit.setTeam(Team::Blue); + unit.SetPos({0, 0}); + unit.SetTeam(Team::Blue); if ( game.AddUnit(std::move(unit)) ) return "Game failed to add valid unit"; @@ -154,8 +154,8 @@ const char* tests() { CUnit unit = CUnit::GetUnitFromVis('<'); - unit.setPos( {1,0} ); - unit.setTeam(Team::Red); + unit.SetPos({1, 0}); + unit.SetTeam(Team::Red); if ( game.AddUnit(std::move(unit)) ) return "Game failed to add valid unit"; @@ -166,10 +166,10 @@ const char* tests() if ( game.GetNumUnits() != 1 ) return "Game failed to kill a unit when it logically should have"; - if ( game.GetUnitByIndex(0).getDir() != dir_t::E ) + if (game.GetUnitByIndex(0).GetDir() != dir_t::E ) return "Game killed the wrong unit"; - if ( game.GetUnitByIndex(0).getID() != id ) + if (game.GetUnitByIndex(0).GetID() != id ) return "Game killed the wrong unit"; if ( game.CheckForWin() != Team::Blue ) From 4aa51a64b664f8066d93d15c9b9aa219321e5942 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Sun, 21 Dec 2014 10:45:08 +0000 Subject: [PATCH 13/95] Correct case for unitvis --- source/game/gametypes.h | 4 ++-- source/game/unit.cpp | 14 +++++++------- source/game/unit.h | 14 +++++++------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/source/game/gametypes.h b/source/game/gametypes.h index 43cc4d3..12ed9b0 100644 --- a/source/game/gametypes.h +++ b/source/game/gametypes.h @@ -15,9 +15,9 @@ enum class Team : char typedef unsigned short unit_id_t; // Type for unit IDs -typedef char unitVis_c; // Typedef for unit visual representations +typedef char unitvis_c; // Typedef for unit visual representations static const unit_id_t unit_id_invalid = std::numeric_limits::max(); -static const unitVis_c unitVis_invalid = std::numeric_limits::max(); +static const unitvis_c unitvis_invalid = std::numeric_limits::max(); #endif //_GAME_TYPES_H_ \ No newline at end of file diff --git a/source/game/unit.cpp b/source/game/unit.cpp index 6121d9c..0f7c8c0 100644 --- a/source/game/unit.cpp +++ b/source/game/unit.cpp @@ -18,7 +18,7 @@ namespace } // Map of visual representation of unit V - typedef std::map< dir_t, unitVis_c > dir_to_vis_map; + typedef std::map< dir_t, unitvis_c> dir_to_vis_map; // Helper function to get the vis map during static init const dir_to_vis_map& get_vis_map_V() @@ -43,7 +43,7 @@ void __forceResetCUnitID() } // Get a unit from a visual -CUnit CUnit::GetUnitFromVis( unitVis_c vis ) +CUnit CUnit::GetUnitFromVis( unitvis_c vis ) { CUnit unit; unit.SetFromVisual(vis); @@ -91,7 +91,7 @@ CUnit CUnit::GetUnitFromString(const std::string& unit ) ret.unit_id = (unit_id_t)id; ret.team_id = (Team)team; - ret.unit_vis = (unitVis_c)vis; + ret.unit_vis = (unitvis_c)vis; ret.dir = (dir_t)dir; ret.pos = uvector2(posx,posy); @@ -102,7 +102,7 @@ CUnit CUnit::GetUnitFromString(const std::string& unit ) CUnit::CUnit() : unit_id ( get_unique_unit_id() ) , team_id ( Team::NUM_INVALID ) -, unit_vis ( unitVis_invalid ) +, unit_vis (unitvis_invalid) , dir ( dir_t::S ) , pos ( { ucoord_invalid, ucoord_invalid } ) { @@ -143,10 +143,10 @@ bool CUnit::operator==(const CUnit& rhs) } // Update the visual representation of the unit -unitVis_c CUnit::UpdateMyVisual() +unitvis_c CUnit::UpdateMyVisual() { // Start at invalid - SetVisual(unitVis_invalid); + SetVisual(unitvis_invalid); dir_to_vis_map::const_iterator it = get_vis_map_V().find(dir); @@ -158,7 +158,7 @@ unitVis_c CUnit::UpdateMyVisual() } // Set the unit from visual -bool CUnit::SetFromVisual(const unitVis_c &vis) +bool CUnit::SetFromVisual(const unitvis_c &vis) { dir_to_vis_map::const_iterator it; diff --git a/source/game/unit.h b/source/game/unit.h index 87f1354..c53ae0b 100644 --- a/source/game/unit.h +++ b/source/game/unit.h @@ -18,7 +18,7 @@ class CUnit public: // Factory function for creating units from a visual - static CUnit GetUnitFromVis( unitVis_c vis ); + static CUnit GetUnitFromVis( unitvis_c vis ); // Unit <--> string conversion functions static std::string GetStringFromUnit(const CUnit& unit ); @@ -37,13 +37,13 @@ public: // Getters for all the members inline const unit_id_t& GetID() const { return unit_id; } inline const Team & GetTeam() const { return team_id; } - inline const unitVis_c& GetVisual() const { return unit_vis; } + inline const unitvis_c & GetVisual() const { return unit_vis; } inline const dir_t& GetDir() const { return dir; } inline const uvector2& GetPos() const { return pos; } // Set inline Team SetTeam(const Team &v) { return (team_id = v); } - inline unitVis_c SetVisual(const unitVis_c &v) { return ( unit_vis = v ); } + inline unitvis_c SetVisual(const unitvis_c &v) { return ( unit_vis = v ); } inline dir_t SetDir(const dir_t &v) { return (dir = v); } inline void SetPos(const uvector2 &v) { pos = v; } @@ -54,7 +54,7 @@ public: inline bool Valid() const; // Set a unit based solely on it's visual - bool SetFromVisual(const unitVis_c &vis); + bool SetFromVisual(const unitvis_c &vis); // Orientation methods dir_t TurnLeft(); @@ -64,13 +64,13 @@ public: private: // Update my visual must be called when setting direction - unitVis_c UpdateMyVisual(); + unitvis_c UpdateMyVisual(); // Unit ID unit_id_t unit_id; // Visual - unitVis_c unit_vis; + unitvis_c unit_vis; // Team ID Team team_id; @@ -91,7 +91,7 @@ inline bool CUnit::Valid() const { return (unit_id != unit_id_invalid ) && (team_id != Team::NUM_INVALID ) - && (unit_vis != unitVis_invalid); + && (unit_vis != unitvis_invalid); } #endif //_UNIT_H_ From d4f947070417857d0911a29ec80d0d6562136380 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Sun, 21 Dec 2014 10:47:58 +0000 Subject: [PATCH 14/95] Correct some usages of COrder --- source/game/orderunitpair.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/game/orderunitpair.h b/source/game/orderunitpair.h index 759f165..278608c 100644 --- a/source/game/orderunitpair.h +++ b/source/game/orderunitpair.h @@ -16,7 +16,7 @@ struct SOrderUnitPair {} // Multi parameter constructor - SOrderUnitPair( CUnit&& u, COrder o ) + SOrderUnitPair( CUnit&& u, SOrder o ) : unit ( std::move(u) ) , order ( o ) {} @@ -30,7 +30,7 @@ struct SOrderUnitPair } CUnit unit; // The unit - COrder order; // Order for this unit from this turn + SOrder order; // Order for this unit from this turn }; // Typedef for a vector of these unit pairs From 9e44d5144b18842255decdc6f845136297b94bdf Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Sun, 21 Dec 2014 11:04:26 +0000 Subject: [PATCH 15/95] Rename all usages of Team to Player This was confusingly inconsistent in the codebase. fixes #7 --- source/game/game.cpp | 64 ++++++++++++++++++++--------------------- source/game/game.h | 14 ++++----- source/game/gametypes.h | 4 +-- source/game/unit.cpp | 18 ++++++------ source/game/unit.h | 18 ++++++------ source/gen/gen.cpp | 24 ++++++++-------- source/test/test.cpp | 20 ++++++------- source/ttrts/README.md | 2 +- source/ttrts/main.cpp | 34 +++++++++++----------- 9 files changed, 98 insertions(+), 100 deletions(-) diff --git a/source/game/game.cpp b/source/game/game.cpp index 90cf422..04292ca 100644 --- a/source/game/game.cpp +++ b/source/game/game.cpp @@ -30,7 +30,7 @@ CTTRTSGame& CTTRTSGame::operator=(CTTRTSGame&& game) } // Interpret a string of orders -int CTTRTSGame::IssueOrders( Team team, const std::string& _orders ) +int CTTRTSGame::IssueOrders( Player player, const std::string& _orders ) { COrderVector orderVector; @@ -53,17 +53,17 @@ int CTTRTSGame::IssueOrders( Team team, const std::string& _orders ) } // Call our add order by vector method - return IssueOrders(team,orderVector); + return IssueOrders(player,orderVector); } // Issue orders by vector to the game -int CTTRTSGame::IssueOrders( Team team, const COrderVector& orders ) +int CTTRTSGame::IssueOrders( Player player, const COrderVector& orders ) { // verify all the orders for ( auto order : orders ) { // If any order returns non-zero, back out - if ( IssueOrder(team,order) ) + if ( IssueOrder(player,order) ) return 1; } @@ -71,10 +71,10 @@ int CTTRTSGame::IssueOrders( Team team, const COrderVector& orders ) } // Issue a single order -int CTTRTSGame::IssueOrder( Team team, const SOrder & order ) +int CTTRTSGame::IssueOrder( Player player, const SOrder & order ) { // Verify the order - if ( VerifyOrder(team,order) ) + if ( VerifyOrder(player,order) ) return 1; // Get the right unit for the order @@ -366,7 +366,7 @@ int CTTRTSGame::AddUnits( CUnitVector&& units ) } // Verify any order -int CTTRTSGame::VerifyOrder( Team team, const SOrder & order ) const +int CTTRTSGame::VerifyOrder( Player player, const SOrder & order ) const { int ret = 1; @@ -378,7 +378,7 @@ int CTTRTSGame::VerifyOrder( Team team, const SOrder & order ) const { // Accept if we have the unit if (pair.unit.GetID() == unitID - && pair.unit.GetTeam() == team ) + && pair.unit.GetPlayer() == player) { ret = 0; break; @@ -434,60 +434,60 @@ CUnit& CTTRTSGame::GetUnitByID( unit_id_t id ) return invalid_unit; } -// Get a vector of the teams in the current game -std::vector CTTRTSGame::GetTeams() const +// Get a vector of the players in the current game +std::vector CTTRTSGame::GetPlayers() const { - std::vector teams; - teams.reserve(GetNumUnits()); + std::vector players; + players.reserve(GetNumUnits()); - // Grab all teams + // Grab all players for ( const SOrderUnitPair & pair : m_OrderUnitPairs ) { - teams.push_back(pair.unit.GetTeam()); + players.push_back(pair.unit.GetPlayer()); } // Remove dupes - std::sort( teams.begin(), teams.end() ); - teams.erase( std::unique( teams.begin(), teams.end() ), teams.end() ); + std::sort( players.begin(), players.end() ); + players.erase( std::unique( players.begin(), players.end() ), players.end() ); - return teams; + return players; } // Check if we have a win state -Team CTTRTSGame::CheckForWin() const +Player CTTRTSGame::CheckForWin() const { - // Array of units for each Team - unsigned int units[(int) Team::NUM_INVALID]; + // Array of units for each Player + unsigned int units[(int) Player::NUM_INVALID]; memset(units,0,sizeof(units)); - // Count up all the units for each Team + // Count up all the units for each Player for ( const SOrderUnitPair & pair : m_OrderUnitPairs ) { - const int team = (int) pair.unit.GetTeam(); - units[team] += 1; + const int player = (int) pair.unit.GetPlayer(); + units[player] += 1; } - // Default winning Team to invalid (no win) - Team winningTeam = Team::NUM_INVALID; + // Default winning Player to invalid (no win) + Player winningPlayer = Player::NUM_INVALID; - // For each of the teams + // For each of the players for ( unsigned int i = 0; i < _countof(units); i++ ) { - // if there are still units in this Team, and the winning Team hasn't been set - if( units[i] > 0 && winningTeam == Team::NUM_INVALID ) + // if there are still units in this Player, and the winning Player hasn't been set + if( units[i] > 0 && winningPlayer == Player::NUM_INVALID ) { - winningTeam = (Team)i; + winningPlayer = (Player)i; } - // Otherwise, if there are units in this Team and the winning Team HAS been set + // Otherwise, if there are units in this Player and the winning Player HAS been set else if ( units[i] > 0 ) { // Set back to invalid and break out of the loop - winningTeam = Team::NUM_INVALID; + winningPlayer = Player::NUM_INVALID; break; } } - return winningTeam; + return winningPlayer; } // Get the game information as a string diff --git a/source/game/game.h b/source/game/game.h index 9eeb76e..76451f6 100644 --- a/source/game/game.h +++ b/source/game/game.h @@ -33,15 +33,15 @@ public: // Check for a win, returns invalid for no win state reached // Note: this function will return invalid a draw was reached // best practice would be to call with GetNumUnits() == 0 - Team CheckForWin() const; + Player CheckForWin() const; // Get the game information as a string std::string GetStateAsString() const; // Issue orders to the game, returns non-zero if orders are incorrect - int IssueOrders( Team team, const std::string& orders ); - int IssueOrders( Team team, const COrderVector& orders ); - int IssueOrder( Team team, const SOrder & order ); + int IssueOrders( Player player, const std::string& orders ); + int IssueOrders( Player player, const COrderVector& orders ); + int IssueOrder( Player player, const SOrder & order ); // Add a units to the game, nonzero return value indicates error int AddUnit( CUnit&& unit ); @@ -70,8 +70,8 @@ public: inline int SetTurn( int in ) { return (turn = in); } inline int GetTurn() const { return turn; } - // Get a vector of the teams in the current game - std::vector GetTeams() const; + // Get a vector of the players in the current game + std::vector GetPlayers() const; private: @@ -79,7 +79,7 @@ private: static bool CheckForPassThrough( const CUnit& one, const CUnit& two ); // Verify any order or position - non-zero is error - int VerifyOrder( Team team, const SOrder & order ) const; + int VerifyOrder( Player player, const SOrder & order ) const; int VerifyPos( uvector2 vec ) const; // Get a units new position after an order diff --git a/source/game/gametypes.h b/source/game/gametypes.h index 12ed9b0..23b7aaf 100644 --- a/source/game/gametypes.h +++ b/source/game/gametypes.h @@ -3,8 +3,8 @@ #include // std::numeric_limits -// Type for a team IDs -enum class Team : char +// Type for a Player IDs +enum class Player : char { Red = 0, Green, diff --git a/source/game/unit.cpp b/source/game/unit.cpp index 0f7c8c0..166020e 100644 --- a/source/game/unit.cpp +++ b/source/game/unit.cpp @@ -51,7 +51,6 @@ CUnit CUnit::GetUnitFromVis( unitvis_c vis ) } // Get a string descriptor of a unit -// "U id:[unit_id] team:[team_id] player:[player_id] vis:[unit_vis] dir:[dir] pos:[pos.x],[pos.y]" std::string CUnit::GetStringFromUnit(const CUnit& unit ) { static char buff[128]; @@ -59,7 +58,7 @@ std::string CUnit::GetStringFromUnit(const CUnit& unit ) snprintf(buff,128, UNIT_FORMATTER, unit.unit_id, - (int)unit.team_id, + (int)unit.player_id, unit.unit_vis, unit.dir, unit.pos.x, @@ -69,13 +68,12 @@ std::string CUnit::GetStringFromUnit(const CUnit& unit ) } // Get a unit from a string descriptor -// "U id:[unit_id] team:[team_id] player:[player_id] vis:[unit_vis] dir:[dir] pos:[pos.x],[pos.y]" CUnit CUnit::GetUnitFromString(const std::string& unit ) { CUnit ret; unsigned int id; - int team; + int player; char vis; char dir; unsigned int posx; @@ -83,14 +81,14 @@ CUnit CUnit::GetUnitFromString(const std::string& unit ) sscanf(unit.c_str(), UNIT_FORMATTER, &id, - &team, + &player, &vis, &dir, &posx, &posy ); ret.unit_id = (unit_id_t)id; - ret.team_id = (Team)team; + ret.player_id = (Player) player; ret.unit_vis = (unitvis_c)vis; ret.dir = (dir_t)dir; ret.pos = uvector2(posx,posy); @@ -101,7 +99,7 @@ CUnit CUnit::GetUnitFromString(const std::string& unit ) // Plain constructor CUnit::CUnit() : unit_id ( get_unique_unit_id() ) -, team_id ( Team::NUM_INVALID ) +, player_id ( Player::NUM_INVALID ) , unit_vis (unitvis_invalid) , dir ( dir_t::S ) , pos ( { ucoord_invalid, ucoord_invalid } ) @@ -112,7 +110,7 @@ CUnit::CUnit() // Move constructor CUnit::CUnit(CUnit&& unit) : unit_id ( std::move(unit.unit_id) ) -, team_id ( std::move(unit.team_id) ) +, player_id ( std::move(unit.player_id) ) , unit_vis ( std::move(unit.unit_vis) ) , dir ( std::move(unit.dir) ) , pos ( std::move(unit.pos) ) @@ -125,7 +123,7 @@ CUnit::CUnit(CUnit&& unit) CUnit& CUnit::operator=(CUnit&& unit) { unit_id = std::move(unit.unit_id) ; - team_id = std::move(unit.team_id) ; + player_id = std::move(unit.player_id) ; unit_vis = std::move(unit.unit_vis) ; dir = std::move(unit.dir) ; pos = std::move(unit.pos) ; @@ -136,7 +134,7 @@ CUnit& CUnit::operator=(CUnit&& unit) bool CUnit::operator==(const CUnit& rhs) { return (unit_id == rhs.unit_id) - && (team_id == rhs.team_id) + && (player_id == rhs.player_id) && (unit_vis == rhs.unit_vis) && (dir == rhs.dir) && (pos == rhs.pos); diff --git a/source/game/unit.h b/source/game/unit.h index c53ae0b..a51ddff 100644 --- a/source/game/unit.h +++ b/source/game/unit.h @@ -7,7 +7,7 @@ #include "gametypes.h" #include "vector2.h" -#define UNIT_FORMATTER "UNIT:%u tm:%u vs:%c dr:%c ps:[%u,%u]" +#define UNIT_FORMATTER "UNIT:%u pl:%u vs:%c dr:%c ps:[%u,%u]" // force a reset of the unit ID value void __forceResetCUnitID(); @@ -36,14 +36,14 @@ public: // Getters for all the members inline const unit_id_t& GetID() const { return unit_id; } - inline const Team & GetTeam() const { return team_id; } - inline const unitvis_c & GetVisual() const { return unit_vis; } + inline const Player & GetPlayer() const { return player_id; } + inline const unitvis_c & GetVisual() const { return unit_vis; } inline const dir_t& GetDir() const { return dir; } inline const uvector2& GetPos() const { return pos; } // Set - inline Team SetTeam(const Team &v) { return (team_id = v); } - inline unitvis_c SetVisual(const unitvis_c &v) { return ( unit_vis = v ); } + inline Player SetPlayer(const Player &v) { return (player_id = v); } + inline unitvis_c SetVisual(const unitvis_c &v) { return (unit_vis = v); } inline dir_t SetDir(const dir_t &v) { return (dir = v); } inline void SetPos(const uvector2 &v) { pos = v; } @@ -70,10 +70,10 @@ private: unit_id_t unit_id; // Visual - unitvis_c unit_vis; + unitvis_c unit_vis; - // Team ID - Team team_id; + // Player ID + Player player_id; // Direction dir_t dir; @@ -90,7 +90,7 @@ typedef std::vector< unit_id_t > CUnitIDVector; inline bool CUnit::Valid() const { return (unit_id != unit_id_invalid ) - && (team_id != Team::NUM_INVALID ) + && (player_id != Player::NUM_INVALID ) && (unit_vis != unitvis_invalid); } diff --git a/source/gen/gen.cpp b/source/gen/gen.cpp index 25bde6f..9e385ed 100644 --- a/source/gen/gen.cpp +++ b/source/gen/gen.cpp @@ -3,11 +3,11 @@ #include #include -void AddUnitToGame( Team team, char vis, uvector2 vec, CTTRTSGame& game ) +void AddUnitToGame( Player player, char vis, uvector2 vec, CTTRTSGame& game ) { CUnit unit = CUnit::GetUnitFromVis(vis); unit.SetPos(vec); - unit.SetTeam(team); + unit.SetPlayer(player); game.AddUnit(std::move(unit)); } @@ -28,10 +28,10 @@ int main() CTTRTSGame game(6, 6); game.SetName("Tiny2v2"); - AddUnitToGame( Team::Red, '<', uvector2(4, 2), game); - AddUnitToGame( Team::Red, '<', uvector2(4, 4), game); - AddUnitToGame( Team::Green, '>', uvector2(1, 1), game); - AddUnitToGame( Team::Green, '>', uvector2(1, 3), game); + AddUnitToGame( Player::Red, '<', uvector2(4, 2), game); + AddUnitToGame( Player::Red, '<', uvector2(4, 4), game); + AddUnitToGame( Player::Green, '>', uvector2(1, 1), game); + AddUnitToGame( Player::Green, '>', uvector2(1, 3), game); OutputGame(std::move(game)); } @@ -42,9 +42,9 @@ int main() game.SetName("Big2v2"); for ( ucoord_t y : { 2,4,6,8,10 } ) - AddUnitToGame( Team::Red, '<', uvector2(18, y), game); + AddUnitToGame( Player::Red, '<', uvector2(18, y), game); for ( ucoord_t y : { 1,3,5,7,9 } ) - AddUnitToGame( Team::Green, '>', uvector2(1, y), game); + AddUnitToGame( Player::Green, '>', uvector2(1, y), game); OutputGame(std::move(game)); @@ -56,13 +56,13 @@ int main() game.SetName("Chess"); for ( ucoord_t y : { 1,3,5,7 } ) { - AddUnitToGame(Team::Red, '<', uvector2(6, y), game); - AddUnitToGame(Team::Red, '<', uvector2(7, y), game); + AddUnitToGame(Player::Red, '<', uvector2(6, y), game); + AddUnitToGame(Player::Red, '<', uvector2(7, y), game); } for ( ucoord_t y : { 0,2,4,6 } ) { - AddUnitToGame(Team::Green, '>', uvector2(0, y), game); - AddUnitToGame(Team::Green, '>', uvector2(1, y), game); + AddUnitToGame(Player::Green, '>', uvector2(0, y), game); + AddUnitToGame(Player::Green, '>', uvector2(1, y), game); } OutputGame(std::move(game)); diff --git a/source/test/test.cpp b/source/test/test.cpp index 4120df7..cdd9469 100644 --- a/source/test/test.cpp +++ b/source/test/test.cpp @@ -36,7 +36,7 @@ const char* tests() { CUnit unit1; unit1.SetFromVisual('v'); - unit1.SetTeam(Team::Green); + unit1.SetPlayer(Player::Green); unit1.SetPos(uvector2(5, 10)); std::string unit1Desc = CUnit::GetStringFromUnit(unit1); @@ -82,7 +82,7 @@ const char* tests() { CUnit unit = CUnit::GetUnitFromVis('^'); unit.SetPos({2, 2}); - unit.SetTeam(Team::Red); + unit.SetPlayer(Player::Red); game.AddUnit(std::move(unit)); } @@ -90,7 +90,7 @@ const char* tests() { CUnit unit = CUnit::GetUnitFromVis('^'); unit.SetPos({2, 2}); - unit.SetTeam(Team::Red); + unit.SetPlayer(Player::Red); if( !game.AddUnit(std::move(unit)) ) return "Game should have rejected unit placed on the same spot"; @@ -109,7 +109,7 @@ const char* tests() SOrder order; unit.SetPos({2, 2}); - unit.SetTeam(Team::Red); + unit.SetPlayer(Player::Red); if ( game.AddUnit(std::move(unit)) ) return "Game failed to add valid unit"; @@ -117,7 +117,7 @@ const char* tests() order.unit = id; order.command = command_c::F; - if( game.IssueOrder(Team::Red,order) ) + if( game.IssueOrder(Player::Red,order) ) return "Game failed to issue valid order"; if (game.SimulateToNextTurn() ) @@ -140,7 +140,7 @@ const char* tests() SOrder order; unit.SetPos({0, 0}); - unit.SetTeam(Team::Blue); + unit.SetPlayer(Player::Blue); if ( game.AddUnit(std::move(unit)) ) return "Game failed to add valid unit"; @@ -148,14 +148,14 @@ const char* tests() order.unit = id; order.command = command_c::A; - if( game.IssueOrder(Team::Blue,order) ) + if( game.IssueOrder(Player::Blue,order) ) return "Game failed to issue valid order"; } { CUnit unit = CUnit::GetUnitFromVis('<'); unit.SetPos({1, 0}); - unit.SetTeam(Team::Red); + unit.SetPlayer(Player::Red); if ( game.AddUnit(std::move(unit)) ) return "Game failed to add valid unit"; @@ -172,8 +172,8 @@ const char* tests() if (game.GetUnitByIndex(0).GetID() != id ) return "Game killed the wrong unit"; - if ( game.CheckForWin() != Team::Blue ) - return "Game failed to recognise a win for the right Team"; + if ( game.CheckForWin() != Player::Blue ) + return "Game failed to recognise a win for the right Player"; std::string game_string = game.GetStateAsString(); CTTRTSGame game2 = CTTRTSGame::CreateFromString(game_string); diff --git a/source/ttrts/README.md b/source/ttrts/README.md index 0bd15c2..1b0f1dc 100644 --- a/source/ttrts/README.md +++ b/source/ttrts/README.md @@ -47,7 +47,7 @@ ## ORDER FILE FORMAT ### Name - Turn_{TURN_NUMBER}_Team_{TEAM_NUMBER}.txt + Player_{TEAM_NUMBER}_Turn_{TURN_NUMBER}.txt ### Contents ORDER:{ORDER_CHAR} id:{UNIT_ID} ... {continue for all orders} diff --git a/source/ttrts/main.cpp b/source/ttrts/main.cpp index 16815f1..68a3b8d 100644 --- a/source/ttrts/main.cpp +++ b/source/ttrts/main.cpp @@ -96,8 +96,8 @@ int main(int argc, char* argv[]) // Create the game CTTRTSGame game = CTTRTSGame::CreateFromString(gameDescriptor); - // Grab the teams involved - auto teams = game.GetTeams(); + // Grab the players involved + auto players = game.GetPlayers(); // Current game directory std::string gameDir = "ttrts_" + game.GetName(); @@ -134,8 +134,8 @@ int main(int argc, char* argv[]) system(cmd1); // While the game hasn't been won - Team winningTeam; - while ( ((winningTeam = game.CheckForWin()) == Team::NUM_INVALID) // We have a winning team + Player winningPlayer; + while ( ((winningPlayer = game.CheckForWin()) == Player::NUM_INVALID) // We have a winning player && game.GetNumUnits() > 0 ) // We have no units left { std::cout<<"Starting turn "<(turnFile)),std::istreambuf_iterator()); // Issue the orders to the game - if( game.IssueOrders(team, orders) ) - std::cerr<<"Warning: Orders for team "<<(int)team<<" failed to correctly parse"< Date: Sun, 21 Dec 2014 11:14:01 +0000 Subject: [PATCH 16/95] Player -> player_t --- source/game/game.cpp | 24 ++++++++++++------------ source/game/game.h | 12 ++++++------ source/game/gametypes.h | 2 +- source/game/unit.cpp | 4 ++-- source/game/unit.h | 8 ++++---- source/gen/gen.cpp | 22 +++++++++++----------- source/test/test.cpp | 18 +++++++++--------- source/ttrts/main.cpp | 8 ++++---- 8 files changed, 49 insertions(+), 49 deletions(-) diff --git a/source/game/game.cpp b/source/game/game.cpp index 04292ca..0e641aa 100644 --- a/source/game/game.cpp +++ b/source/game/game.cpp @@ -30,7 +30,7 @@ CTTRTSGame& CTTRTSGame::operator=(CTTRTSGame&& game) } // Interpret a string of orders -int CTTRTSGame::IssueOrders( Player player, const std::string& _orders ) +int CTTRTSGame::IssueOrders( player_t player, const std::string& _orders ) { COrderVector orderVector; @@ -57,7 +57,7 @@ int CTTRTSGame::IssueOrders( Player player, const std::string& _orders ) } // Issue orders by vector to the game -int CTTRTSGame::IssueOrders( Player player, const COrderVector& orders ) +int CTTRTSGame::IssueOrders( player_t player, const COrderVector& orders ) { // verify all the orders for ( auto order : orders ) @@ -71,7 +71,7 @@ int CTTRTSGame::IssueOrders( Player player, const COrderVector& orders ) } // Issue a single order -int CTTRTSGame::IssueOrder( Player player, const SOrder & order ) +int CTTRTSGame::IssueOrder( player_t player, const SOrder & order ) { // Verify the order if ( VerifyOrder(player,order) ) @@ -366,7 +366,7 @@ int CTTRTSGame::AddUnits( CUnitVector&& units ) } // Verify any order -int CTTRTSGame::VerifyOrder( Player player, const SOrder & order ) const +int CTTRTSGame::VerifyOrder( player_t player, const SOrder & order ) const { int ret = 1; @@ -435,9 +435,9 @@ CUnit& CTTRTSGame::GetUnitByID( unit_id_t id ) } // Get a vector of the players in the current game -std::vector CTTRTSGame::GetPlayers() const +std::vector CTTRTSGame::GetPlayers() const { - std::vector players; + std::vector players; players.reserve(GetNumUnits()); // Grab all players @@ -454,10 +454,10 @@ std::vector CTTRTSGame::GetPlayers() const } // Check if we have a win state -Player CTTRTSGame::CheckForWin() const +player_t CTTRTSGame::CheckForWin() const { // Array of units for each Player - unsigned int units[(int) Player::NUM_INVALID]; + unsigned int units[(int) player_t::NUM_INVALID]; memset(units,0,sizeof(units)); // Count up all the units for each Player @@ -468,21 +468,21 @@ Player CTTRTSGame::CheckForWin() const } // Default winning Player to invalid (no win) - Player winningPlayer = Player::NUM_INVALID; + player_t winningPlayer = player_t::NUM_INVALID; // For each of the players for ( unsigned int i = 0; i < _countof(units); i++ ) { // if there are still units in this Player, and the winning Player hasn't been set - if( units[i] > 0 && winningPlayer == Player::NUM_INVALID ) + if( units[i] > 0 && winningPlayer == player_t::NUM_INVALID ) { - winningPlayer = (Player)i; + winningPlayer = (player_t)i; } // Otherwise, if there are units in this Player and the winning Player HAS been set else if ( units[i] > 0 ) { // Set back to invalid and break out of the loop - winningPlayer = Player::NUM_INVALID; + winningPlayer = player_t::NUM_INVALID; break; } } diff --git a/source/game/game.h b/source/game/game.h index 76451f6..f672e1b 100644 --- a/source/game/game.h +++ b/source/game/game.h @@ -33,15 +33,15 @@ public: // Check for a win, returns invalid for no win state reached // Note: this function will return invalid a draw was reached // best practice would be to call with GetNumUnits() == 0 - Player CheckForWin() const; + player_t CheckForWin() const; // Get the game information as a string std::string GetStateAsString() const; // Issue orders to the game, returns non-zero if orders are incorrect - int IssueOrders( Player player, const std::string& orders ); - int IssueOrders( Player player, const COrderVector& orders ); - int IssueOrder( Player player, const SOrder & order ); + int IssueOrders( player_t player, const std::string& orders ); + int IssueOrders( player_t player, const COrderVector& orders ); + int IssueOrder( player_t player, const SOrder & order ); // Add a units to the game, nonzero return value indicates error int AddUnit( CUnit&& unit ); @@ -71,7 +71,7 @@ public: inline int GetTurn() const { return turn; } // Get a vector of the players in the current game - std::vector GetPlayers() const; + std::vector GetPlayers() const; private: @@ -79,7 +79,7 @@ private: static bool CheckForPassThrough( const CUnit& one, const CUnit& two ); // Verify any order or position - non-zero is error - int VerifyOrder( Player player, const SOrder & order ) const; + int VerifyOrder( player_t player, const SOrder & order ) const; int VerifyPos( uvector2 vec ) const; // Get a units new position after an order diff --git a/source/game/gametypes.h b/source/game/gametypes.h index 23b7aaf..0ee4e5b 100644 --- a/source/game/gametypes.h +++ b/source/game/gametypes.h @@ -4,7 +4,7 @@ #include // std::numeric_limits // Type for a Player IDs -enum class Player : char +enum class player_t : char { Red = 0, Green, diff --git a/source/game/unit.cpp b/source/game/unit.cpp index 166020e..72b7184 100644 --- a/source/game/unit.cpp +++ b/source/game/unit.cpp @@ -88,7 +88,7 @@ CUnit CUnit::GetUnitFromString(const std::string& unit ) &posy ); ret.unit_id = (unit_id_t)id; - ret.player_id = (Player) player; + ret.player_id = (player_t) player; ret.unit_vis = (unitvis_c)vis; ret.dir = (dir_t)dir; ret.pos = uvector2(posx,posy); @@ -99,7 +99,7 @@ CUnit CUnit::GetUnitFromString(const std::string& unit ) // Plain constructor CUnit::CUnit() : unit_id ( get_unique_unit_id() ) -, player_id ( Player::NUM_INVALID ) +, player_id ( player_t::NUM_INVALID ) , unit_vis (unitvis_invalid) , dir ( dir_t::S ) , pos ( { ucoord_invalid, ucoord_invalid } ) diff --git a/source/game/unit.h b/source/game/unit.h index a51ddff..fdbfd1f 100644 --- a/source/game/unit.h +++ b/source/game/unit.h @@ -36,13 +36,13 @@ public: // Getters for all the members inline const unit_id_t& GetID() const { return unit_id; } - inline const Player & GetPlayer() const { return player_id; } + inline const player_t & GetPlayer() const { return player_id; } inline const unitvis_c & GetVisual() const { return unit_vis; } inline const dir_t& GetDir() const { return dir; } inline const uvector2& GetPos() const { return pos; } // Set - inline Player SetPlayer(const Player &v) { return (player_id = v); } + inline player_t SetPlayer(const player_t &v) { return (player_id = v); } inline unitvis_c SetVisual(const unitvis_c &v) { return (unit_vis = v); } inline dir_t SetDir(const dir_t &v) { return (dir = v); } inline void SetPos(const uvector2 &v) { pos = v; } @@ -73,7 +73,7 @@ private: unitvis_c unit_vis; // Player ID - Player player_id; + player_t player_id; // Direction dir_t dir; @@ -90,7 +90,7 @@ typedef std::vector< unit_id_t > CUnitIDVector; inline bool CUnit::Valid() const { return (unit_id != unit_id_invalid ) - && (player_id != Player::NUM_INVALID ) + && (player_id != player_t::NUM_INVALID ) && (unit_vis != unitvis_invalid); } diff --git a/source/gen/gen.cpp b/source/gen/gen.cpp index 9e385ed..ac7ab2e 100644 --- a/source/gen/gen.cpp +++ b/source/gen/gen.cpp @@ -3,7 +3,7 @@ #include #include -void AddUnitToGame( Player player, char vis, uvector2 vec, CTTRTSGame& game ) +void AddUnitToGame( player_t player, char vis, uvector2 vec, CTTRTSGame& game ) { CUnit unit = CUnit::GetUnitFromVis(vis); unit.SetPos(vec); @@ -28,10 +28,10 @@ int main() CTTRTSGame game(6, 6); game.SetName("Tiny2v2"); - AddUnitToGame( Player::Red, '<', uvector2(4, 2), game); - AddUnitToGame( Player::Red, '<', uvector2(4, 4), game); - AddUnitToGame( Player::Green, '>', uvector2(1, 1), game); - AddUnitToGame( Player::Green, '>', uvector2(1, 3), game); + AddUnitToGame( player_t::Red, '<', uvector2(4, 2), game); + AddUnitToGame( player_t::Red, '<', uvector2(4, 4), game); + AddUnitToGame( player_t::Green, '>', uvector2(1, 1), game); + AddUnitToGame( player_t::Green, '>', uvector2(1, 3), game); OutputGame(std::move(game)); } @@ -42,9 +42,9 @@ int main() game.SetName("Big2v2"); for ( ucoord_t y : { 2,4,6,8,10 } ) - AddUnitToGame( Player::Red, '<', uvector2(18, y), game); + AddUnitToGame( player_t::Red, '<', uvector2(18, y), game); for ( ucoord_t y : { 1,3,5,7,9 } ) - AddUnitToGame( Player::Green, '>', uvector2(1, y), game); + AddUnitToGame( player_t::Green, '>', uvector2(1, y), game); OutputGame(std::move(game)); @@ -56,13 +56,13 @@ int main() game.SetName("Chess"); for ( ucoord_t y : { 1,3,5,7 } ) { - AddUnitToGame(Player::Red, '<', uvector2(6, y), game); - AddUnitToGame(Player::Red, '<', uvector2(7, y), game); + AddUnitToGame(player_t::Red, '<', uvector2(6, y), game); + AddUnitToGame(player_t::Red, '<', uvector2(7, y), game); } for ( ucoord_t y : { 0,2,4,6 } ) { - AddUnitToGame(Player::Green, '>', uvector2(0, y), game); - AddUnitToGame(Player::Green, '>', uvector2(1, y), game); + AddUnitToGame(player_t::Green, '>', uvector2(0, y), game); + AddUnitToGame(player_t::Green, '>', uvector2(1, y), game); } OutputGame(std::move(game)); diff --git a/source/test/test.cpp b/source/test/test.cpp index cdd9469..00e5328 100644 --- a/source/test/test.cpp +++ b/source/test/test.cpp @@ -36,7 +36,7 @@ const char* tests() { CUnit unit1; unit1.SetFromVisual('v'); - unit1.SetPlayer(Player::Green); + unit1.SetPlayer(player_t::Green); unit1.SetPos(uvector2(5, 10)); std::string unit1Desc = CUnit::GetStringFromUnit(unit1); @@ -82,7 +82,7 @@ const char* tests() { CUnit unit = CUnit::GetUnitFromVis('^'); unit.SetPos({2, 2}); - unit.SetPlayer(Player::Red); + unit.SetPlayer(player_t::Red); game.AddUnit(std::move(unit)); } @@ -90,7 +90,7 @@ const char* tests() { CUnit unit = CUnit::GetUnitFromVis('^'); unit.SetPos({2, 2}); - unit.SetPlayer(Player::Red); + unit.SetPlayer(player_t::Red); if( !game.AddUnit(std::move(unit)) ) return "Game should have rejected unit placed on the same spot"; @@ -109,7 +109,7 @@ const char* tests() SOrder order; unit.SetPos({2, 2}); - unit.SetPlayer(Player::Red); + unit.SetPlayer(player_t::Red); if ( game.AddUnit(std::move(unit)) ) return "Game failed to add valid unit"; @@ -117,7 +117,7 @@ const char* tests() order.unit = id; order.command = command_c::F; - if( game.IssueOrder(Player::Red,order) ) + if( game.IssueOrder(player_t::Red,order) ) return "Game failed to issue valid order"; if (game.SimulateToNextTurn() ) @@ -140,7 +140,7 @@ const char* tests() SOrder order; unit.SetPos({0, 0}); - unit.SetPlayer(Player::Blue); + unit.SetPlayer(player_t::Blue); if ( game.AddUnit(std::move(unit)) ) return "Game failed to add valid unit"; @@ -148,14 +148,14 @@ const char* tests() order.unit = id; order.command = command_c::A; - if( game.IssueOrder(Player::Blue,order) ) + if( game.IssueOrder(player_t::Blue,order) ) return "Game failed to issue valid order"; } { CUnit unit = CUnit::GetUnitFromVis('<'); unit.SetPos({1, 0}); - unit.SetPlayer(Player::Red); + unit.SetPlayer(player_t::Red); if ( game.AddUnit(std::move(unit)) ) return "Game failed to add valid unit"; @@ -172,7 +172,7 @@ const char* tests() if (game.GetUnitByIndex(0).GetID() != id ) return "Game killed the wrong unit"; - if ( game.CheckForWin() != Player::Blue ) + if ( game.CheckForWin() != player_t::Blue ) return "Game failed to recognise a win for the right Player"; std::string game_string = game.GetStateAsString(); diff --git a/source/ttrts/main.cpp b/source/ttrts/main.cpp index 68a3b8d..db64cea 100644 --- a/source/ttrts/main.cpp +++ b/source/ttrts/main.cpp @@ -134,8 +134,8 @@ int main(int argc, char* argv[]) system(cmd1); // While the game hasn't been won - Player winningPlayer; - while ( ((winningPlayer = game.CheckForWin()) == Player::NUM_INVALID) // We have a winning player + player_t winningPlayer; + while ( ((winningPlayer = game.CheckForWin()) == player_t::NUM_INVALID) // We have a winning player && game.GetNumUnits() > 0 ) // We have no units left { std::cout<<"Starting turn "< Date: Sun, 21 Dec 2014 11:14:20 +0000 Subject: [PATCH 17/95] dir_t -> dir_c --- source/game/game.cpp | 12 +++---- source/game/unit.cpp | 68 ++++++++++++++++++++-------------------- source/game/unit.h | 12 +++---- source/maths/mathtypes.h | 2 +- source/maths/vector2.h | 10 +++--- source/test/test.cpp | 2 +- 6 files changed, 53 insertions(+), 53 deletions(-) diff --git a/source/game/game.cpp b/source/game/game.cpp index 0e641aa..fca3376 100644 --- a/source/game/game.cpp +++ b/source/game/game.cpp @@ -296,26 +296,26 @@ bool CTTRTSGame::CheckForPassThrough( const CUnit& one, const CUnit& two ) { uvector2 pos1 = one.GetPos(); uvector2 pos2 = two.GetPos(); - dir_t dir1 = one.GetDir(); - dir_t dir2 = two.GetDir(); + dir_c dir1 = one.GetDir(); + dir_c dir2 = two.GetDir(); if( pos1.x == pos2.x ) { // Same col if (pos1.y == (pos2.y + 1)) { - if (dir1 == dir_t::N && dir2 == dir_t::S) + if (dir1 == dir_c::N && dir2 == dir_c::S) return true; } else if (pos1.y == (pos2.y - 1)) { - if (dir1 == dir_t::S && dir2 == dir_t::N) + if (dir1 == dir_c::S && dir2 == dir_c::N) return true; } } else if( pos1.y == pos2.y ) { // Same row if( pos1.x == (pos2.x+1) ) { - if( dir1 == dir_t::E && dir2 == dir_t::W ) + if( dir1 == dir_c::E && dir2 == dir_c::W ) return true; } else if( pos1.x == (pos2.x-1) ) { - if( dir1 == dir_t::E && dir2 == dir_t::W ) + if( dir1 == dir_c::E && dir2 == dir_c::W ) return true; } } diff --git a/source/game/unit.cpp b/source/game/unit.cpp index 72b7184..39d9b48 100644 --- a/source/game/unit.cpp +++ b/source/game/unit.cpp @@ -18,17 +18,17 @@ namespace } // Map of visual representation of unit V - typedef std::map< dir_t, unitvis_c> dir_to_vis_map; + typedef std::map dir_to_vis_map; // Helper function to get the vis map during static init const dir_to_vis_map& get_vis_map_V() { static const dir_to_vis_map sk_visMap = { - {dir_t::N,'^'}, - {dir_t::E,'>'}, - {dir_t::S,'v'}, - {dir_t::W,'<'}, + {dir_c::N,'^'}, + {dir_c::E,'>'}, + {dir_c::S,'v'}, + {dir_c::W,'<'}, }; return sk_visMap; @@ -90,7 +90,7 @@ CUnit CUnit::GetUnitFromString(const std::string& unit ) ret.unit_id = (unit_id_t)id; ret.player_id = (player_t) player; ret.unit_vis = (unitvis_c)vis; - ret.dir = (dir_t)dir; + ret.dir = (dir_c)dir; ret.pos = uvector2(posx,posy); return ret; @@ -101,7 +101,7 @@ CUnit::CUnit() : unit_id ( get_unique_unit_id() ) , player_id ( player_t::NUM_INVALID ) , unit_vis (unitvis_invalid) -, dir ( dir_t::S ) +, dir ( dir_c::S ) , pos ( { ucoord_invalid, ucoord_invalid } ) { UpdateMyVisual(); @@ -175,24 +175,24 @@ bool CUnit::SetFromVisual(const unitvis_c &vis) } // Turn unit left -dir_t CUnit::TurnLeft() +dir_c CUnit::TurnLeft() { switch( dir ) { - case dir_t::N: - dir = dir_t::W; + case dir_c::N: + dir = dir_c::W; break; - case dir_t::E: - dir = dir_t::N; + case dir_c::E: + dir = dir_c::N; break; - case dir_t::S: - dir = dir_t::E; + case dir_c::S: + dir = dir_c::E; break; - case dir_t::W: - dir = dir_t::S; + case dir_c::W: + dir = dir_c::S; break; } @@ -202,24 +202,24 @@ dir_t CUnit::TurnLeft() } // Turn unit right -dir_t CUnit::TurnRight() +dir_c CUnit::TurnRight() { switch( dir ) { - case dir_t::N: - dir = dir_t::E; + case dir_c::N: + dir = dir_c::E; break; - case dir_t::E: - dir = dir_t::S; + case dir_c::E: + dir = dir_c::S; break; - case dir_t::S: - dir = dir_t::W; + case dir_c::S: + dir = dir_c::W; break; - case dir_t::W: - dir = dir_t::N; + case dir_c::W: + dir = dir_c::N; break; } @@ -229,24 +229,24 @@ dir_t CUnit::TurnRight() } // Turn unit around -dir_t CUnit::TurnAround() +dir_c CUnit::TurnAround() { switch( dir ) { - case dir_t::N: - dir = dir_t::S; + case dir_c::N: + dir = dir_c::S; break; - case dir_t::E: - dir = dir_t::W; + case dir_c::E: + dir = dir_c::W; break; - case dir_t::S: - dir = dir_t::N; + case dir_c::S: + dir = dir_c::N; break; - case dir_t::W: - dir = dir_t::E; + case dir_c::W: + dir = dir_c::E; break; } diff --git a/source/game/unit.h b/source/game/unit.h index fdbfd1f..982f140 100644 --- a/source/game/unit.h +++ b/source/game/unit.h @@ -38,13 +38,13 @@ public: inline const unit_id_t& GetID() const { return unit_id; } inline const player_t & GetPlayer() const { return player_id; } inline const unitvis_c & GetVisual() const { return unit_vis; } - inline const dir_t& GetDir() const { return dir; } + inline const dir_c & GetDir() const { return dir; } inline const uvector2& GetPos() const { return pos; } // Set inline player_t SetPlayer(const player_t &v) { return (player_id = v); } inline unitvis_c SetVisual(const unitvis_c &v) { return (unit_vis = v); } - inline dir_t SetDir(const dir_t &v) { return (dir = v); } + inline dir_c SetDir(const dir_c &v) { return (dir = v); } inline void SetPos(const uvector2 &v) { pos = v; } // Get the co-ordinate in front of the unit @@ -57,9 +57,9 @@ public: bool SetFromVisual(const unitvis_c &vis); // Orientation methods - dir_t TurnLeft(); - dir_t TurnRight(); - dir_t TurnAround(); + dir_c TurnLeft(); + dir_c TurnRight(); + dir_c TurnAround(); private: @@ -76,7 +76,7 @@ private: player_t player_id; // Direction - dir_t dir; + dir_c dir; // Position uvector2 pos; diff --git a/source/maths/mathtypes.h b/source/maths/mathtypes.h index b7804af..d987e25 100644 --- a/source/maths/mathtypes.h +++ b/source/maths/mathtypes.h @@ -17,7 +17,7 @@ static const coord_t coord_invalid = std::numeric_limits::max(); static const ucoord_t ucoord_invalid = std::numeric_limits::max(); // Direction representation -enum class dir_t : char +enum class dir_c : char { N = 'N', S = 'S', diff --git a/source/maths/vector2.h b/source/maths/vector2.h index ee36d5d..40ce5ad 100644 --- a/source/maths/vector2.h +++ b/source/maths/vector2.h @@ -60,20 +60,20 @@ struct uvector2 inline vector2::operator uvector2() const { return { (ucoord_t)x, (ucoord_t)y }; } -inline vector2 vecFromDir( dir_t dir ) +inline vector2 vecFromDir( dir_c dir ) { switch( dir ) { - case dir_t::N: + case dir_c::N: return { 0,1 }; - case dir_t::E: + case dir_c::E: return { 1,0 }; - case dir_t::S: + case dir_c::S: return { 0,-1 }; - case dir_t::W: + case dir_c::W: return { -1,0 }; default: diff --git a/source/test/test.cpp b/source/test/test.cpp index 00e5328..b4d197c 100644 --- a/source/test/test.cpp +++ b/source/test/test.cpp @@ -166,7 +166,7 @@ const char* tests() if ( game.GetNumUnits() != 1 ) return "Game failed to kill a unit when it logically should have"; - if (game.GetUnitByIndex(0).GetDir() != dir_t::E ) + if (game.GetUnitByIndex(0).GetDir() != dir_c::E ) return "Game killed the wrong unit"; if (game.GetUnitByIndex(0).GetID() != id ) From e90ddee67efd63457a2670ebeb70f04a287a2d1a Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Sun, 21 Dec 2014 11:19:37 +0000 Subject: [PATCH 18/95] Final fixes to indentation. fixes #13 --- source/game/game.h | 8 ++++---- source/game/unit.h | 24 ++++++++++++------------ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/source/game/game.h b/source/game/game.h index f672e1b..99896ea 100644 --- a/source/game/game.h +++ b/source/game/game.h @@ -33,7 +33,7 @@ public: // Check for a win, returns invalid for no win state reached // Note: this function will return invalid a draw was reached // best practice would be to call with GetNumUnits() == 0 - player_t CheckForWin() const; + player_t CheckForWin() const; // Get the game information as a string std::string GetStateAsString() const; @@ -52,11 +52,11 @@ public: // Get unit and orderby index as above (not unit ID) inline const CUnit& GetUnitByIndex( unsigned int i ) const { return m_OrderUnitPairs[i].unit; } - inline const SOrder & GetOrdersByIndex( unsigned int i ) const { return m_OrderUnitPairs[i].order; } + inline const SOrder & GetOrdersByIndex( unsigned int i ) const { return m_OrderUnitPairs[i].order; } // Get a unit by it's ID const CUnit& GetUnitByIDConst( unit_id_t id ) const; - const SOrder & GetOrderByIDConst( unit_id_t id ) const; + const SOrder & GetOrderByIDConst( unit_id_t id ) const; // Get dimensions inline const uvector2& GetDimensions() const { return dimensions; } @@ -71,7 +71,7 @@ public: inline int GetTurn() const { return turn; } // Get a vector of the players in the current game - std::vector GetPlayers() const; + std::vector GetPlayers() const; private: diff --git a/source/game/unit.h b/source/game/unit.h index 982f140..ce9295f 100644 --- a/source/game/unit.h +++ b/source/game/unit.h @@ -38,13 +38,13 @@ public: inline const unit_id_t& GetID() const { return unit_id; } inline const player_t & GetPlayer() const { return player_id; } inline const unitvis_c & GetVisual() const { return unit_vis; } - inline const dir_c & GetDir() const { return dir; } + inline const dir_c & GetDir() const { return dir; } inline const uvector2& GetPos() const { return pos; } // Set - inline player_t SetPlayer(const player_t &v) { return (player_id = v); } + inline player_t SetPlayer(const player_t &v) { return (player_id = v); } inline unitvis_c SetVisual(const unitvis_c &v) { return (unit_vis = v); } - inline dir_c SetDir(const dir_c &v) { return (dir = v); } + inline dir_c SetDir(const dir_c &v) { return (dir = v); } inline void SetPos(const uvector2 &v) { pos = v; } // Get the co-ordinate in front of the unit @@ -57,29 +57,29 @@ public: bool SetFromVisual(const unitvis_c &vis); // Orientation methods - dir_c TurnLeft(); - dir_c TurnRight(); - dir_c TurnAround(); + dir_c TurnLeft(); + dir_c TurnRight(); + dir_c TurnAround(); private: // Update my visual must be called when setting direction - unitvis_c UpdateMyVisual(); + unitvis_c UpdateMyVisual(); // Unit ID - unit_id_t unit_id; + unit_id_t unit_id; // Visual - unitvis_c unit_vis; + unitvis_c unit_vis; // Player ID - player_t player_id; + player_t player_id; // Direction - dir_c dir; + dir_c dir; // Position - uvector2 pos; + uvector2 pos; }; // Typedef for a vector of units From 024253bb84b52d816c4e0447d6595b5053b5db9f Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Mon, 22 Dec 2014 19:55:23 +0000 Subject: [PATCH 19/95] Fix usage text to reflect new formatters --- source/ttrts/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source/ttrts/README.md b/source/ttrts/README.md index 1b0f1dc..ae97b36 100644 --- a/source/ttrts/README.md +++ b/source/ttrts/README.md @@ -41,13 +41,13 @@ TURN:{TURN_NUMBER} ... {any extra properties could go here} ~~~~ - UNIT:{ID} tm:{TEAM} vs:{VIS} dr:{DIR(NESW)} ps:[{X},{Y}] + UNIT:{ID} pl:{PLAYER} vs:{VIS} dr:{DIR(NESW)} ps:[{X},{Y}] ... {continue for all units} END ## ORDER FILE FORMAT ### Name - Player_{TEAM_NUMBER}_Turn_{TURN_NUMBER}.txt + Player_{PLAYER_ID}_Turn_{TURN_NUMBER}.txt ### Contents ORDER:{ORDER_CHAR} id:{UNIT_ID} ... {continue for all orders} @@ -56,4 +56,5 @@ ### Orders F - move unit [F]orward one space L/R - rotate unit [L]eft or [R]ight - A - [A]ttack in straight line in front of unit \ No newline at end of file + A - [A]ttack in straight line in front of unit + \ No newline at end of file From 5d07bb03f39e25ee488092cffd832912cda1f88f Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Mon, 22 Dec 2014 20:03:18 +0000 Subject: [PATCH 20/95] Correct using player for turn and turn for player --- source/ttrts/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ttrts/main.cpp b/source/ttrts/main.cpp index db64cea..91fbf1b 100644 --- a/source/ttrts/main.cpp +++ b/source/ttrts/main.cpp @@ -152,7 +152,7 @@ int main(int argc, char* argv[]) { // Construct the player order filename char playerOrderFileName[128]; - snprintf(playerOrderFileName, 128, "%s/Player_%i_Turn_%i.txt", gameDir.c_str(), game.GetTurn(), (int) player); + snprintf(playerOrderFileName, 128, "%s/Player_%i_Turn_%i.txt", gameDir.c_str(), (int) player, game.GetTurn()); // Wait for the player order file to be created std::cout<<"Waiting for "<< playerOrderFileName < Date: Mon, 22 Dec 2014 20:03:31 +0000 Subject: [PATCH 21/95] Update using player instead of team and matching new file formats --- ttrts.pm | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/ttrts.pm b/ttrts.pm index eb588ba..3cf0820 100644 --- a/ttrts.pm +++ b/ttrts.pm @@ -8,7 +8,7 @@ our $ttrts_perlai_versioncompat_minor = 1; # Get information about a unit from it's descriptor sub getUnit { - return ($_[0] =~ /UNIT:(\d+) tm:(\d+) vs:([^ ]+) dr:([^ ]+) ps:\[(\d+),(\d+)\]/); + return ($_[0] =~ /UNIT:(\d+) pl:(\d+) vs:([^ ]+) dr:([^ ]+) ps:\[(\d+),(\d+)\]/); } # Get the units from a turn file @@ -84,17 +84,17 @@ sub GetHeaderForTurn return ($gameName,$gameX,$gameY); } -# Get units from a specific team -sub getUnitsOnTeam +# Get units from a specific player +sub getUnitsOnPlayer { - my $theTeam = shift; + my $thePlayer = shift; my @allUnits = @_; my @myUnits; for my $unit (@allUnits) { - my ($unitTeam) = $unit =~ /tm:(\d+)/; - if ( $unitTeam == $theTeam ) + my ($unitplayer) = $unit =~ /pl:(\d+)/; + if ( $unitplayer == $thePlayer ) { push(@myUnits,$unit); } @@ -114,10 +114,10 @@ sub GetTurnFile sub GetCommandFile { my $turn = shift; - my $team = shift; - my $cmdFileName = "Turn_TURN_Team_TEAM.txt"; + my $player = shift; + my $cmdFileName = "Player_PLAYER_Turn_TURN.txt"; $cmdFileName =~ s/TURN/$turn/; - $cmdFileName =~ s/TEAM/$team/; + $cmdFileName =~ s/PLAYER/$player/; return $cmdFileName; } @@ -125,11 +125,11 @@ sub GetCommandFile sub OutputCommandsFile { my $turn = shift; - my $team = shift; + my $player = shift; my $commands = shift; # Get output file - our $cmdFileName = GetCommandFile($turn,$team); + our $cmdFileName = GetCommandFile($turn,$player); if (! -e $cmdFileName) { @@ -172,10 +172,10 @@ sub PrintGameMap # Fill with units for my $unit (@units) { - my ($id,$tm,$vs,$dr,$psx,$psy) = getUnit($unit); + my ($id,$pl,$vs,$dr,$psx,$psy) = getUnit($unit); - $tm += 31; - $vs = "\e[".$tm."m".$vs."\e[0m"; + $pl += 31; + $vs = "\e[".$pl."m".$vs."\e[0m"; $map[$psx][$psy] = $vs; } From f9ee646c93ba3d03f00065f24ee39c93163cda23 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Mon, 22 Dec 2014 20:05:30 +0000 Subject: [PATCH 22/95] Update to be compatible with 0.2 --- ttrts.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ttrts.pm b/ttrts.pm index 3cf0820..8acdf17 100644 --- a/ttrts.pm +++ b/ttrts.pm @@ -3,7 +3,7 @@ use strict; use warnings; our $ttrts_perlai_versioncompat_major = 0; -our $ttrts_perlai_versioncompat_minor = 1; +our $ttrts_perlai_versioncompat_minor = 2; # Get information about a unit from it's descriptor sub getUnit From 78bc326b8d1a4651627766aa38133bbcf65eeec6 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Mon, 22 Dec 2014 20:05:49 +0000 Subject: [PATCH 23/95] Update to minor version 2 The file format and name has changed in the following ways: All team references are now player, so tm: -> pl. Order file format is now Player_#_Turn_#.txt. --- README.md | 2 +- source/CMakeLists.txt | 2 +- source/ttrts/README.md | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index be67d0d..db1e409 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# TTRTS v0.1.0 +# TTRTS v0.2.0 *The Tiny Terminal RTS where the players write their AIs* diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 7891d29..f22f656 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required( VERSION 2.8.7 ) # Set version information set( TTRTS_VERSION_MAJOR 0 ) -set( TTRTS_VERSION_MINOR 1 ) +set( TTRTS_VERSION_MINOR 2 ) set( TTRTS_VERSION_PATCH 0 ) # Use c++1y (14) diff --git a/source/ttrts/README.md b/source/ttrts/README.md index ae97b36..11e135f 100644 --- a/source/ttrts/README.md +++ b/source/ttrts/README.md @@ -1,5 +1,5 @@ ## NAME - ttrts - Tiny Terminal RTS v0.1.0 + ttrts - Tiny Terminal RTS v0.2.0 ## SYNOPSYS ttrts MAPFILE @@ -57,4 +57,3 @@ F - move unit [F]orward one space L/R - rotate unit [L]eft or [R]ight A - [A]ttack in straight line in front of unit - \ No newline at end of file From 5737ae31be0d1ed42eba8e45270e931d3c72346e Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Mon, 29 Dec 2014 21:52:25 +0000 Subject: [PATCH 24/95] Some small cleanup and refactoring. Update name of a few functions to best suit their usage. Split up checking for winning player and checking for game over state. --- source/game/game.cpp | 8 ++++---- source/game/game.h | 16 +++++++++++----- source/test/test.cpp | 2 +- source/ttrts/main.cpp | 9 +++++---- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/source/game/game.cpp b/source/game/game.cpp index fca3376..45c2646 100644 --- a/source/game/game.cpp +++ b/source/game/game.cpp @@ -92,7 +92,7 @@ int CTTRTSGame::IssueOrder( player_t player, const SOrder & order ) } // Verify a position -int CTTRTSGame::VerifyPos(uvector2 vec) const +int CTTRTSGame::VerifyPosIsValidMovement(uvector2 vec) const { // Simply check if within the bounds of our dimensions for now if ( ( vec.x >= dimensions.x ) @@ -137,7 +137,7 @@ int CTTRTSGame::SimulateToNextTurn() uvector2 newpos = GetNewPosition(pair); // Verify the position is even available - bool possible = ( VerifyPos(newpos) == 0 ); + bool possible = (VerifyPosIsValidMovement(newpos) == 0 ); if ( possible ) { @@ -202,7 +202,7 @@ int CTTRTSGame::SimulateToNextTurn() { uvector2 newpos = pair.unit.GetInFront(); // If move would be within the arena - if ( ( newpos.x <= dimensions.x-1 ) && ( newpos.y <= dimensions.y-1 ) ) + if (VerifyPosIsValidMovement(newpos) == 0 ) { pair.unit.SetPos(newpos); @@ -454,7 +454,7 @@ std::vector CTTRTSGame::GetPlayers() const } // Check if we have a win state -player_t CTTRTSGame::CheckForWin() const +player_t CTTRTSGame::GetWinningPlayer() const { // Array of units for each Player unsigned int units[(int) player_t::NUM_INVALID]; diff --git a/source/game/game.h b/source/game/game.h index 99896ea..061ccc5 100644 --- a/source/game/game.h +++ b/source/game/game.h @@ -30,10 +30,16 @@ public: // Returns non-zero if simulation failed int SimulateToNextTurn(); - // Check for a win, returns invalid for no win state reached - // Note: this function will return invalid a draw was reached - // best practice would be to call with GetNumUnits() == 0 - player_t CheckForWin() const; + // Check for winning player, returns invalid for no win state reached + // Note: this function will return invalid if a draw was reached + // do not rely on this to test for end state + player_t GetWinningPlayer() const; + + // Check if the game is over + bool GameOver() const; + + // Check if any of the units can move + bool UnitsCanMove() const; // Get the game information as a string std::string GetStateAsString() const; @@ -80,7 +86,7 @@ private: // Verify any order or position - non-zero is error int VerifyOrder( player_t player, const SOrder & order ) const; - int VerifyPos( uvector2 vec ) const; + int VerifyPosIsValidMovement(uvector2 vec) const; // Get a units new position after an order uvector2 GetNewPosition( const SOrderUnitPair & pair ) const; diff --git a/source/test/test.cpp b/source/test/test.cpp index b4d197c..60d9028 100644 --- a/source/test/test.cpp +++ b/source/test/test.cpp @@ -172,7 +172,7 @@ const char* tests() if (game.GetUnitByIndex(0).GetID() != id ) return "Game killed the wrong unit"; - if ( game.CheckForWin() != player_t::Blue ) + if ( game.GetWinningPlayer() != player_t::Blue ) return "Game failed to recognise a win for the right Player"; std::string game_string = game.GetStateAsString(); diff --git a/source/ttrts/main.cpp b/source/ttrts/main.cpp index 91fbf1b..c17fffb 100644 --- a/source/ttrts/main.cpp +++ b/source/ttrts/main.cpp @@ -133,10 +133,8 @@ int main(int argc, char* argv[]) snprintf(cmd1,128, "rm -rf %s/*",gameDir.c_str()); system(cmd1); - // While the game hasn't been won - player_t winningPlayer; - while ( ((winningPlayer = game.CheckForWin()) == player_t::NUM_INVALID) // We have a winning player - && game.GetNumUnits() > 0 ) // We have no units left + // While the game isn't finished + while ( ! game.GameOver() ) { std::cout<<"Starting turn "< Date: Mon, 29 Dec 2014 21:54:34 +0000 Subject: [PATCH 25/95] Output usage with cout not cerr --- source/ttrts/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ttrts/main.cpp b/source/ttrts/main.cpp index c17fffb..272abef 100644 --- a/source/ttrts/main.cpp +++ b/source/ttrts/main.cpp @@ -61,7 +61,7 @@ int main(int argc, char* argv[]) // If no args, print usage if ( argc == 1 ) { - std::cerr< Date: Mon, 29 Dec 2014 21:55:32 +0000 Subject: [PATCH 26/95] Implement invalid unit positions --- source/game/game.cpp | 119 ++++++++++++++++++++++++++++++++++++---- source/game/game.h | 10 +++- source/game/gametypes.h | 7 +++ source/game/unit.h | 2 - 4 files changed, 122 insertions(+), 16 deletions(-) diff --git a/source/game/game.cpp b/source/game/game.cpp index 45c2646..818225f 100644 --- a/source/game/game.cpp +++ b/source/game/game.cpp @@ -101,6 +101,15 @@ int CTTRTSGame::VerifyPosIsValidMovement(uvector2 vec) const return 1; } + // Check within our invalid positions + for ( const uvector2& invalid : m_InvalidPositions ) + { + if( vec == invalid ) + { + return 2; + } + } + return 0; } @@ -158,6 +167,8 @@ int CTTRTSGame::SimulateToNextTurn() // If the movement is still possible if ( possible ) { + // Push back the old position to our invalid positions list + AddInvalidPosition(pair.unit.GetPos()); pair.unit.SetPos(newpos); } } @@ -493,9 +504,30 @@ player_t CTTRTSGame::GetWinningPlayer() const // Get the game information as a string std::string CTTRTSGame::GetStateAsString() const { + // Grab the invalid positions + std::string invalid_positions; + if( m_InvalidPositions.size() == 0 ) + { + invalid_positions = "NONE"; + } + + for ( auto invalid_pos : m_InvalidPositions ) + { + char pos[16]; + if( snprintf(pos, 16, GAME_POS_FORMATTER , invalid_pos.x, invalid_pos.y ) < 0 ) + { + return "BUFFER OVERFLOW"; + } + invalid_positions += pos; + } + + // Print out the header - char header[64]; - snprintf(header, 512, GAME_HEADER_FORMATTER , name.c_str(), dimensions.x, dimensions.y, turn ); + char header[512]; + if ( snprintf(header, 512, GAME_HEADER_FORMATTER , name.c_str(), dimensions.x, dimensions.y, turn, invalid_positions.c_str() ) < 0 ) + { + return "BUFFER OVERFLOW"; + } // Gather unit information std::string units; @@ -514,7 +546,6 @@ std::string CTTRTSGame::GetStateAsString() const return state; } - // Get the game information as a string CTTRTSGame CTTRTSGame::CreateFromString( const std::string& input ) { @@ -524,24 +555,90 @@ CTTRTSGame CTTRTSGame::CreateFromString( const std::string& input ) std::string units = input.substr(headerEnd + strlen(GAME_HEADER_DELIMITER)); // Grab information from the header - char buf[64]; + char name[64]; unsigned int turn; unsigned int sizex; unsigned int sizey; - sscanf(header.c_str(), GAME_HEADER_FORMATTER, buf, &sizex, &sizey, &turn ); + char invalid_positions[512]; + if( sscanf(header.c_str(), GAME_HEADER_FORMATTER, name, &sizex, &sizey, &turn, invalid_positions ) != 5 ) + { + return CTTRTSGame(0,0); + } + + std::vector invalid_pos_vector; + { + std::string invalid_positions_str = invalid_positions; + size_t pos; + while ( ( pos = invalid_positions_str.find(']') ) != std::string::npos ) + { + std::string pos_string = invalid_positions_str.substr(1,pos); + + // Use scanf to extract positions + + unsigned int x; + unsigned int y; + if( sscanf(pos_string.c_str(), GAME_POS_FORMATTER, &x, &y ) != 2 ) + { + return CTTRTSGame(0,0); + } + + uvector2 inv_pos(x,y); + + // Erase this coordinate + invalid_positions_str.erase(0,pos+1); + + // Append our list + invalid_pos_vector.push_back(inv_pos); + } + } CTTRTSGame game(sizex,sizey); - game.SetName(buf); + game.SetName(name); game.SetTurn(turn); // For each line, construct a unit - size_t pos; - while ( ( pos = units.find('\n') ) != std::string::npos ) { - std::string unit_string = units.substr(0,pos); - units.erase(0,pos+1); - game.AddUnit(CUnit::GetUnitFromString(unit_string)); + size_t pos; + while ((pos = units.find('\n')) != std::string::npos) { + std::string unit_string = units.substr(0, pos); + units.erase(0, pos + 1); + game.AddUnit(CUnit::GetUnitFromString(unit_string)); + } + } + + // Add all invalid positions + for ( auto inv : invalid_pos_vector ) + { + game.AddInvalidPosition(inv); } return game; +} + +// Check if any of the units can move +bool CTTRTSGame::UnitsCanMove() const +{ + for( const SOrderUnitPair& pair: m_OrderUnitPairs ) + { + uvector2 pos = pair.unit.GetPos(); + + // Assume if unit is adjacent to any valid tile, then it can move there + if( VerifyPosIsValidMovement(pos + vector2(1, 0) ) == 0 + || VerifyPosIsValidMovement(pos + vector2(0, 1)) == 0 + || VerifyPosIsValidMovement(pos + vector2(-1, 0)) == 0 + || VerifyPosIsValidMovement(pos + vector2(0, -1)) == 0 ) + { + return true; + } + } + + return false; +} + +// Check if the game is over +bool CTTRTSGame::GameOver() const +{ + return ( (GetWinningPlayer() != player_t::NUM_INVALID ) // We have a winning player + || GetNumUnits() == 0 + || !UnitsCanMove() ); // OR we have no units } \ No newline at end of file diff --git a/source/game/game.h b/source/game/game.h index 061ccc5..c3eeca4 100644 --- a/source/game/game.h +++ b/source/game/game.h @@ -6,9 +6,6 @@ #include "order.h" #include "orderunitpair.h" -#define GAME_HEADER_FORMATTER "NAME:%s\nSIZE:[%u,%u]\nTURN:%u" -#define GAME_HEADER_DELIMITER "~~~~\n" - // Full TTRTS Game class // Stores information about the game // Can convert from a string or to a string @@ -79,6 +76,12 @@ public: // Get a vector of the players in the current game std::vector GetPlayers() const; + // Get the vector of current invalid positions + inline std::vector GetInvalidPositions() const { return m_InvalidPositions; } + + // Add an invalid position + inline void AddInvalidPosition( uvector2 vec ) { m_InvalidPositions.push_back(vec); } + private: // Check for a pass through @@ -101,6 +104,7 @@ private: unsigned int turn; // Int to store the current turn uvector2 dimensions; // Dimensions of the game OrderUnitPairVector m_OrderUnitPairs; // Vector to store all units and orders + std::vector m_InvalidPositions; // Vector of invalidated positions }; diff --git a/source/game/gametypes.h b/source/game/gametypes.h index 0ee4e5b..e86ebf3 100644 --- a/source/game/gametypes.h +++ b/source/game/gametypes.h @@ -3,6 +3,13 @@ #include // std::numeric_limits +#define GAME_POS_FORMATTER "[%u,%u]" + +#define GAME_HEADER_FORMATTER "NAME:%s\nSIZE:" GAME_POS_FORMATTER "\nTURN:%u\nWALL:%s" +#define GAME_HEADER_DELIMITER "~~~~\n" + +#define UNIT_FORMATTER "UNIT:%u pl:%u vs:%c dr:%c ps:" GAME_POS_FORMATTER + // Type for a Player IDs enum class player_t : char { diff --git a/source/game/unit.h b/source/game/unit.h index ce9295f..b594836 100644 --- a/source/game/unit.h +++ b/source/game/unit.h @@ -7,8 +7,6 @@ #include "gametypes.h" #include "vector2.h" -#define UNIT_FORMATTER "UNIT:%u pl:%u vs:%c dr:%c ps:[%u,%u]" - // force a reset of the unit ID value void __forceResetCUnitID(); From fc62785768a9b3a039df1d1db97523360bdbd4b4 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Mon, 29 Dec 2014 21:57:14 +0000 Subject: [PATCH 27/95] update to v0.3.0 to account for new format and features In this case, new WALLs to take into account for the game --- README.md | 3 +-- source/CMakeLists.txt | 2 +- source/ttrts/README.md | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 3b3d8ee..a1abd86 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -# TTRTS v0.2.0 - +# TTRTS v0.3.0 *The Tiny Terminal RTS where the players write their AIs* ----------------------------------------------------------- diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index f22f656..1f5def4 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required( VERSION 2.8.7 ) # Set version information set( TTRTS_VERSION_MAJOR 0 ) -set( TTRTS_VERSION_MINOR 2 ) +set( TTRTS_VERSION_MINOR 3 ) set( TTRTS_VERSION_PATCH 0 ) # Use c++1y (14) diff --git a/source/ttrts/README.md b/source/ttrts/README.md index 11e135f..4805313 100644 --- a/source/ttrts/README.md +++ b/source/ttrts/README.md @@ -1,5 +1,4 @@ -## NAME - ttrts - Tiny Terminal RTS v0.2.0 +# ttrts - Tiny Terminal RTS v0.3.0 ## SYNOPSYS ttrts MAPFILE From 286cc81f3cee868e173bdd45e6ac7b2cd920c66a Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Mon, 29 Dec 2014 21:57:52 +0000 Subject: [PATCH 28/95] Update README files with new changes. Also add changelog to top level readme --- README.md | 36 +++++++++++++-- source/game/README.md | 17 ------- source/ttrts/README.md | 100 +++++++++++++++++++++++++++++------------ 3 files changed, 105 insertions(+), 48 deletions(-) delete mode 100644 source/game/README.md diff --git a/README.md b/README.md index a1abd86..57ba61f 100644 --- a/README.md +++ b/README.md @@ -19,10 +19,40 @@ TTRTS is from the ground up designed to be a fun way to practice programming. An $ cd ttrts $ ./bootstrap.sh $ ./ttrts # To launch binary and display usage - + +----------------------------------------------------------- +## Development + +* [master](master) branch always stores latest stable release +* master/{hotfix} branches store in progress hotfixes for the stable branch +* [dev](dev) branch stores in progress development +* dev/{feature} branches store features + +----------------------------------------------------------- +## Changelog + +## v0.3.0 +* Additional functionality of walls + * Walls are noted in gamestate file on new "WALL:[X,Y]..." line + * Walls are impassable by all movement +* Units leave an impassable wall behind after movement a la +* Game can now end if no units are able to move +* Various C++ api simplifications +* ttrts now integrates +* Integration of perl api from [ttrts-players](https://github.com/mdiluz/ttrts-players) + +## v0.2.0 +* All team references changed to player + * Order file format changed to Player_#_Turn_#.txt + * Unit descriptors now use pl: instead of tm: +* Various other C++ api corrections and refactors + +## v0.1.0 +* First playable version of ttrts + ----------------------------------------------------------- ## Further Information -See [the ttrts binary readme](source/ttrts/README.md) for full usage and game rules +See the ttrts binary [readme](source/ttrts/README.md) for full usage and game rules -See [my ttrts-players repository](https://github.com/mdiluz/ttrts-players) for examples of players +See [ttrts-players](https://github.com/mdiluz/ttrts-players) for examples of AIs diff --git a/source/game/README.md b/source/game/README.md deleted file mode 100644 index 4b61793..0000000 --- a/source/game/README.md +++ /dev/null @@ -1,17 +0,0 @@ -TTRTS Gameplay -================= - -The game takes place in a series of simultaneous turns on an arbitrarily sized 2D board. - -Each player is in control of a set number of starting units, and each turn receives data on the status of the board. - -Each player must then issue a command to each unit in their control. - -All commands are evaluated simultaniously. - -All attempted movement to the same square by two or more units will fail. - -Friendly fire is enabled by default. - -A player wins when all opposing units have been destroyed. - diff --git a/source/ttrts/README.md b/source/ttrts/README.md index 4805313..478fa65 100644 --- a/source/ttrts/README.md +++ b/source/ttrts/README.md @@ -1,58 +1,102 @@ # ttrts - Tiny Terminal RTS v0.3.0 -## SYNOPSYS +## SYNOPSIS ttrts MAPFILE ## DESCRIPTION ttrts is a tiny terminal based RTS where that uses text - files as order lists to control it's units. + files as order lists to control it's units This means that any user, program or cat that can read - and write to text files can play the game. - -## USAGE - When invoked, ttrts will set up a full game and output a - single file representing the current gamestate into a - local directory called `ttrts_{GAME_NAME}`. - - This file can be read in and interpretted by human, robot - or cat. ttrts will wait for orders files to be placed in - it's current working directory. - - Once orders have been set for each player taking part - ttrts will calculate the new game state and output a new - gamestate file for the next turn. - - This process repeats until a winner is chosen! + and write to text files can play the game ## OPTIONS MAPFILE - File to read in the initial game state from --------------------------------------------------------------- +## USAGE + When invoked, ttrts will set up the game in a local + directory called `ttrts_{GAME_NAME}` -## GAMESTATE FILE FORMAT -### Name + The GAMESTATE 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 + +----------------------------------------------------------- +# TTRTS GAMEPLAY + +## RULES + 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. + +----------------------------------------------------------- +# FILE FORMATS + +## Gamestate File Turn_{TURN_NUMBER}.txt + ### Contents ===== ttrts v{MAJOR}.{MINOR}.{PATCH} ===== NAME:{GAMENAME} SIZE:[{X},{Y}] TURN:{TURN_NUMBER} - ... {any extra properties could go here} + 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 FORMAT -### Name +## Order File Player_{PLAYER_ID}_Turn_{TURN_NUMBER}.txt + ### Contents ORDER:{ORDER_CHAR} id:{UNIT_ID} ... {continue for all orders} END -### Orders - F - move unit [F]orward one space - L/R - rotate unit [L]eft or [R]ight - A - [A]ttack in straight line in front of unit From b50c838f2896014a4f23f7dbc00916ce92dd54e3 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Mon, 29 Dec 2014 21:59:59 +0000 Subject: [PATCH 29/95] Large refactor and addition of new features in line with 0.3.0 --- ttrts.pm | 223 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 159 insertions(+), 64 deletions(-) diff --git a/ttrts.pm b/ttrts.pm index 8acdf17..6dc279e 100644 --- a/ttrts.pm +++ b/ttrts.pm @@ -3,50 +3,97 @@ use strict; use warnings; our $ttrts_perlai_versioncompat_major = 0; -our $ttrts_perlai_versioncompat_minor = 2; +our $ttrts_perlai_versioncompat_minor = 3; -# Get information about a unit from it's descriptor -sub getUnit +our $headerDelimiter="~~~~"; + +our $VERBOSE = $ENV{"VERBOSE"}; + +# Format of the a gamestate header +our $headerFormatter = qr/==== ttrts v(\d+)\.(\d+)\.(\d+)+ ==== +NAME:(.+) +SIZE:\[(\d+),(\d+)\] +TURN:(\d+) +(WALL:.*?) +$headerDelimiter/; + +# Formatter for coords +our $coordFormatter = qr/\[\d+,\d+\]/; + +# Format of a unit descriptor +our $unitFormatterNonCapture = qr/UNIT:\d+ pl:\d+ vs:[^ ]+ dr:[^ ]+ ps:\[\d+,\d+\]\n?/; + +# Format of a unit descriptor +our $unitFormatter = qr/UNIT:(\d+) pl:(\d+) vs:([^ ]+) dr:([^ ]+) ps:\[(\d+),(\d+)\]\n?/; + +# Get x and y +sub getPositionsXandYString { - return ($_[0] =~ /UNIT:(\d+) pl:(\d+) vs:([^ ]+) dr:([^ ]+) ps:\[(\d+),(\d+)\]/); + return (shift =~ /\[(\d+),(\d+)\]/); } -# Get the units from a turn file -sub GetUnitsForTurn +# Get all positions +sub getPositionStringsFromLine { - my $turnFile = shift; + return (shift =~ /$coordFormatter/gm ); +} - # Open the turn file - open (my $TURNHANDLE, '<', $turnFile) or die "Could not open '$turnFile' $!"; - - # Skip the header information - my $num = 0; - while( !( <$TURNHANDLE> =~ /~~~~/ ) ) - { - $num++; - $num > 20 and die "gamestate file did not reach ~~~~ line within 10 lines"; - } +# Get information about a unit from it's descriptor +sub getUnitInfo +{ + return (shift =~ /$unitFormatter/); +} - my @units; - while( my $unitLine = <$TURNHANDLE> ) +# Get set of units from a string +sub GetUnitStringsFromGamestate +{ + my $gamestate = shift; + + my @units = ( $gamestate =~ /$unitFormatterNonCapture/gm ); + + foreach my $unit (@units) { - chomp $unitLine; - if( !($unitLine eq "END") ) - { - push(@units,$unitLine); - } + chomp($unit); } - close $TURNHANDLE; - return @units; } +# in the format $major,$minor,$patch,$name,$sizex,$sizey,$turn,$invalidpositions+ +sub GetGameInfoFromGamestate +{ + my $header = shift; + (! defined $header) and die "GetGameInfoFromGamestate was not passed valid header parameter"; + + my @info = ($header =~ /$headerFormatter/ ); + + return @info; +} + +# Get the units from a turn file +sub GetUnitStringsFromFile +{ + my $turnFile = shift or die "GetUnitStringsFromFile needs file parameter"; + + # Read in the whole file method from http://www.perlmonks.org/?node_id=1952 + my $text; + { + local $/=undef; + open FILE, $turnFile or die "Couldn't open file: $!"; + $text = ; + close FILE; + } + + return GetUnitStringsFromGamestate($text); +} + # Check version numbers against ttrts.pm version -sub checkVersion +sub verifyVersion { my $version_major = shift; + (! defined $version_major) and die "verifyVersion needs version_major parameter"; my $version_minor = shift; + (! defined $version_minor) and die "verifyVersion needs version_minor parameter"; if( ($version_major != $ttrts_perlai_versioncompat_major) or ($version_minor != $ttrts_perlai_versioncompat_minor) ) { @@ -55,40 +102,34 @@ sub checkVersion } } + # Get information from the header for this turn -sub GetHeaderForTurn +sub GetGameInfoFromFile { - my $turnFile = shift; + my $turnFile = shift or die "GetGameInfoFromFile needs turnFile parameter"; - # Open the turn file - open (my $TURNHANDLE, '<', $turnFile) or die "Could not open '$turnFile' $!"; - - # Pull in the header information - my $headerLine = <$TURNHANDLE>; - chomp $headerLine; - my $nameLine = <$TURNHANDLE>; - chomp $nameLine; - my $sizeLine = <$TURNHANDLE>; - chomp $sizeLine; - my $turnLine = <$TURNHANDLE>; - chomp $turnLine; + # Read in the whole file method from http://www.perlmonks.org/?node_id=1952 + my $text; + { + local $/=undef; + open FILE, $turnFile or die "Couldn't open file: $!"; + $text = ; + close FILE; + } - my ($version_major,$version_minor) = ( $headerLine =~ /==== ttrts v(\d+)\.(\d+)\.\d+ ====/ ); - checkVersion $version_major,$version_minor; + my @info = GetGameInfoFromGamestate($text); + verifyVersion @info; - my ($gameName) = ( $nameLine =~ /NAME:(.+)/ ); - my ($gameX,$gameY) = ( $sizeLine =~ /SIZE:\[(\d+),(\d+)\]/ ); - - close $TURNHANDLE; - - return ($gameName,$gameX,$gameY); + return @info; } # Get units from a specific player -sub getUnitsOnPlayer +sub GetPlayerUnits { my $thePlayer = shift; + (! defined $thePlayer) and die "GetPlayerUnits needs player parameter"; my @allUnits = @_; + (! @allUnits) and die "GetPlayerUnits needs units parameters"; my @myUnits; for my $unit (@allUnits) @@ -103,18 +144,21 @@ sub getUnitsOnPlayer return @myUnits; } -sub GetTurnFile +sub GetTurnFileName { my $turn = shift; + (! defined $turn) and die "GetTurnFileName needs turn parameter"; my $turnFile = "Turn_TURN.txt"; $turnFile =~ s/TURN/$turn/; return $turnFile; } -sub GetCommandFile +sub GetCommandFileName { my $turn = shift; + (! defined $turn) and die "GetCommandFileName needs turn parameter"; my $player = shift; + (! defined $player) and die "GetCommandFileName needs player parameter"; my $cmdFileName = "Player_PLAYER_Turn_TURN.txt"; $cmdFileName =~ s/TURN/$turn/; $cmdFileName =~ s/PLAYER/$player/; @@ -125,11 +169,13 @@ sub GetCommandFile sub OutputCommandsFile { my $turn = shift; + (! defined $turn) and die "OutputCommandsFile needs turn parameter"; my $player = shift; - my $commands = shift; + (! defined $player) and die "OutputCommandsFile needs player parameter"; + my $commands = shift or die "OutputCommandsFile needs commands parameter"; # Get output file - our $cmdFileName = GetCommandFile($turn,$player); + our $cmdFileName = GetCommandFileName($turn,$player); if (! -e $cmdFileName) { @@ -138,25 +184,41 @@ sub OutputCommandsFile print $cmdFile "END"; close $cmdFile; - printf "Outputted $cmdFileName\n"; + $VERBOSE and printf "Outputted $cmdFileName\n"; printf "$commands"; } else { - open(my $cmdFile, '<', $cmdFileName) or die "Couldn't open '$cmdFileName' $!"; - my $old_commands = do { <$cmdFile> }; + # Read in the whole file method from http://www.perlmonks.org/?node_id=1952 + my $text; + { + local $/=undef; + open FILE, $cmdFileName or die "Couldn't open file: $!"; + $text = ; + close FILE; + } + + $text =~ s/\nEND//; printf "Replaying $cmdFileName\n"; - printf "$old_commands"; + printf "$text\n"; } } # Print a game map -sub PrintGameMap +sub PrintGameFromGamestateString { - my $gameX = shift; - my $gameY = shift; - my @units = @_; + my $gamestateString = shift or die "PrintGameFromGamestateString needs string parameter"; + + my @info = GetGameInfoFromGamestate($gamestateString); + my @units = GetUnitStringsFromGamestate($gamestateString); + + # $major,$minor,$patch,$name,$sizex,$sizey,$turn,$invalidpositions+ + my $gameX = $info[4]; + my $gameY = $info[5]; + + # Shift into info to where the invalid positions are stored + my @invalids = getPositionStringsFromLine($info[7]); my @map; @@ -169,10 +231,17 @@ sub PrintGameMap } } + # Fill in all invalid coordinates + foreach my $coord (@invalids) + { + my @invalidPos = getPositionsXandYString($coord); + $map[$invalidPos[0]][$invalidPos[1]] = "~"; + } + # Fill with units for my $unit (@units) { - my ($id,$pl,$vs,$dr,$psx,$psy) = getUnit($unit); + my ($id,$pl,$vs,$dr,$psx,$psy) = getUnitInfo($unit); $pl += 31; $vs = "\e[".$pl."m".$vs."\e[0m"; @@ -191,10 +260,36 @@ sub PrintGameMap } } +# Print a game map +sub PrintGameFromFile +{ + my $turnFile = shift or die "PrintGameFromFile needs file parameter"; + + # Read in the whole file method from http://www.perlmonks.org/?node_id=1952 + my $text; + { + local $/=undef; + open FILE, $turnFile or die "Couldn't open file: $!"; + $text = ; + close FILE; + } + + PrintGameFromGamestateString($text); +} + +# Print a turn +sub PrintGameMapForTurn +{ + my $turn = shift; + (! defined $turn) and die "PrintGameMapForTurn needs turn parameter"; + $turn = GetTurnFileName($turn); + PrintGameFromFile( $turn ); +} + # Wait for a file to exist sub WaitForFile { - my $file = $_[0]; + my $file = shift or die "WaitForFile needs file parameter"; while( ! -e $file ) { select(undef, undef, undef, 0.01); From 128dc14bb6e326af6d4c4289f3bb5c0c03972268 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Mon, 29 Dec 2014 22:07:59 +0000 Subject: [PATCH 30/95] Move ttrts perl module into api/perl dubdirectory --- ttrts.pm => api/perl/ttrts.pm | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ttrts.pm => api/perl/ttrts.pm (100%) diff --git a/ttrts.pm b/api/perl/ttrts.pm similarity index 100% rename from ttrts.pm rename to api/perl/ttrts.pm From 485a05293c8743e0b233042113ec381d4287155f Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Mon, 29 Dec 2014 22:29:27 +0000 Subject: [PATCH 31/95] Rename invalid positions to walls --- source/game/game.cpp | 46 +++++++++++++++++++++----------------------- source/game/game.h | 8 ++++---- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/source/game/game.cpp b/source/game/game.cpp index 818225f..05d2b6f 100644 --- a/source/game/game.cpp +++ b/source/game/game.cpp @@ -102,7 +102,7 @@ int CTTRTSGame::VerifyPosIsValidMovement(uvector2 vec) const } // Check within our invalid positions - for ( const uvector2& invalid : m_InvalidPositions ) + for ( const uvector2& invalid : m_walls) { if( vec == invalid ) { @@ -167,8 +167,8 @@ int CTTRTSGame::SimulateToNextTurn() // If the movement is still possible if ( possible ) { - // Push back the old position to our invalid positions list - AddInvalidPosition(pair.unit.GetPos()); + // Create a wall at our old position + AddWall(pair.unit.GetPos()); pair.unit.SetPos(newpos); } } @@ -504,27 +504,27 @@ player_t CTTRTSGame::GetWinningPlayer() const // Get the game information as a string std::string CTTRTSGame::GetStateAsString() const { - // Grab the invalid positions - std::string invalid_positions; - if( m_InvalidPositions.size() == 0 ) + // Grab the walls + std::string walls; + if( m_walls.size() == 0 ) { - invalid_positions = "NONE"; + walls = "NONE"; } - for ( auto invalid_pos : m_InvalidPositions ) + for ( auto wall : m_walls) { char pos[16]; - if( snprintf(pos, 16, GAME_POS_FORMATTER , invalid_pos.x, invalid_pos.y ) < 0 ) + if( snprintf(pos, 16, GAME_POS_FORMATTER , wall.x, wall.y ) < 0 ) { return "BUFFER OVERFLOW"; } - invalid_positions += pos; + walls += pos; } // Print out the header char header[512]; - if ( snprintf(header, 512, GAME_HEADER_FORMATTER , name.c_str(), dimensions.x, dimensions.y, turn, invalid_positions.c_str() ) < 0 ) + if ( snprintf(header, 512, GAME_HEADER_FORMATTER , name.c_str(), dimensions.x, dimensions.y, turn, walls.c_str() ) < 0 ) { return "BUFFER OVERFLOW"; } @@ -559,19 +559,19 @@ CTTRTSGame CTTRTSGame::CreateFromString( const std::string& input ) unsigned int turn; unsigned int sizex; unsigned int sizey; - char invalid_positions[512]; - if( sscanf(header.c_str(), GAME_HEADER_FORMATTER, name, &sizex, &sizey, &turn, invalid_positions ) != 5 ) + char walls[512]; + if( sscanf(header.c_str(), GAME_HEADER_FORMATTER, name, &sizex, &sizey, &turn, walls) != 5 ) { return CTTRTSGame(0,0); } - std::vector invalid_pos_vector; + std::vector walls_vector; { - std::string invalid_positions_str = invalid_positions; + std::string walls_str = walls; size_t pos; - while ( ( pos = invalid_positions_str.find(']') ) != std::string::npos ) + while ( ( pos = walls_str.find(']') ) != std::string::npos ) { - std::string pos_string = invalid_positions_str.substr(1,pos); + std::string pos_string = walls_str.substr(1,pos); // Use scanf to extract positions @@ -582,13 +582,11 @@ CTTRTSGame CTTRTSGame::CreateFromString( const std::string& input ) return CTTRTSGame(0,0); } - uvector2 inv_pos(x,y); - // Erase this coordinate - invalid_positions_str.erase(0,pos+1); + walls_str.erase(0,pos+1); // Append our list - invalid_pos_vector.push_back(inv_pos); + walls_vector.push_back({(ucoord_t)x,(ucoord_t)y}); } } @@ -606,10 +604,10 @@ CTTRTSGame CTTRTSGame::CreateFromString( const std::string& input ) } } - // Add all invalid positions - for ( auto inv : invalid_pos_vector ) + // Add all walls + for ( auto wall : walls_vector) { - game.AddInvalidPosition(inv); + game.AddWall(wall); } return game; diff --git a/source/game/game.h b/source/game/game.h index c3eeca4..c9c338d 100644 --- a/source/game/game.h +++ b/source/game/game.h @@ -76,11 +76,11 @@ public: // Get a vector of the players in the current game std::vector GetPlayers() const; - // Get the vector of current invalid positions - inline std::vector GetInvalidPositions() const { return m_InvalidPositions; } + // Get the vector of wall positions + inline std::vector GetWalls() const { return m_walls; } // Add an invalid position - inline void AddInvalidPosition( uvector2 vec ) { m_InvalidPositions.push_back(vec); } + inline void AddWall(uvector2 vec) { m_walls.push_back(vec); } private: @@ -104,7 +104,7 @@ private: unsigned int turn; // Int to store the current turn uvector2 dimensions; // Dimensions of the game OrderUnitPairVector m_OrderUnitPairs; // Vector to store all units and orders - std::vector m_InvalidPositions; // Vector of invalidated positions + std::vector m_walls; // Vector of wall positions }; From a80c415932c290728073386fa55035630ab6f733 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Mon, 29 Dec 2014 22:31:35 +0000 Subject: [PATCH 32/95] Remove french line --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 57ba61f..ed29f53 100644 --- a/README.md +++ b/README.md @@ -35,10 +35,9 @@ TTRTS is from the ground up designed to be a fun way to practice programming. An * Additional functionality of walls * Walls are noted in gamestate file on new "WALL:[X,Y]..." line * Walls are impassable by all movement -* Units leave an impassable wall behind after movement a la +* Units leave an impassable wall behind after movement * Game can now end if no units are able to move * Various C++ api simplifications -* ttrts now integrates * Integration of perl api from [ttrts-players](https://github.com/mdiluz/ttrts-players) ## v0.2.0 From 97ef46db165b4efe7971b89ce254e1fd2241a7de Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Mon, 29 Dec 2014 22:35:40 +0000 Subject: [PATCH 33/95] Update README with fixes to links --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ed29f53..bdb0e74 100644 --- a/README.md +++ b/README.md @@ -23,15 +23,15 @@ TTRTS is from the ground up designed to be a fun way to practice programming. An ----------------------------------------------------------- ## Development -* [master](master) branch always stores latest stable release +* master branch always stores latest stable release * master/{hotfix} branches store in progress hotfixes for the stable branch -* [dev](dev) branch stores in progress development +* dev branch stores in progress development * dev/{feature} branches store features ----------------------------------------------------------- ## Changelog -## v0.3.0 +#### v0.3.0 * Additional functionality of walls * Walls are noted in gamestate file on new "WALL:[X,Y]..." line * Walls are impassable by all movement @@ -40,13 +40,13 @@ TTRTS is from the ground up designed to be a fun way to practice programming. An * Various C++ api simplifications * Integration of perl api from [ttrts-players](https://github.com/mdiluz/ttrts-players) -## v0.2.0 +#### v0.2.0 * All team references changed to player * Order file format changed to Player_#_Turn_#.txt * Unit descriptors now use pl: instead of tm: * Various other C++ api corrections and refactors -## v0.1.0 +#### v0.1.0 * First playable version of ttrts ----------------------------------------------------------- From 481153606b0bdc8b8d51180d52fc88ce8bca1810 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Mon, 29 Dec 2014 22:44:47 +0000 Subject: [PATCH 34/95] Remove version numbers from unneeded places --- README.md | 2 +- source/ttrts/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bdb0e74..e2c6fd8 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# TTRTS v0.3.0 +# TTRTS *The Tiny Terminal RTS where the players write their AIs* ----------------------------------------------------------- diff --git a/source/ttrts/README.md b/source/ttrts/README.md index 478fa65..f14853e 100644 --- a/source/ttrts/README.md +++ b/source/ttrts/README.md @@ -1,4 +1,4 @@ -# ttrts - Tiny Terminal RTS v0.3.0 +# ttrts - Tiny Terminal RTS ## SYNOPSIS ttrts MAPFILE From 415361ac9c16d9478f8b06c1d996107eb6ba5e80 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Tue, 30 Dec 2014 13:24:17 +0000 Subject: [PATCH 35/95] Update CMakelists Additional install targets for maps, and reworked dependencies --- .gitignore | 1 + bootstrap.sh | 21 +++++++++++++++++---- scripts/gen_maps.sh | 13 +++++++++++++ {source/scripts => scripts}/gen_usage.sh | 0 source/gen/CMakeLists.txt | 13 ++++++++++++- source/ttrts/CMakeLists.txt | 7 ++++--- 6 files changed, 47 insertions(+), 8 deletions(-) create mode 100755 scripts/gen_maps.sh rename {source/scripts => scripts}/gen_usage.sh (100%) diff --git a/.gitignore b/.gitignore index 379896d..502564d 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,5 @@ *.user *.sublime* *.idea +*~ diff --git a/bootstrap.sh b/bootstrap.sh index 9b9a839..dcba4b0 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -1,38 +1,51 @@ #! /bin/bash +# Double check +if [ ! -e "source/CMakeLists.txt" ]; then + echo "TTRTS: No source cmakelist found" + exit +fi + echo "TTRTS: Running cmake" test ! -e build && mkdir build cd build/ cmake ../source if [[ $? != 0 ]]; then echo "TTRTS: CMake failed, exiting Bootstrap" + exit fi echo "TTRTS: Running make" make if [[ $? != 0 ]]; then echo "TTRTS: make failed, exiting Bootstrap" + exit fi echo "TTRTS: Running tests" ./test/ttrts-test if [[ $? != 0 ]]; then echo "TTRTS: Tests failed, build must be broken" + exit fi echo "TTRTS: Generating maps" -test ! -e ../maps && mkdir ../maps -cd ../maps -./../build/gen/ttrts-gen +./../scripts/gen_maps.sh "$PWD/gen/ttrts-gen" if [[ $? != 0 ]]; then - echo "TTRTS: Generating maps, exiting Bootstrap" + echo "TTRTS: Failed to generate maps, exiting Bootstrap" + exit fi +# Copy these maps into parent directory +cp -rf maps .. echo "TTRTS: Moving binaries" cd .. if [ ! -e build/ttrts/ttrts ]; then echo "TTRTS: No TTRTS Binary found, something has gone wrong" + exit fi cp build/ttrts/ttrts . chmod a+x ttrts + +echo "TTRTS: Bootstrap complete" diff --git a/scripts/gen_maps.sh b/scripts/gen_maps.sh new file mode 100755 index 0000000..bb02331 --- /dev/null +++ b/scripts/gen_maps.sh @@ -0,0 +1,13 @@ +#! /bin/bash +# Use to generate the ttrts maps + +ttrtsgen=$1 + +test ! -e maps && mkdir maps # Make maps directory if needed +if [ ! -e maps ]; then + exit 1 +fi + +cd maps + +$ttrtsgen \ No newline at end of file diff --git a/source/scripts/gen_usage.sh b/scripts/gen_usage.sh similarity index 100% rename from source/scripts/gen_usage.sh rename to scripts/gen_usage.sh diff --git a/source/gen/CMakeLists.txt b/source/gen/CMakeLists.txt index 9eff3b8..5d17de9 100644 --- a/source/gen/CMakeLists.txt +++ b/source/gen/CMakeLists.txt @@ -14,4 +14,15 @@ set( SOURCES # Add the executable add_executable( ttrts-gen ${SOURCES} ) -target_link_libraries( ttrts-gen game ) \ No newline at end of file +target_link_libraries( ttrts-gen game ) + +# Run the gen_usage script to generate our usage header +add_custom_target( + ttrts-gen-maps ALL + ${CMAKE_SOURCE_DIR}/../scripts/gen_maps.sh "${CMAKE_CURRENT_BINARY_DIR}/ttrts-gen" +) + +add_dependencies(ttrts-gen-maps ${PROJECT_NAME}) + +# Installation target +install( DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/maps DESTINATION /usr/share/ttrts ) \ No newline at end of file diff --git a/source/ttrts/CMakeLists.txt b/source/ttrts/CMakeLists.txt index d7aa9da..19d01ea 100644 --- a/source/ttrts/CMakeLists.txt +++ b/source/ttrts/CMakeLists.txt @@ -23,7 +23,8 @@ install( TARGETS ${PROJECT_NAME} DESTINATION bin ) # Run the gen_usage script to generate our usage header add_custom_target( - gen_ttrts_usage - cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_SOURCE_DIR}/scripts/gen_usage.sh "${CMAKE_CURRENT_BINARY_DIR}/usage.h" + 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} gen_ttrts_usage) \ No newline at end of file + +add_dependencies(${PROJECT_NAME} ttrts-client-usage) \ No newline at end of file From d9b9f3d7dd5c8089bbbad7fb87d647c405d811f8 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Tue, 30 Dec 2014 13:24:19 +0000 Subject: [PATCH 36/95] Re-organise source directory and targets ttrts -> client game -> ttrts --- bootstrap.sh | 11 ++++++--- source/CMakeLists.txt | 2 +- source/client/CMakeLists.txt | 34 ++++++++++++++++++++++++++ source/{ttrts => client}/README.md | 0 source/{ttrts => client}/main.cpp | 0 source/{ttrts => client}/version.h | 0 source/game/CMakeLists.txt | 17 ------------- source/gen/CMakeLists.txt | 4 +-- source/test/CMakeLists.txt | 4 +-- source/ttrts/CMakeLists.txt | 33 +++++++++---------------- source/{game => ttrts}/game.cpp | 0 source/{game => ttrts}/game.h | 0 source/{game => ttrts}/gametypes.h | 0 source/{game => ttrts}/order.cpp | 0 source/{game => ttrts}/order.h | 0 source/{game => ttrts}/orderunitpair.h | 0 source/{game => ttrts}/unit.cpp | 0 source/{game => ttrts}/unit.h | 0 18 files changed, 58 insertions(+), 47 deletions(-) create mode 100644 source/client/CMakeLists.txt rename source/{ttrts => client}/README.md (100%) rename source/{ttrts => client}/main.cpp (100%) rename source/{ttrts => client}/version.h (100%) delete mode 100644 source/game/CMakeLists.txt rename source/{game => ttrts}/game.cpp (100%) rename source/{game => ttrts}/game.h (100%) rename source/{game => ttrts}/gametypes.h (100%) rename source/{game => ttrts}/order.cpp (100%) rename source/{game => ttrts}/order.h (100%) rename source/{game => ttrts}/orderunitpair.h (100%) rename source/{game => ttrts}/unit.cpp (100%) rename source/{game => ttrts}/unit.h (100%) diff --git a/bootstrap.sh b/bootstrap.sh index dcba4b0..2a7688e 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -1,11 +1,12 @@ #! /bin/bash -# Double check +# Double check for cmakelist if [ ! -e "source/CMakeLists.txt" ]; then echo "TTRTS: No source cmakelist found" exit fi +# Run cmake echo "TTRTS: Running cmake" test ! -e build && mkdir build cd build/ @@ -15,6 +16,7 @@ if [[ $? != 0 ]]; then exit fi +# Run make echo "TTRTS: Running make" make if [[ $? != 0 ]]; then @@ -22,6 +24,7 @@ if [[ $? != 0 ]]; then exit fi +# Run tests echo "TTRTS: Running tests" ./test/ttrts-test if [[ $? != 0 ]]; then @@ -29,6 +32,7 @@ if [[ $? != 0 ]]; then exit fi +# Generate maps echo "TTRTS: Generating maps" ./../scripts/gen_maps.sh "$PWD/gen/ttrts-gen" if [[ $? != 0 ]]; then @@ -38,14 +42,15 @@ fi # Copy these maps into parent directory cp -rf maps .. +# Move binaries echo "TTRTS: Moving binaries" cd .. -if [ ! -e build/ttrts/ttrts ]; then +if [ ! -e build/client/ttrts ]; then echo "TTRTS: No TTRTS Binary found, something has gone wrong" exit fi -cp build/ttrts/ttrts . +cp build/client/ttrts . chmod a+x ttrts echo "TTRTS: Bootstrap complete" diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 1f5def4..76cbf07 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -30,7 +30,7 @@ add_definitions( # Subprojects add_subdirectory( ttrts ) -add_subdirectory( game ) +add_subdirectory( client ) # Auxhilary binaries add_subdirectory( test ) diff --git a/source/client/CMakeLists.txt b/source/client/CMakeLists.txt new file mode 100644 index 0000000..81fdf72 --- /dev/null +++ b/source/client/CMakeLists.txt @@ -0,0 +1,34 @@ +# ====================== ttrts ======================= +# Project name +project( ttrts-client ) + +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ../maths + ../ttrts +) + +# Add the sources +set( SOURCES + main.cpp +) + +# 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 ) + +# 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) \ No newline at end of file diff --git a/source/ttrts/README.md b/source/client/README.md similarity index 100% rename from source/ttrts/README.md rename to source/client/README.md diff --git a/source/ttrts/main.cpp b/source/client/main.cpp similarity index 100% rename from source/ttrts/main.cpp rename to source/client/main.cpp diff --git a/source/ttrts/version.h b/source/client/version.h similarity index 100% rename from source/ttrts/version.h rename to source/client/version.h diff --git a/source/game/CMakeLists.txt b/source/game/CMakeLists.txt deleted file mode 100644 index 2ed80ff..0000000 --- a/source/game/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -cmake_minimum_required(VERSION 2.8.7) - -# game project -project( game ) - -include_directories( - ../maths -) - -# Add the sources -set( SOURCES - game.cpp - unit.cpp - order.cpp -) - -add_library( game ${SOURCES} ) \ No newline at end of file diff --git a/source/gen/CMakeLists.txt b/source/gen/CMakeLists.txt index 5d17de9..ef75c4a 100644 --- a/source/gen/CMakeLists.txt +++ b/source/gen/CMakeLists.txt @@ -3,7 +3,7 @@ project( ttrts-gen ) include_directories( - ../game + ../ttrts ../maths ) @@ -14,7 +14,7 @@ set( SOURCES # Add the executable add_executable( ttrts-gen ${SOURCES} ) -target_link_libraries( ttrts-gen game ) +target_link_libraries( ttrts-gen ttrts ) # Run the gen_usage script to generate our usage header add_custom_target( diff --git a/source/test/CMakeLists.txt b/source/test/CMakeLists.txt index 3779ca8..179f7a8 100644 --- a/source/test/CMakeLists.txt +++ b/source/test/CMakeLists.txt @@ -4,7 +4,7 @@ project( ttrts-test ) include_directories( - ../game + ../ttrts ../maths ) @@ -15,4 +15,4 @@ set( SOURCES # Add the executable add_executable( ttrts-test ${SOURCES} ) -target_link_libraries( ttrts-test game ) +target_link_libraries( ttrts-test ttrts ) diff --git a/source/ttrts/CMakeLists.txt b/source/ttrts/CMakeLists.txt index 19d01ea..f77fc63 100644 --- a/source/ttrts/CMakeLists.txt +++ b/source/ttrts/CMakeLists.txt @@ -1,30 +1,19 @@ -# ====================== ttrts ======================= -# Project name +cmake_minimum_required(VERSION 2.8.7) + +# Main ttrts library project( ttrts ) +# Include the maths include_directories( - ${CMAKE_CURRENT_BINARY_DIR} ../maths - ../game ) -# Add the sources -set( SOURCES - main.cpp +# Add our sources +set( SOURCES + game.cpp + unit.cpp + order.cpp ) -# Add the executable -add_executable( ${PROJECT_NAME} ${SOURCES} ) - -target_link_libraries( ${PROJECT_NAME} game ) - -# 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) \ No newline at end of file +# Add this library +add_library( ttrts ${SOURCES} ) \ No newline at end of file diff --git a/source/game/game.cpp b/source/ttrts/game.cpp similarity index 100% rename from source/game/game.cpp rename to source/ttrts/game.cpp diff --git a/source/game/game.h b/source/ttrts/game.h similarity index 100% rename from source/game/game.h rename to source/ttrts/game.h diff --git a/source/game/gametypes.h b/source/ttrts/gametypes.h similarity index 100% rename from source/game/gametypes.h rename to source/ttrts/gametypes.h diff --git a/source/game/order.cpp b/source/ttrts/order.cpp similarity index 100% rename from source/game/order.cpp rename to source/ttrts/order.cpp diff --git a/source/game/order.h b/source/ttrts/order.h similarity index 100% rename from source/game/order.h rename to source/ttrts/order.h diff --git a/source/game/orderunitpair.h b/source/ttrts/orderunitpair.h similarity index 100% rename from source/game/orderunitpair.h rename to source/ttrts/orderunitpair.h diff --git a/source/game/unit.cpp b/source/ttrts/unit.cpp similarity index 100% rename from source/game/unit.cpp rename to source/ttrts/unit.cpp diff --git a/source/game/unit.h b/source/ttrts/unit.h similarity index 100% rename from source/game/unit.h rename to source/ttrts/unit.h From 3342300324f1a4a67b59cd5da6615693740cb697 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Tue, 30 Dec 2014 13:24:20 +0000 Subject: [PATCH 37/95] Remove math library and merge gametypes and mathtypes --- source/maths/mathtypes.h | 28 -------------------------- source/ttrts/gametypes.h | 32 +++++++++++++++++++++++++----- source/{maths => ttrts}/vector2.h | 0 source/{client => ttrts}/version.h | 0 4 files changed, 27 insertions(+), 33 deletions(-) delete mode 100644 source/maths/mathtypes.h rename source/{maths => ttrts}/vector2.h (100%) rename source/{client => ttrts}/version.h (100%) diff --git a/source/maths/mathtypes.h b/source/maths/mathtypes.h deleted file mode 100644 index d987e25..0000000 --- a/source/maths/mathtypes.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _BASETYPES_H_ -#define _BASETYPES_H_ - -#include // std::numeric_limits - -#include "stdlib.h" // for size_t - -template -constexpr size_t _countof(T (&)[N]) { return N; } - -// Coordinate types -typedef short coord_t; -typedef unsigned short ucoord_t; - -// Invalid values -static const coord_t coord_invalid = std::numeric_limits::max(); -static const ucoord_t ucoord_invalid = std::numeric_limits::max(); - -// Direction representation -enum class dir_c : char -{ - N = 'N', - S = 'S', - E = 'E', - W = 'W' -}; - -#endif //_BASETYPES_H_ diff --git a/source/ttrts/gametypes.h b/source/ttrts/gametypes.h index e86ebf3..d37591b 100644 --- a/source/ttrts/gametypes.h +++ b/source/ttrts/gametypes.h @@ -2,6 +2,7 @@ #define _GAME_TYPES_H_ #include // std::numeric_limits +#include "stdlib.h" // for size_t #define GAME_POS_FORMATTER "[%u,%u]" @@ -20,11 +21,32 @@ enum class player_t : char NUM_INVALID }; - -typedef unsigned short unit_id_t; // Type for unit IDs -typedef char unitvis_c; // Typedef for unit visual representations - +// Type for unit IDs +typedef unsigned short unit_id_t; static const unit_id_t unit_id_invalid = std::numeric_limits::max(); -static const unitvis_c unitvis_invalid = std::numeric_limits::max(); + +// Typedef for unit visual representations +typedef char unitvis_c; +static const unitvis_c unitvis_invalid = std::numeric_limits::max(); + +// Coordinate types +typedef short coord_t; +static const coord_t coord_invalid = std::numeric_limits::max(); + +typedef unsigned short ucoord_t; +static const ucoord_t ucoord_invalid = std::numeric_limits::max(); + +// Direction representation +enum class dir_c : char +{ + N = 'N', + S = 'S', + E = 'E', + W = 'W' +}; + +// Helper function for count of an array +template +constexpr size_t _countof(T (&)[N]) { return N; } #endif //_GAME_TYPES_H_ \ No newline at end of file diff --git a/source/maths/vector2.h b/source/ttrts/vector2.h similarity index 100% rename from source/maths/vector2.h rename to source/ttrts/vector2.h diff --git a/source/client/version.h b/source/ttrts/version.h similarity index 100% rename from source/client/version.h rename to source/ttrts/version.h From 71aab498dc014a582d6db27c81ee38d04c207017 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Tue, 30 Dec 2014 13:24:21 +0000 Subject: [PATCH 38/95] extract format functions out into formatters files --- source/client/main.cpp | 5 +- source/gen/gen.cpp | 3 +- source/test/test.cpp | 15 +-- source/ttrts/CMakeLists.txt | 2 +- source/ttrts/formatters.cpp | 196 ++++++++++++++++++++++++++++++++++++ source/ttrts/formatters.h | 29 ++++++ source/ttrts/game.cpp | 113 +-------------------- source/ttrts/game.h | 8 +- source/ttrts/gametypes.h | 7 -- source/ttrts/order.cpp | 33 ------ source/ttrts/order.h | 4 - source/ttrts/unit.cpp | 46 --------- source/ttrts/unit.h | 7 +- source/ttrts/vector2.h | 2 +- 14 files changed, 246 insertions(+), 224 deletions(-) create mode 100644 source/ttrts/formatters.cpp create mode 100644 source/ttrts/formatters.h delete mode 100644 source/ttrts/order.cpp diff --git a/source/client/main.cpp b/source/client/main.cpp index 272abef..27053fb 100644 --- a/source/client/main.cpp +++ b/source/client/main.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "game.h" #include "version.h" @@ -41,7 +42,7 @@ bool OutputGameStateFile(CTTRTSGame &game, std::string &gameDir) } // Output the turn description - std::string turnDescriptor = game.GetStateAsString(); + std::string turnDescriptor = GetStringFromGame(game); // Append the version number turnDescriptor = std::string("==== ttrts v") @@ -94,7 +95,7 @@ int main(int argc, char* argv[]) } // Create the game - CTTRTSGame game = CTTRTSGame::CreateFromString(gameDescriptor); + CTTRTSGame game = GetGameFromString(gameDescriptor); // Grab the players involved auto players = game.GetPlayers(); diff --git a/source/gen/gen.cpp b/source/gen/gen.cpp index ac7ab2e..ca092d7 100644 --- a/source/gen/gen.cpp +++ b/source/gen/gen.cpp @@ -2,6 +2,7 @@ #include #include +#include "formatters.h" void AddUnitToGame( player_t player, char vis, uvector2 vec, CTTRTSGame& game ) { @@ -15,7 +16,7 @@ void OutputGame( CTTRTSGame&& game ) { std::ofstream output; output.open (game.GetName() + ".txt"); - output << game.GetStateAsString(); + output << GetStringFromGame(game); output.close(); __forceResetCUnitID(); diff --git a/source/test/test.cpp b/source/test/test.cpp index 60d9028..5cbb700 100644 --- a/source/test/test.cpp +++ b/source/test/test.cpp @@ -1,3 +1,4 @@ +#include #include // std::cout #include "order.h" @@ -25,8 +26,8 @@ const char* tests() { CUnit unit1; - std::string unit1Desc = CUnit::GetStringFromUnit(unit1); - CUnit unit2 = CUnit::GetUnitFromString(unit1Desc); + std::string unit1Desc = GetStringFromUnit(unit1); + CUnit unit2 = GetUnitFromString(unit1Desc); if ( unit1 != unit2 ) return "Failed to convert an empty unit to string and back"; @@ -39,8 +40,8 @@ const char* tests() unit1.SetPlayer(player_t::Green); unit1.SetPos(uvector2(5, 10)); - std::string unit1Desc = CUnit::GetStringFromUnit(unit1); - CUnit unit2 = CUnit::GetUnitFromString(unit1Desc); + std::string unit1Desc = GetStringFromUnit(unit1); + CUnit unit2 = GetUnitFromString(unit1Desc); if ( unit1 != unit2 ) return "Failed to convert custom unit to string and back"; @@ -175,10 +176,10 @@ const char* tests() if ( game.GetWinningPlayer() != player_t::Blue ) return "Game failed to recognise a win for the right Player"; - std::string game_string = game.GetStateAsString(); - CTTRTSGame game2 = CTTRTSGame::CreateFromString(game_string); + std::string game_string = GetStringFromGame(game); + CTTRTSGame game2 = GetGameFromString(game_string); - std::string game2_string = game2.GetStateAsString(); + std::string game2_string = GetStringFromGame(game2); // Try matching up the game descriptors if( game_string != game2_string ) diff --git a/source/ttrts/CMakeLists.txt b/source/ttrts/CMakeLists.txt index f77fc63..53f91fb 100644 --- a/source/ttrts/CMakeLists.txt +++ b/source/ttrts/CMakeLists.txt @@ -12,7 +12,7 @@ include_directories( set( SOURCES game.cpp unit.cpp - order.cpp + formatters.cpp ) # Add this library diff --git a/source/ttrts/formatters.cpp b/source/ttrts/formatters.cpp new file mode 100644 index 0000000..25374d7 --- /dev/null +++ b/source/ttrts/formatters.cpp @@ -0,0 +1,196 @@ +#include "formatters.h" + +// Get the game information as a string +std::string GetStringFromGame( const CTTRTSGame& game ) +{ + // Grab the walls + std::string walls; + if( game.GetWalls().size() == 0 ) + { + walls = "NONE"; + } + + for ( auto wall : game.GetWalls() ) + { + char pos[16]; + if( snprintf(pos, 16, GAME_POS_FORMATTER , wall.x, wall.y ) < 0 ) + { + return "BUFFER OVERFLOW"; + } + walls += pos; + } + + + // Print out the header + char header[512]; + if ( snprintf(header, 512, GAME_HEADER_FORMATTER , + game.GetName().c_str(), + game.GetDimensions().x, + game.GetDimensions().y, + game.GetTurn(), + walls.c_str() ) < 0 ) + { + return "BUFFER OVERFLOW"; + } + + // Gather unit information + std::string units; + for ( const SOrderUnitPair & pair : game.GetOrderUnitPairs() ) + { + units += GetStringFromUnit(pair.unit); + units += '\n'; + } + + // Append the header and units + std::string state(header); + state += '\n'; + state += GAME_HEADER_DELIMITER; + state += units; + state += "END"; + + return state; +} + +// Get the game information as a string +CTTRTSGame GetGameFromString( const std::string& input ) +{ + size_t headerEnd = input.find(GAME_HEADER_DELIMITER); + + std::string header = input.substr(0, headerEnd); + std::string units = input.substr(headerEnd + strlen(GAME_HEADER_DELIMITER)); + + // Grab information from the header + char name[64]; + unsigned int turn; + unsigned int sizex; + unsigned int sizey; + char walls[512]; + if( sscanf(header.c_str(), GAME_HEADER_FORMATTER, name, &sizex, &sizey, &turn, walls) != 5 ) + { + return CTTRTSGame(0,0); + } + + std::vector walls_vector; + { + std::string walls_str = walls; + size_t pos; + while ( ( pos = walls_str.find(']') ) != std::string::npos ) + { + std::string pos_string = walls_str.substr(1,pos); + + // Use scanf to extract positions + + unsigned int x; + unsigned int y; + if( sscanf(pos_string.c_str(), GAME_POS_FORMATTER, &x, &y ) != 2 ) + { + return CTTRTSGame(0,0); + } + + // Erase this coordinate + walls_str.erase(0,pos+1); + + // Append our list + walls_vector.push_back({(ucoord_t)x,(ucoord_t)y}); + } + } + + CTTRTSGame game(sizex,sizey); + game.SetName(name); + game.SetTurn(turn); + + // For each line, construct a unit + { + size_t pos; + while ((pos = units.find('\n')) != std::string::npos) { + std::string unit_string = units.substr(0, pos); + units.erase(0, pos + 1); + game.AddUnit(GetUnitFromString(unit_string)); + } + } + + // Add all walls + for ( auto wall : walls_vector) + { + game.AddWall(wall); + } + + return game; +} + +// Get a string descriptor of a unit +std::string GetStringFromUnit(const CUnit& unit ) +{ + static char buff[128]; + memset(buff,0,sizeof(buff)); + + snprintf(buff,128, UNIT_FORMATTER, + unit.GetID(), + (int)unit.GetPlayer(), + unit.GetVisual(), + unit.GetDir(), + unit.GetPos().x, + unit.GetPos().y ); + + return buff; +} + +// Get a unit from a string descriptor +CUnit GetUnitFromString(const std::string& unit ) +{ + CUnit ret; + + unsigned int id; + int player; + char vis; + char dir; + unsigned int posx; + unsigned int posy; + + sscanf(unit.c_str(), UNIT_FORMATTER, + &id, + &player, + &vis, + &dir, + &posx, + &posy ); + + ret.ForceSetID((unit_id_t)id); + ret.SetPlayer((player_t) player); + ret.SetVisual((unitvis_c)vis); + ret.SetDir((dir_c)dir); + ret.SetPos(uvector2(posx,posy)); + + return ret; +} + +// Convert an order to a string +std::string GetStringFromOrder(const SOrder & order ) +{ + static char buff[128]; + memset(buff,0,sizeof(buff)); + + snprintf(buff,128, ORDER_FORMATTER, + order.command, + order.unit); + + return buff; +} + +// Convert a string to an order +SOrder GetOrderFromString( const std::string& order ) +{ + SOrder ret; + + char corder; + unsigned int unit; + + sscanf(order.c_str(), ORDER_FORMATTER, + &corder, + &unit); + + ret.command = (command_c)corder; + ret.unit = unit; + + return ret; +} \ No newline at end of file diff --git a/source/ttrts/formatters.h b/source/ttrts/formatters.h new file mode 100644 index 0000000..96d34fb --- /dev/null +++ b/source/ttrts/formatters.h @@ -0,0 +1,29 @@ +#ifndef _TTRTS_FORMATTERS_H_ +#define _TTRTS_FORMATTERS_H_ + +#include "order.h" +#include "game.h" +#include "unit.h" + +#include "string.h" + +#define GAME_POS_FORMATTER "[%u,%u]" + +#define GAME_HEADER_FORMATTER "NAME:%s\nSIZE:" GAME_POS_FORMATTER "\nTURN:%u\nWALL:%s" +#define GAME_HEADER_DELIMITER "~~~~\n" + +#define UNIT_FORMATTER "UNIT:%u pl:%u vs:%c dr:%c ps:" GAME_POS_FORMATTER + +// order <--> string conversion functions +std::string GetStringFromOrder(const SOrder & order ); +SOrder GetOrderFromString( const std::string& order ); + +// game <--> string conversion functions +CTTRTSGame GetGameFromString( const std::string& input ); +std::string GetStringFromGame( const CTTRTSGame& game ); + +// unit <--> string conversion functions +std::string GetStringFromUnit(const CUnit& unit ); +CUnit GetUnitFromString(const std::string& unit ); + +#endif \ No newline at end of file diff --git a/source/ttrts/game.cpp b/source/ttrts/game.cpp index 05d2b6f..96800d5 100644 --- a/source/ttrts/game.cpp +++ b/source/ttrts/game.cpp @@ -2,6 +2,7 @@ #include #include +#include "formatters.h" CTTRTSGame::CTTRTSGame( ucoord_t c, ucoord_t r ) : dimensions( c,r ) @@ -501,118 +502,6 @@ player_t CTTRTSGame::GetWinningPlayer() const return winningPlayer; } -// Get the game information as a string -std::string CTTRTSGame::GetStateAsString() const -{ - // Grab the walls - std::string walls; - if( m_walls.size() == 0 ) - { - walls = "NONE"; - } - - for ( auto wall : m_walls) - { - char pos[16]; - if( snprintf(pos, 16, GAME_POS_FORMATTER , wall.x, wall.y ) < 0 ) - { - return "BUFFER OVERFLOW"; - } - walls += pos; - } - - - // Print out the header - char header[512]; - if ( snprintf(header, 512, GAME_HEADER_FORMATTER , name.c_str(), dimensions.x, dimensions.y, turn, walls.c_str() ) < 0 ) - { - return "BUFFER OVERFLOW"; - } - - // Gather unit information - std::string units; - for ( const SOrderUnitPair & pair : m_OrderUnitPairs ) - { - units += CUnit::GetStringFromUnit(pair.unit); - units += '\n'; - } - - // Append the header and units - std::string state(header); - state += '\n'; - state += GAME_HEADER_DELIMITER; - state += units; - state += "END"; - - return state; -} -// Get the game information as a string -CTTRTSGame CTTRTSGame::CreateFromString( const std::string& input ) -{ - size_t headerEnd = input.find(GAME_HEADER_DELIMITER); - - std::string header = input.substr(0, headerEnd); - std::string units = input.substr(headerEnd + strlen(GAME_HEADER_DELIMITER)); - - // Grab information from the header - char name[64]; - unsigned int turn; - unsigned int sizex; - unsigned int sizey; - char walls[512]; - if( sscanf(header.c_str(), GAME_HEADER_FORMATTER, name, &sizex, &sizey, &turn, walls) != 5 ) - { - return CTTRTSGame(0,0); - } - - std::vector walls_vector; - { - std::string walls_str = walls; - size_t pos; - while ( ( pos = walls_str.find(']') ) != std::string::npos ) - { - std::string pos_string = walls_str.substr(1,pos); - - // Use scanf to extract positions - - unsigned int x; - unsigned int y; - if( sscanf(pos_string.c_str(), GAME_POS_FORMATTER, &x, &y ) != 2 ) - { - return CTTRTSGame(0,0); - } - - // Erase this coordinate - walls_str.erase(0,pos+1); - - // Append our list - walls_vector.push_back({(ucoord_t)x,(ucoord_t)y}); - } - } - - CTTRTSGame game(sizex,sizey); - game.SetName(name); - game.SetTurn(turn); - - // For each line, construct a unit - { - size_t pos; - while ((pos = units.find('\n')) != std::string::npos) { - std::string unit_string = units.substr(0, pos); - units.erase(0, pos + 1); - game.AddUnit(CUnit::GetUnitFromString(unit_string)); - } - } - - // Add all walls - for ( auto wall : walls_vector) - { - game.AddWall(wall); - } - - return game; -} - // Check if any of the units can move bool CTTRTSGame::UnitsCanMove() const { diff --git a/source/ttrts/game.h b/source/ttrts/game.h index c9c338d..1401b33 100644 --- a/source/ttrts/game.h +++ b/source/ttrts/game.h @@ -13,9 +13,6 @@ class CTTRTSGame { public: - // Get the game information as a string - static CTTRTSGame CreateFromString( const std::string& input ); - // Constructors CTTRTSGame( ucoord_t c, ucoord_t r ); CTTRTSGame(CTTRTSGame&& game); @@ -38,9 +35,6 @@ public: // Check if any of the units can move bool UnitsCanMove() const; - // Get the game information as a string - std::string GetStateAsString() const; - // Issue orders to the game, returns non-zero if orders are incorrect int IssueOrders( player_t player, const std::string& orders ); int IssueOrders( player_t player, const COrderVector& orders ); @@ -61,6 +55,8 @@ public: const CUnit& GetUnitByIDConst( unit_id_t id ) const; const SOrder & GetOrderByIDConst( unit_id_t id ) const; + inline const OrderUnitPairVector& GetOrderUnitPairs() const { return m_OrderUnitPairs; } + // Get dimensions inline const uvector2& GetDimensions() const { return dimensions; } diff --git a/source/ttrts/gametypes.h b/source/ttrts/gametypes.h index d37591b..b01318d 100644 --- a/source/ttrts/gametypes.h +++ b/source/ttrts/gametypes.h @@ -4,13 +4,6 @@ #include // std::numeric_limits #include "stdlib.h" // for size_t -#define GAME_POS_FORMATTER "[%u,%u]" - -#define GAME_HEADER_FORMATTER "NAME:%s\nSIZE:" GAME_POS_FORMATTER "\nTURN:%u\nWALL:%s" -#define GAME_HEADER_DELIMITER "~~~~\n" - -#define UNIT_FORMATTER "UNIT:%u pl:%u vs:%c dr:%c ps:" GAME_POS_FORMATTER - // Type for a Player IDs enum class player_t : char { diff --git a/source/ttrts/order.cpp b/source/ttrts/order.cpp deleted file mode 100644 index 8e0e82f..0000000 --- a/source/ttrts/order.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include "order.h" - -// Convert an order to a string -std::string GetStringFromOrder(const SOrder & order ) -{ - static char buff[128]; - memset(buff,0,sizeof(buff)); - - snprintf(buff,128, ORDER_FORMATTER, - order.command, - order.unit); - - return buff; -} - -// Convert a string to an order -SOrder GetOrderFromString( const std::string& order ) -{ - SOrder ret; - - char corder; - unsigned int unit; - - sscanf(order.c_str(), ORDER_FORMATTER, - &corder, - &unit); - - ret.command = (command_c)corder; - ret.unit = unit; - - return ret; -} diff --git a/source/ttrts/order.h b/source/ttrts/order.h index 845e27f..1ad995a 100644 --- a/source/ttrts/order.h +++ b/source/ttrts/order.h @@ -47,8 +47,4 @@ inline bool SOrder::operator== ( const SOrder & rhs ) const // Typedef a vector of orders typedef std::vector COrderVector; -// string <--> order conversion functions -std::string GetStringFromOrder(const SOrder & order ); -SOrder GetOrderFromString( const std::string& order ); - #endif //_ORDERS_H_ diff --git a/source/ttrts/unit.cpp b/source/ttrts/unit.cpp index 39d9b48..b6708c5 100644 --- a/source/ttrts/unit.cpp +++ b/source/ttrts/unit.cpp @@ -50,52 +50,6 @@ CUnit CUnit::GetUnitFromVis( unitvis_c vis ) return unit; } -// Get a string descriptor of a unit -std::string CUnit::GetStringFromUnit(const CUnit& unit ) -{ - static char buff[128]; - memset(buff,0,sizeof(buff)); - - snprintf(buff,128, UNIT_FORMATTER, - unit.unit_id, - (int)unit.player_id, - unit.unit_vis, - unit.dir, - unit.pos.x, - unit.pos.y ); - - return buff; -} - -// Get a unit from a string descriptor -CUnit CUnit::GetUnitFromString(const std::string& unit ) -{ - CUnit ret; - - unsigned int id; - int player; - char vis; - char dir; - unsigned int posx; - unsigned int posy; - - sscanf(unit.c_str(), UNIT_FORMATTER, - &id, - &player, - &vis, - &dir, - &posx, - &posy ); - - ret.unit_id = (unit_id_t)id; - ret.player_id = (player_t) player; - ret.unit_vis = (unitvis_c)vis; - ret.dir = (dir_c)dir; - ret.pos = uvector2(posx,posy); - - return ret; -} - // Plain constructor CUnit::CUnit() : unit_id ( get_unique_unit_id() ) diff --git a/source/ttrts/unit.h b/source/ttrts/unit.h index b594836..7f6e77e 100644 --- a/source/ttrts/unit.h +++ b/source/ttrts/unit.h @@ -18,10 +18,6 @@ public: // Factory function for creating units from a visual static CUnit GetUnitFromVis( unitvis_c vis ); - // Unit <--> string conversion functions - static std::string GetStringFromUnit(const CUnit& unit ); - static CUnit GetUnitFromString(const std::string& unit ); - // Constructor CUnit(); @@ -59,6 +55,9 @@ public: dir_c TurnRight(); dir_c TurnAround(); + // Force set an ID + inline void ForceSetID( unit_id_t id ) { unit_id = id; } + private: // Update my visual must be called when setting direction diff --git a/source/ttrts/vector2.h b/source/ttrts/vector2.h index 40ce5ad..1cd2e34 100644 --- a/source/ttrts/vector2.h +++ b/source/ttrts/vector2.h @@ -1,7 +1,7 @@ #ifndef _VECTOR2_H_ #define _VECTOR2_H_ -#include "mathtypes.h" +#include "gametypes.h" struct uvector2; From 2c0a393f775a8900f6265766717e49c3cc0d98b1 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Tue, 30 Dec 2014 13:24:21 +0000 Subject: [PATCH 39/95] Update readme to reflect new libraries --- source/README.md | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/source/README.md b/source/README.md index a18fa94..5ca2d8e 100644 --- a/source/README.md +++ b/source/README.md @@ -1,19 +1,13 @@ # Targets -### ttrts +### client Main TTRTS binary, runs from the command line and acts as host for games -### test (ttrts-test) +### test Test binary, to be compiled and run to test various functionality -### gen (ttrts-gen) +### gen Binary to generate example map files # Libraries -### game +### ttrts Implementation of the RTS rules and simulation - -### maths -Simple maths library for 2D calculations and types - -### scripts -Directory of scripts used in build process From f1e4f432e6ec46e1949765d02883337c0f215578 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Tue, 30 Dec 2014 18:32:17 +0000 Subject: [PATCH 40/95] Move top level cmakelist up to main directory --- source/CMakeLists.txt => CMakeLists.txt | 24 ++++++++++++++---------- bootstrap.sh | 16 +++++++--------- source/client/CMakeLists.txt | 2 +- source/gen/CMakeLists.txt | 2 +- 4 files changed, 23 insertions(+), 21 deletions(-) rename source/CMakeLists.txt => CMakeLists.txt (53%) diff --git a/source/CMakeLists.txt b/CMakeLists.txt similarity index 53% rename from source/CMakeLists.txt rename to CMakeLists.txt index 76cbf07..8b757b5 100644 --- a/source/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,19 +19,23 @@ if( CMAKE_BUILD_TYPE MATCHES "Debug" ) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g" ) endif() -# Add definitions for the version number -add_definitions( - -DTTRTS_VERSION_MAJOR=${TTRTS_VERSION_MAJOR} - -DTTRTS_VERSION_MINOR=${TTRTS_VERSION_MINOR} - -DTTRTS_VERSION_PATCH=${TTRTS_VERSION_PATCH} - -DTTRTS_VERSION_STRING=\"${TTRTS_VERSION_MAJOR}.${TTRTS_VERSION_MINOR}.${TTRTS_VERSION_PATCH}\" +# Add bash completion to install +install( FILES scripts/ttrts_complete DESTINATION /etc/bash_completion.d/ ) + +# Add target to generate man page +# Run the gen_usage script to generate our usage header +add_custom_target( + ttrts-gen-manpage ALL + ${CMAKE_SOURCE_DIR}/scripts/gen_manpage.sh "ttrts.6" "${CMAKE_SOURCE_DIR}/source/client/README.md" ) +# Install the ttrts man page +install( FILES "${CMAKE_BINARY_DIR}/ttrts.6" DESTINATION man/man6/ ) # Subprojects -add_subdirectory( ttrts ) -add_subdirectory( client ) +add_subdirectory( source/ttrts ) +add_subdirectory( source/client ) # Auxhilary binaries -add_subdirectory( test ) -add_subdirectory( gen ) +add_subdirectory( source/test ) +add_subdirectory( source/gen ) diff --git a/bootstrap.sh b/bootstrap.sh index 2a7688e..49f384b 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -1,7 +1,7 @@ #! /bin/bash # Double check for cmakelist -if [ ! -e "source/CMakeLists.txt" ]; then +if [ ! -e "CMakeLists.txt" ]; then echo "TTRTS: No source cmakelist found" exit fi @@ -10,7 +10,7 @@ fi echo "TTRTS: Running cmake" test ! -e build && mkdir build cd build/ -cmake ../source +cmake .. if [[ $? != 0 ]]; then echo "TTRTS: CMake failed, exiting Bootstrap" exit @@ -26,7 +26,7 @@ fi # Run tests echo "TTRTS: Running tests" -./test/ttrts-test +./source/test/ttrts-test if [[ $? != 0 ]]; then echo "TTRTS: Tests failed, build must be broken" exit @@ -34,23 +34,21 @@ fi # Generate maps echo "TTRTS: Generating maps" -./../scripts/gen_maps.sh "$PWD/gen/ttrts-gen" +cd .. +./scripts/gen_maps.sh "$PWD/build/source/gen/ttrts-gen" if [[ $? != 0 ]]; then echo "TTRTS: Failed to generate maps, exiting Bootstrap" exit fi -# Copy these maps into parent directory -cp -rf maps .. # Move binaries echo "TTRTS: Moving binaries" -cd .. -if [ ! -e build/client/ttrts ]; then +if [ ! -e build/source/client/ttrts ]; then echo "TTRTS: No TTRTS Binary found, something has gone wrong" exit fi -cp build/client/ttrts . +cp build/source/client/ttrts . chmod a+x ttrts echo "TTRTS: Bootstrap complete" diff --git a/source/client/CMakeLists.txt b/source/client/CMakeLists.txt index 81fdf72..7d12cef 100644 --- a/source/client/CMakeLists.txt +++ b/source/client/CMakeLists.txt @@ -28,7 +28,7 @@ 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" + 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) \ No newline at end of file diff --git a/source/gen/CMakeLists.txt b/source/gen/CMakeLists.txt index ef75c4a..7d0a030 100644 --- a/source/gen/CMakeLists.txt +++ b/source/gen/CMakeLists.txt @@ -19,7 +19,7 @@ target_link_libraries( ttrts-gen ttrts ) # Run the gen_usage script to generate our usage header add_custom_target( ttrts-gen-maps ALL - ${CMAKE_SOURCE_DIR}/../scripts/gen_maps.sh "${CMAKE_CURRENT_BINARY_DIR}/ttrts-gen" + ${CMAKE_SOURCE_DIR}/scripts/gen_maps.sh "${CMAKE_CURRENT_BINARY_DIR}/ttrts-gen" ) add_dependencies(ttrts-gen-maps ${PROJECT_NAME}) From 31644b1f950f563cc7c5cb3807fbf4a98725556b Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Tue, 30 Dec 2014 18:33:59 +0000 Subject: [PATCH 41/95] Fix a couple of bugs in gen_usage.sh --- scripts/gen_usage.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/gen_usage.sh b/scripts/gen_usage.sh index a183af7..8bc0f7b 100755 --- a/scripts/gen_usage.sh +++ b/scripts/gen_usage.sh @@ -1,8 +1,9 @@ #! /bin/bash # Used to generate usage text from markdown cat README.md \ - | sed 's/^#* //g' \ - | sed 's/\t/\\t/g' \ + | sed 's/^#\+ //g' \ + | sed 's/^\t/\\t/g' \ + | sed 's/^ /\\t/g' \ | sed ':a;N;$!ba;s/\n/\\n\n/g' \ | sed 's/^/\"/' \ | sed 's/$/\"/' \ From 53e882ae1234975771ccdd127f70fc904a3389f9 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Tue, 30 Dec 2014 18:36:01 +0000 Subject: [PATCH 42/95] Allow env variables to set game and map locations the client will also now look in /usr/local for maps --- source/client/main.cpp | 82 ++++++++++++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 22 deletions(-) diff --git a/source/client/main.cpp b/source/client/main.cpp index 27053fb..76ce858 100644 --- a/source/client/main.cpp +++ b/source/client/main.cpp @@ -2,17 +2,22 @@ #include #include #include + #include #include #include #include +#include +#include #include "game.h" -#include "version.h" static const char* sk_usage = #include "usage.h" ; + +// Verbose mode +static const bool env_verbose = getenv("VERBOSE"); // time for waiting between file stats static const std::chrono::milliseconds sk_waitTime = std::chrono::milliseconds(100); @@ -44,12 +49,6 @@ bool OutputGameStateFile(CTTRTSGame &game, std::string &gameDir) // Output the turn description std::string turnDescriptor = GetStringFromGame(game); - // Append the version number - turnDescriptor = std::string("==== ttrts v") - + sk_ttrts_version_string - + std::string(" ====\n") - + turnDescriptor; - turnFile<>input; if( !input.size() || std::tolower(input[0]) != 'y' ) { std::cerr<<"Aborting..."< Date: Tue, 30 Dec 2014 18:37:46 +0000 Subject: [PATCH 43/95] Update with more install targets. Installing headers and library to /usr/local/ Requires workaround for version information header generation Install a man page Install some basic bash completion for maps Also update the readme to fit with the manpage and new autocompletion features Fixes the oddity where generated map files were missing the initial line of the header --- scripts/gen_manpage.sh | 29 ++++++++ scripts/gen_version_header.sh | 13 ++++ scripts/ttrts_complete | 23 ++++++ source/client/README.md | 136 +++++++++++++++++----------------- source/ttrts/CMakeLists.txt | 30 +++++++- source/ttrts/formatters.cpp | 18 ++++- source/ttrts/formatters.h | 4 +- source/ttrts/version.h | 9 --- 8 files changed, 179 insertions(+), 83 deletions(-) create mode 100755 scripts/gen_manpage.sh create mode 100755 scripts/gen_version_header.sh create mode 100755 scripts/ttrts_complete delete mode 100644 source/ttrts/version.h diff --git a/scripts/gen_manpage.sh b/scripts/gen_manpage.sh new file mode 100755 index 0000000..ccb211d --- /dev/null +++ b/scripts/gen_manpage.sh @@ -0,0 +1,29 @@ +#! /bin/bash +# Used to a man page from markdown + +echo ".\" Man page for the ttrts project" > $1 +echo ".\" this man page is auto-generated, do not edit directly" >> $1 + +echo ".TH TTRTS\ v0.3.0 6 $(date +%Y-%m-%d) http://mdiluz.github.io/ttrts/" >> $1 + +# sections to section headers +# sub-sections in man page sub-sections +# 4-space lines to tabs +# tab starts removed +# Environment variables in bold +# User variables in italics +# remove all line-widths +# Put all back-ticks quotes in bold +# underline mapfile opt +# ensure name section uses correct +cat "$2" \ + | sed -r 's/^# (\w+)/.SH \1/g' \ + | sed -r 's/^##+ (\w+)/.SS \1/g' \ + | sed -r 's/^ (.*)$/\n\t\1\n/g' \ + | sed -r 's/^\t//g' \ + | sed -r 's/\$\{(\w+)\}/\\fB\$\1\\fR/g' \ + | sed -r 's/\{(\w+)\}/\\fI\1\\fR/g' \ + | sed -r 's/-----+//g' \ + | sed -r 's/`(.*?)`/\\fB\1\\fR/g' \ + | sed -r 's/MAPFILE/\\fImapfile\\fR/g' \ + | sed -r 's/\tttrts -/\tttrts \\-/g' >> $1 diff --git a/scripts/gen_version_header.sh b/scripts/gen_version_header.sh new file mode 100755 index 0000000..907c2be --- /dev/null +++ b/scripts/gen_version_header.sh @@ -0,0 +1,13 @@ +HEADER="// Auto generated ttrts version header +// do not edit manually +#ifndef _TTRTS_VERSION_H_ +#define _TTRTS_VERSION_H_ + +#define TTRTS_VERSION_MAJOR $1 +#define TTRTS_VERSION_MINOR $2 +#define TTRTS_VERSION_PATCH $3 +#define TTRTS_VERSION_STRING \"v$1.$2.$3\" + +#endif //_TTRTS_VERSION_H_" + +echo "$HEADER" > "version.h" \ No newline at end of file diff --git a/scripts/ttrts_complete b/scripts/ttrts_complete new file mode 100755 index 0000000..7b884b7 --- /dev/null +++ b/scripts/ttrts_complete @@ -0,0 +1,23 @@ +# ttrts completion + +test ! -z TTRTS_MAPS && TTRTS_MAPS=/usr/share/ttrts/maps/ + +have ttrts && +function _ttrts +{ + commandnames="" + for filename in ${TTRTS_MAPS}/* + do + map="${filename##*/}" + commandnames+="$map " + done + + local cur prev + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + COMPREPLY=( $(compgen -W "${commandnames}" -- ${cur}) ) +} + +complete -F _ttrts ttrts diff --git a/source/client/README.md b/source/client/README.md index f14853e..9e8cf27 100644 --- a/source/client/README.md +++ b/source/client/README.md @@ -1,53 +1,78 @@ -# ttrts - Tiny Terminal RTS +# NAME + ttrts - Tiny Terminal RTS -## SYNOPSIS +# SYNOPSIS ttrts MAPFILE -## DESCRIPTION - ttrts is a tiny terminal based RTS where that uses text - files as order lists to control it's units +# 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 + This means that any user, program or cat that can read and write to text files can play the game -## OPTIONS - MAPFILE - File to read in the initial game state from +# RETURN VALUE + ttrts will return -1 on error, or the winning player on completion -## USAGE - When invoked, ttrts will set up the game in a local - directory called `ttrts_{GAME_NAME}` +# OPTIONS + MAPFILE - File to read in the initial game state. Local or in ${TTRTS_MAPS} - The GAMESTATE files in this directory can be read and - interpreted by human, robot or cat. +# USAGE + When invoked, ttrts will set up the game in a directory within ${TTRTS_GAMES} by the name of the map - ttrts will then await ORDER files from each participant + The files in this directory can be read and interpreted by human, robot or cat - Once all ORDER files have been received ttrts will - calculate the turn and output a new GAMESTATE file + 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/` + ----------------------------------------------------------- -# TTRTS GAMEPLAY +# FILES + `/usr/share/ttrts/maps/` holds a sample set of maps -## RULES - The game takes place in a series of simultaneous turns - on an arbitrarily sized 2D board +## Gamestate File + Turn_{TURNNUMBER}.txt - Each turn, the client outputs a GAMESTATE file and - waits for an ORDER file from each player +### 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 - All commands are evaluated simultaneously with friendly - fire enabled by default +## 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) + * 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 + Each unit occupies a single tile on the board, facing in a compass direction (NESW) Units will only accept orders from their owner @@ -55,48 +80,19 @@ 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 +# 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 + * 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 +### L/R - Rotate unit [L]eft or [R]ight - Unit will rotate clockwise or counter-clockwise, - this order cannot fail + 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. - ------------------------------------------------------------ -# FILE FORMATS - -## Gamestate File - Turn_{TURN_NUMBER}.txt - -### Contents - ===== ttrts v{MAJOR}.{MINOR}.{PATCH} ===== - NAME:{GAMENAME} - SIZE:[{X},{Y}] - TURN:{TURN_NUMBER} - 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 +### 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. diff --git a/source/ttrts/CMakeLists.txt b/source/ttrts/CMakeLists.txt index 53f91fb..b528b3f 100644 --- a/source/ttrts/CMakeLists.txt +++ b/source/ttrts/CMakeLists.txt @@ -5,6 +5,7 @@ project( ttrts ) # Include the maths include_directories( + ${CMAKE_CURRENT_BINARY_DIR} ../maths ) @@ -16,4 +17,31 @@ set( SOURCES ) # Add this library -add_library( ttrts ${SOURCES} ) \ No newline at end of file +add_library( ttrts ${SOURCES} ) + +add_custom_target( + ttrts-version-header ALL + ${CMAKE_SOURCE_DIR}/scripts/gen_version_header.sh ${TTRTS_VERSION_MAJOR} ${TTRTS_VERSION_MINOR} ${TTRTS_VERSION_PATCH} +) + +# ttrts is dependent on this +add_dependencies( ${PROJECT_NAME} ttrts-version-header ) + +# Install headers +install( + FILES + game.h + unit.h + order.h + formatters.h + vector2.h + orderunitpair.h + gametypes.h + ${CMAKE_CURRENT_BINARY_DIR}/version.h + + DESTINATION + include/ttrts +) + +# Install the ttrts static lib +install( TARGETS ttrts DESTINATION lib ) \ No newline at end of file diff --git a/source/ttrts/formatters.cpp b/source/ttrts/formatters.cpp index 25374d7..0127803 100644 --- a/source/ttrts/formatters.cpp +++ b/source/ttrts/formatters.cpp @@ -1,4 +1,7 @@ #include "formatters.h" +#include + +#include "version.h" // Get the game information as a string std::string GetStringFromGame( const CTTRTSGame& game ) @@ -24,6 +27,9 @@ std::string GetStringFromGame( const CTTRTSGame& game ) // Print out the header char header[512]; if ( snprintf(header, 512, GAME_HEADER_FORMATTER , + TTRTS_VERSION_MAJOR, + TTRTS_VERSION_MINOR, + TTRTS_VERSION_PATCH, game.GetName().c_str(), game.GetDimensions().x, game.GetDimensions().y, @@ -60,16 +66,26 @@ CTTRTSGame GetGameFromString( const std::string& input ) std::string units = input.substr(headerEnd + strlen(GAME_HEADER_DELIMITER)); // Grab information from the header + unsigned int major; + unsigned int minor; + unsigned int patch; char name[64]; unsigned int turn; unsigned int sizex; unsigned int sizey; char walls[512]; - if( sscanf(header.c_str(), GAME_HEADER_FORMATTER, name, &sizex, &sizey, &turn, walls) != 5 ) + if( sscanf(header.c_str(), GAME_HEADER_FORMATTER, &major, &minor, &patch, name, &sizex, &sizey, &turn, walls) != 8 ) { + std::cerr<<"Error: Failed to properly read game state from text"< walls_vector; { std::string walls_str = walls; diff --git a/source/ttrts/formatters.h b/source/ttrts/formatters.h index 96d34fb..31cf9e7 100644 --- a/source/ttrts/formatters.h +++ b/source/ttrts/formatters.h @@ -9,7 +9,7 @@ #define GAME_POS_FORMATTER "[%u,%u]" -#define GAME_HEADER_FORMATTER "NAME:%s\nSIZE:" GAME_POS_FORMATTER "\nTURN:%u\nWALL:%s" +#define GAME_HEADER_FORMATTER "==== ttrts v%u.%u.%u ====\nNAME:%s\nSIZE:" GAME_POS_FORMATTER "\nTURN:%u\nWALL:%s" #define GAME_HEADER_DELIMITER "~~~~\n" #define UNIT_FORMATTER "UNIT:%u pl:%u vs:%c dr:%c ps:" GAME_POS_FORMATTER @@ -24,6 +24,6 @@ std::string GetStringFromGame( const CTTRTSGame& game ); // unit <--> string conversion functions std::string GetStringFromUnit(const CUnit& unit ); -CUnit GetUnitFromString(const std::string& unit ); +CUnit GetUnitFromString(const std::string& unit ); #endif \ No newline at end of file diff --git a/source/ttrts/version.h b/source/ttrts/version.h deleted file mode 100644 index b64c49c..0000000 --- a/source/ttrts/version.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _TTRTS_VERSION_H_ -#define _TTRTS_VERSION_H_ - -static const int sk_ttrts_version_major = TTRTS_VERSION_MAJOR; -static const int sk_ttrts_version_minor = TTRTS_VERSION_MINOR; -static const int sk_ttrts_version_patch = TTRTS_VERSION_PATCH; -static const char* sk_ttrts_version_string = TTRTS_VERSION_STRING; - -#endif //_TTRTS_VERSION_H_ \ No newline at end of file From ad803a5d7af5495a29bd29ab48ece0df0e6dd82a Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Tue, 30 Dec 2014 18:53:15 +0000 Subject: [PATCH 44/95] Rework bootstrap to use new install targets --- bootstrap.sh | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/bootstrap.sh b/bootstrap.sh index 49f384b..12eda15 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -16,15 +16,14 @@ if [[ $? != 0 ]]; then exit fi -# Run make -echo "TTRTS: Running make" -make +echo "Performing install" +make install if [[ $? != 0 ]]; then - echo "TTRTS: make failed, exiting Bootstrap" + echo "TTRTS: Install failed, check output" exit fi -# Run tests +# Run final test to make sure echo "TTRTS: Running tests" ./source/test/ttrts-test if [[ $? != 0 ]]; then @@ -32,23 +31,4 @@ if [[ $? != 0 ]]; then exit fi -# Generate maps -echo "TTRTS: Generating maps" -cd .. -./scripts/gen_maps.sh "$PWD/build/source/gen/ttrts-gen" -if [[ $? != 0 ]]; then - echo "TTRTS: Failed to generate maps, exiting Bootstrap" - exit -fi - -# Move binaries -echo "TTRTS: Moving binaries" -if [ ! -e build/source/client/ttrts ]; then - echo "TTRTS: No TTRTS Binary found, something has gone wrong" - exit -fi - -cp build/source/client/ttrts . -chmod a+x ttrts - echo "TTRTS: Bootstrap complete" From cb46c84de5a2f4de3b76f92d2cf1c3adad763f73 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Tue, 30 Dec 2014 19:23:03 +0000 Subject: [PATCH 45/95] Actually use real version number in the man page --- CMakeLists.txt | 2 +- scripts/gen_manpage.sh | 12 +++++++----- scripts/gen_usage.sh | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b757b5..2c8bf5d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,7 +26,7 @@ install( FILES scripts/ttrts_complete DESTINATION /etc/bash_completion.d/ ) # Run the gen_usage script to generate our usage header add_custom_target( ttrts-gen-manpage ALL - ${CMAKE_SOURCE_DIR}/scripts/gen_manpage.sh "ttrts.6" "${CMAKE_SOURCE_DIR}/source/client/README.md" + ${CMAKE_SOURCE_DIR}/scripts/gen_manpage.sh "${TTRTS_VERSION_MAJOR}" "${TTRTS_VERSION_MINOR}" "${TTRTS_VERSION_PATCH}" "ttrts.6" "${CMAKE_SOURCE_DIR}/source/client/README.md" ) # Install the ttrts man page diff --git a/scripts/gen_manpage.sh b/scripts/gen_manpage.sh index ccb211d..9b7e02a 100755 --- a/scripts/gen_manpage.sh +++ b/scripts/gen_manpage.sh @@ -1,10 +1,12 @@ #! /bin/bash # Used to a man page from markdown -echo ".\" Man page for the ttrts project" > $1 -echo ".\" this man page is auto-generated, do not edit directly" >> $1 -echo ".TH TTRTS\ v0.3.0 6 $(date +%Y-%m-%d) http://mdiluz.github.io/ttrts/" >> $1 + +echo ".\" Man page for the ttrts project" > $4 +echo ".\" this man page is auto-generated, do not edit directly" >> $4 + +echo ".TH TTRTS\ v$1.$2.$3 6 $(date +%Y-%m-%d) http://mdiluz.github.io/ttrts/" >> $4 # sections to section headers # sub-sections in man page sub-sections @@ -16,7 +18,7 @@ echo ".TH TTRTS\ v0.3.0 6 $(date +%Y-%m-%d) http://mdiluz.github.io/ttrts/" >> $ # Put all back-ticks quotes in bold # underline mapfile opt # ensure name section uses correct -cat "$2" \ +cat "$5" \ | sed -r 's/^# (\w+)/.SH \1/g' \ | sed -r 's/^##+ (\w+)/.SS \1/g' \ | sed -r 's/^ (.*)$/\n\t\1\n/g' \ @@ -26,4 +28,4 @@ cat "$2" \ | sed -r 's/-----+//g' \ | sed -r 's/`(.*?)`/\\fB\1\\fR/g' \ | sed -r 's/MAPFILE/\\fImapfile\\fR/g' \ - | sed -r 's/\tttrts -/\tttrts \\-/g' >> $1 + | sed -r 's/\tttrts -/\tttrts \\-/g' >> $4 diff --git a/scripts/gen_usage.sh b/scripts/gen_usage.sh index 8bc0f7b..c989b2d 100755 --- a/scripts/gen_usage.sh +++ b/scripts/gen_usage.sh @@ -1,7 +1,7 @@ #! /bin/bash # Used to generate usage text from markdown cat README.md \ - | sed 's/^#\+ //g' \ + | sed 's/^#\+ //g' \ | sed 's/^\t/\\t/g' \ | sed 's/^ /\\t/g' \ | sed ':a;N;$!ba;s/\n/\\n\n/g' \ From 66f522679731670d11b11e7433392393743705d4 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Tue, 30 Dec 2014 19:25:11 +0000 Subject: [PATCH 46/95] Correct spelling mistake in README and add sudo to install --- README.md | 2 +- bootstrap.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e2c6fd8..55b81c9 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ TTRTS is from the ground up designed to be a fun way to practice programming. An ## Building TTRTS #### Requirements -* cmake - our build system uses cmake +* CMake - our build system uses cmake * Linux/OSX - currently no support for Windows, tracked with [Issue #9](https://github.com/mdiluz/ttrts/issues/9) #### To Build diff --git a/bootstrap.sh b/bootstrap.sh index 12eda15..26e306d 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -17,7 +17,7 @@ if [[ $? != 0 ]]; then fi echo "Performing install" -make install +sudo make install if [[ $? != 0 ]]; then echo "TTRTS: Install failed, check output" exit From 9c68372f64823e7bf4656c1ea47dc576e40e3592 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Tue, 30 Dec 2014 19:26:14 +0000 Subject: [PATCH 47/95] Update to patch 0.3.1 --- CMakeLists.txt | 2 +- README.md | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c8bf5d..ddc7e66 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required( VERSION 2.8.7 ) # Set version information set( TTRTS_VERSION_MAJOR 0 ) set( TTRTS_VERSION_MINOR 3 ) -set( TTRTS_VERSION_PATCH 0 ) +set( TTRTS_VERSION_PATCH 1 ) # Use c++1y (14) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++1y" ) diff --git a/README.md b/README.md index 55b81c9..f13350c 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,19 @@ TTRTS is from the ground up designed to be a fun way to practice programming. An ----------------------------------------------------------- ## Changelog +#### v0.3.1 +* Upgraded install target to repository + * libttrts static library binary in /usr/local/lib + * ttrts headers in /usr/local/include/ttrts + * bash completion into /etc/bash_completion.d/ + * man page into /usr/local/man/man6 + * maps into /usr/share/ttrts/maps +* client now supports env variable configuration + * TTRTS_MAPS for location of map files, defaults to /usr/share/ttrts/maps + * TTRTS_GAMES for gameplay directories, defaults to /tmp/ +* Map files now have proper header +* NOTE: This version is compatible with v0.3.0, but old generated mapfiles will need the additional header line added + #### v0.3.0 * Additional functionality of walls * Walls are noted in gamestate file on new "WALL:[X,Y]..." line From 3f76b6430b4407de2ed47ea0c48e136a05f0bd0f Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Wed, 31 Dec 2014 13:50:15 +0000 Subject: [PATCH 48/95] Fix usage of sed and man page on OSX --- CMakeLists.txt | 10 +++++++++- scripts/gen_manpage.sh | 28 ++++++++++++++++------------ scripts/gen_usage.sh | 12 ++++++------ 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ddc7e66..6d72293 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,15 @@ add_custom_target( ) # Install the ttrts man page -install( FILES "${CMAKE_BINARY_DIR}/ttrts.6" DESTINATION man/man6/ ) +if( ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" ) + set ( MANPAGE_LOC share/man/man6 ) +elseif( ${CMAKE_SYSTEM_NAME} MATCHES "Linux" ) + set ( MANPAGE_LOC man/man6 ) +else() + message(ERROR "Unsupported system detected") +endif() + +install( FILES "${CMAKE_BINARY_DIR}/ttrts.6" DESTINATION ${MANPAGE_LOC} ) # Subprojects add_subdirectory( source/ttrts ) diff --git a/scripts/gen_manpage.sh b/scripts/gen_manpage.sh index 9b7e02a..57ad57c 100755 --- a/scripts/gen_manpage.sh +++ b/scripts/gen_manpage.sh @@ -1,13 +1,15 @@ #! /bin/bash # Used to a man page from markdown - - echo ".\" Man page for the ttrts project" > $4 echo ".\" this man page is auto-generated, do not edit directly" >> $4 echo ".TH TTRTS\ v$1.$2.$3 6 $(date +%Y-%m-%d) http://mdiluz.github.io/ttrts/" >> $4 +# NOTE: For the OSX version of sed we use -E, which on linux appears be an undocumented switch for -r +# we also have to use [A-Za-z] instead of \w for some reason +# as well as escaped new line characters and literal tabs instead of \n and \t + # sections to section headers # sub-sections in man page sub-sections # 4-space lines to tabs @@ -19,13 +21,15 @@ echo ".TH TTRTS\ v$1.$2.$3 6 $(date +%Y-%m-%d) http://mdiluz.github.io/ttrts/" > # underline mapfile opt # ensure name section uses correct cat "$5" \ - | sed -r 's/^# (\w+)/.SH \1/g' \ - | sed -r 's/^##+ (\w+)/.SS \1/g' \ - | sed -r 's/^ (.*)$/\n\t\1\n/g' \ - | sed -r 's/^\t//g' \ - | sed -r 's/\$\{(\w+)\}/\\fB\$\1\\fR/g' \ - | sed -r 's/\{(\w+)\}/\\fI\1\\fR/g' \ - | sed -r 's/-----+//g' \ - | sed -r 's/`(.*?)`/\\fB\1\\fR/g' \ - | sed -r 's/MAPFILE/\\fImapfile\\fR/g' \ - | sed -r 's/\tttrts -/\tttrts \\-/g' >> $4 + | sed -E 's/^# ([A-Za-z]+)/.SH \1/g' \ + | sed -E 's/^##+ ([A-Za-z]+)/.SS \1/g' \ + | sed -E 's/^ (.*)$/\ + \1\ +/g' \ + | sed -E 's/^ //g' \ + | sed -E 's/\$\{([A-Za-z]+)\}/\\fB\$\1\\fR/g' \ + | sed -E 's/\{([A-Za-z]+)\}/\\fI\1\\fR/g' \ + | sed -E 's/-----+//g' \ + | sed -E 's/`(.*)`/\\fB\1\\fR/g' \ + | sed -E 's/MAPFILE/\\fImapfile\\fR/g' \ + | sed -E 's/ ttrts -/ ttrts \\-/g' >> $4 diff --git a/scripts/gen_usage.sh b/scripts/gen_usage.sh index c989b2d..efeab0a 100755 --- a/scripts/gen_usage.sh +++ b/scripts/gen_usage.sh @@ -1,10 +1,10 @@ #! /bin/bash # Used to generate usage text from markdown + cat README.md \ - | sed 's/^#\+ //g' \ - | sed 's/^\t/\\t/g' \ - | sed 's/^ /\\t/g' \ - | sed ':a;N;$!ba;s/\n/\\n\n/g' \ - | sed 's/^/\"/' \ - | sed 's/$/\"/' \ + | sed -E 's/^#+ //g' \ + | sed -E 's/^ /\\t/g' \ + | sed -E 's/^ /\\t/g' \ + | sed -E 's/^/\"/' \ + | sed -E 's/$/\\n\"/' \ > $1 From 3f892ec2aa4e72955ccc339fc32dee13f5dbebb7 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Wed, 31 Dec 2014 14:07:34 +0000 Subject: [PATCH 49/95] Move maps to /usr/local and allow these settings to get defaults from the cmakelists --- source/client/CMakeLists.txt | 8 ++++++++ source/client/main.cpp | 7 +++++-- source/gen/CMakeLists.txt | 2 +- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/source/client/CMakeLists.txt b/source/client/CMakeLists.txt index 7d12cef..6549943 100644 --- a/source/client/CMakeLists.txt +++ b/source/client/CMakeLists.txt @@ -13,6 +13,14 @@ set( SOURCES main.cpp ) +# Set defaults for ttrts maps and games +set( TTRTS_MAPS "/usr/local/share/ttrts/maps/" ) +set( TTRTS_GAMES "/tmp/" ) + +# 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}" ) + # Add the executable add_executable( ${PROJECT_NAME} ${SOURCES} ) diff --git a/source/client/main.cpp b/source/client/main.cpp index 76ce858..35bf5de 100644 --- a/source/client/main.cpp +++ b/source/client/main.cpp @@ -12,6 +12,9 @@ #include "game.h" +#define STRINGIFY(x) _STRINGIFY(x) +#define _STRINGIFY(x) #x + static const char* sk_usage = #include "usage.h" ; @@ -69,7 +72,7 @@ int main(int argc, char* argv[]) std::string gameFile = argv[1]; // Default for maps - std::string ttrts_maps_dir = "/usr/share/ttrts/maps/"; + std::string ttrts_maps_dir = STRINGIFY(TTRTS_MAPS); if( getenv("TTRTS_MAPS") ) { ttrts_maps_dir = getenv("TTRTS_MAPS"); @@ -80,7 +83,7 @@ int main(int argc, char* argv[]) } // Default for games - std::string ttrts_games_dir = "/tmp/"; + std::string ttrts_games_dir = STRINGIFY(TTRTS_GAMES); if( getenv("TTRTS_GAMES") ) { ttrts_games_dir = getenv("TTRTS_GAMES"); diff --git a/source/gen/CMakeLists.txt b/source/gen/CMakeLists.txt index 7d0a030..466e233 100644 --- a/source/gen/CMakeLists.txt +++ b/source/gen/CMakeLists.txt @@ -25,4 +25,4 @@ add_custom_target( add_dependencies(ttrts-gen-maps ${PROJECT_NAME}) # Installation target -install( DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/maps DESTINATION /usr/share/ttrts ) \ No newline at end of file +install( DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/maps DESTINATION /usr/local/share/ttrts ) \ No newline at end of file From faa7cdc501f5290d45ef02b159d849a77641db7c Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Wed, 31 Dec 2014 18:39:11 +0000 Subject: [PATCH 50/95] Fix bug when loading games with walls Game would fail to load as it was cutting off the first [ --- source/ttrts/formatters.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ttrts/formatters.cpp b/source/ttrts/formatters.cpp index 0127803..6d6d03a 100644 --- a/source/ttrts/formatters.cpp +++ b/source/ttrts/formatters.cpp @@ -92,7 +92,7 @@ CTTRTSGame GetGameFromString( const std::string& input ) size_t pos; while ( ( pos = walls_str.find(']') ) != std::string::npos ) { - std::string pos_string = walls_str.substr(1,pos); + std::string pos_string = walls_str.substr(0,pos); // Use scanf to extract positions @@ -209,4 +209,4 @@ SOrder GetOrderFromString( const std::string& order ) ret.unit = unit; return ret; -} \ No newline at end of file +} From 189241853b6ece5850205f66167b141659db4560 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Wed, 31 Dec 2014 18:39:58 +0000 Subject: [PATCH 51/95] Update the map generation New maps! 3 player! Update names, as it wasn't 2v2 so much as 1v1 with 2 units each --- source/gen/gen.cpp | 104 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 99 insertions(+), 5 deletions(-) diff --git a/source/gen/gen.cpp b/source/gen/gen.cpp index ca092d7..8265a53 100644 --- a/source/gen/gen.cpp +++ b/source/gen/gen.cpp @@ -24,23 +24,44 @@ void OutputGame( CTTRTSGame&& game ) int main() { - // Tiny 2v2 Game + // Tiny 1v1 Game + //------ + //-G---- + //----R- + //-G---- + //----R- + //------ { CTTRTSGame game(6, 6); - game.SetName("Tiny2v2"); + game.SetName("Tiny2player"); AddUnitToGame( player_t::Red, '<', uvector2(4, 2), game); AddUnitToGame( player_t::Red, '<', uvector2(4, 4), game); AddUnitToGame( player_t::Green, '>', uvector2(1, 1), game); AddUnitToGame( player_t::Green, '>', uvector2(1, 3), game); + game.AddWall(uvector2(3,2)); + game.AddWall(uvector2(3,3)); + OutputGame(std::move(game)); } - // Basic 5v5 game + // Basic 1v1 game + // -------------------- + // -G------------------ + // ------------------R- + // -G------------------ + // ------------------R- + // -G------------------ + // ------------------R- + // -G------------------ + // ------------------R- + // -G------------------ + // ------------------R- + // -------------------- { CTTRTSGame game(20, 12); - game.SetName("Big2v2"); + game.SetName("Big2Player"); for ( ucoord_t y : { 2,4,6,8,10 } ) AddUnitToGame( player_t::Red, '<', uvector2(18, y), game); @@ -51,7 +72,15 @@ int main() OutputGame(std::move(game)); } - // Chess 10v10 game + // Sort of like Chess + //GG------ + //------RR + //GG------ + //------RR + //GG------ + //------RR + //GG------ + //------RR { CTTRTSGame game(8, 8); game.SetName("Chess"); @@ -68,4 +97,69 @@ int main() OutputGame(std::move(game)); } + + // Medium 4 player game + //---------- + //---------- + //---GGGG--- + //--R -- B-- + //--R- -B-- + //--R- -B-- + //--R -- B-- + //---YYYY--- + //---------- + //---------- + { + CTTRTSGame game(10, 10); + game.SetName("Medium4Player"); + + for ( ucoord_t y : { 2,3,4,5 } ) { + AddUnitToGame(player_t::Red, '>', uvector2(2, y), game); + AddUnitToGame(player_t::Blue, '<', uvector2(7, y), game); + } + + for ( ucoord_t x : { 2,3,4,5 } ) { + AddUnitToGame(player_t::Yellow, '^', uvector2(x,7), game); + AddUnitToGame(player_t::Green, 'v', uvector2(x,2), game); + } + + // Diagonal walls + game.AddWall(uvector2(3,3)); + game.AddWall(uvector2(3,6)); + game.AddWall(uvector2(6,3)); + game.AddWall(uvector2(6,6)); + + // middle walls + game.AddWall(uvector2(4,4)); + game.AddWall(uvector2(4,5)); + game.AddWall(uvector2(5,4)); + game.AddWall(uvector2(5,5)); + + OutputGame(std::move(game)); + } + + // Medium 3 player game + //---------- + //--------Y- + //--------Y- + //---------- + //-G-------- + //-G-------- + //---------- + //--------R- + //--------R- + //---------- + { + CTTRTSGame game(10, 10); + game.SetName("Medium3Player"); + + AddUnitToGame(player_t::Red, '<', uvector2(8, 1), game); + AddUnitToGame(player_t::Red, '<', uvector2(8, 2), game); + AddUnitToGame(player_t::Green, '>', uvector2(1, 4), game); + AddUnitToGame(player_t::Green, '>', uvector2(1, 5), game); + AddUnitToGame(player_t::Yellow, '<', uvector2(8,7), game); + AddUnitToGame(player_t::Yellow, '<', uvector2(8,8), game); + + OutputGame(std::move(game)); + } } \ No newline at end of file From 05c8318099ed1b9a4a0b3f6243fcbdfd3cc2cbe8 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Wed, 31 Dec 2014 18:43:30 +0000 Subject: [PATCH 52/95] Update to v0.3.2 --- CMakeLists.txt | 2 +- README.md | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d72293..01d8a13 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required( VERSION 2.8.7 ) # Set version information set( TTRTS_VERSION_MAJOR 0 ) set( TTRTS_VERSION_MINOR 3 ) -set( TTRTS_VERSION_PATCH 1 ) +set( TTRTS_VERSION_PATCH 2 ) # Use c++1y (14) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++1y" ) diff --git a/README.md b/README.md index f13350c..1f18053 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,13 @@ TTRTS is from the ground up designed to be a fun way to practice programming. An ----------------------------------------------------------- ## Changelog +#### v0.3.2 +* Fix bug when loading map files with walls +* Fix ttrts on OSX + * Install man files to correct location + * Update usage of sed to be compatible with BSD as well as GNU versions +* New maps and renames of old ones + #### v0.3.1 * Upgraded install target to repository * libttrts static library binary in /usr/local/lib From ca5526b2b70cad06aa21835bd64bafe2fa219ccf Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Fri, 2 Jan 2015 13:55:23 +0000 Subject: [PATCH 53/95] Add base files for net code --- source/client/CMakeLists.txt | 7 ++++++- source/client/client.cpp | 1 + source/client/client.h | 4 ++++ source/client/net.cpp | 1 + source/client/net.h | 4 ++++ source/client/server.cpp | 1 + source/client/server.h | 4 ++++ 7 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 source/client/client.cpp create mode 100644 source/client/client.h create mode 100644 source/client/net.cpp create mode 100644 source/client/net.h create mode 100644 source/client/server.cpp create mode 100644 source/client/server.h diff --git a/source/client/CMakeLists.txt b/source/client/CMakeLists.txt index 6549943..53ae704 100644 --- a/source/client/CMakeLists.txt +++ b/source/client/CMakeLists.txt @@ -11,15 +11,20 @@ include_directories( # Add the sources set( SOURCES main.cpp + client.cpp + server.cpp + net.cpp ) -# Set defaults for ttrts maps and games +# 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} ) diff --git a/source/client/client.cpp b/source/client/client.cpp new file mode 100644 index 0000000..a7f5447 --- /dev/null +++ b/source/client/client.cpp @@ -0,0 +1 @@ +#include "client.h" \ No newline at end of file diff --git a/source/client/client.h b/source/client/client.h new file mode 100644 index 0000000..cb8909f --- /dev/null +++ b/source/client/client.h @@ -0,0 +1,4 @@ +#ifndef _TTRTS_CLIENT_H_ +#define _TTRTS_CLIENT_H_ + +#endif \ No newline at end of file diff --git a/source/client/net.cpp b/source/client/net.cpp new file mode 100644 index 0000000..35b5308 --- /dev/null +++ b/source/client/net.cpp @@ -0,0 +1 @@ +#include "net.h" \ No newline at end of file diff --git a/source/client/net.h b/source/client/net.h new file mode 100644 index 0000000..26fdbf0 --- /dev/null +++ b/source/client/net.h @@ -0,0 +1,4 @@ +#ifndef _TTRTS_NET_H_ +#define _TTRTS_NET_H_ + +#endif \ No newline at end of file diff --git a/source/client/server.cpp b/source/client/server.cpp new file mode 100644 index 0000000..e9ea187 --- /dev/null +++ b/source/client/server.cpp @@ -0,0 +1 @@ +#include "server.h" \ No newline at end of file diff --git a/source/client/server.h b/source/client/server.h new file mode 100644 index 0000000..c13c320 --- /dev/null +++ b/source/client/server.h @@ -0,0 +1,4 @@ +#ifndef _TTRTS_SERVER_H_ +#define _TTRTS_SERVER_H_ + +#endif \ No newline at end of file From 3b5599ffad603b167a4bcfebd7885995ce5bcf97 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Fri, 2 Jan 2015 14:04:11 +0000 Subject: [PATCH 54/95] Remove references to non-existent maths --- source/client/CMakeLists.txt | 5 ++--- source/gen/CMakeLists.txt | 5 ++--- source/test/CMakeLists.txt | 3 +-- source/ttrts/CMakeLists.txt | 5 ++--- 4 files changed, 7 insertions(+), 11 deletions(-) diff --git a/source/client/CMakeLists.txt b/source/client/CMakeLists.txt index 53ae704..8fb0953 100644 --- a/source/client/CMakeLists.txt +++ b/source/client/CMakeLists.txt @@ -3,8 +3,7 @@ project( ttrts-client ) include_directories( - ${CMAKE_CURRENT_BINARY_DIR} - ../maths + ${CMAKE_CURRENT_BINARY_DIR} ../ttrts ) @@ -44,4 +43,4 @@ add_custom_target( 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) \ No newline at end of file +add_dependencies(${PROJECT_NAME} ttrts-client-usage) diff --git a/source/gen/CMakeLists.txt b/source/gen/CMakeLists.txt index 466e233..67167f0 100644 --- a/source/gen/CMakeLists.txt +++ b/source/gen/CMakeLists.txt @@ -3,8 +3,7 @@ project( ttrts-gen ) include_directories( - ../ttrts - ../maths + ../ttrts ) set( SOURCES @@ -25,4 +24,4 @@ add_custom_target( add_dependencies(ttrts-gen-maps ${PROJECT_NAME}) # Installation target -install( DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/maps DESTINATION /usr/local/share/ttrts ) \ No newline at end of file +install( DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/maps DESTINATION /usr/local/share/ttrts ) diff --git a/source/test/CMakeLists.txt b/source/test/CMakeLists.txt index 179f7a8..3e6a60c 100644 --- a/source/test/CMakeLists.txt +++ b/source/test/CMakeLists.txt @@ -4,8 +4,7 @@ project( ttrts-test ) include_directories( - ../ttrts - ../maths + ../ttrts ) set( SOURCES diff --git a/source/ttrts/CMakeLists.txt b/source/ttrts/CMakeLists.txt index b528b3f..93a6d94 100644 --- a/source/ttrts/CMakeLists.txt +++ b/source/ttrts/CMakeLists.txt @@ -5,8 +5,7 @@ project( ttrts ) # Include the maths include_directories( - ${CMAKE_CURRENT_BINARY_DIR} - ../maths + ${CMAKE_CURRENT_BINARY_DIR} ) # Add our sources @@ -44,4 +43,4 @@ install( ) # Install the ttrts static lib -install( TARGETS ttrts DESTINATION lib ) \ No newline at end of file +install( TARGETS ttrts DESTINATION lib ) From 0962546a8226a80a8f435e67c6dca66c617af971 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Fri, 2 Jan 2015 14:04:37 +0000 Subject: [PATCH 55/95] Move current client code out to server file, still uses old file-system method --- source/client/main.cpp | 222 +-------------------------------------- source/client/server.cpp | 222 ++++++++++++++++++++++++++++++++++++++- source/client/server.h | 4 + 3 files changed, 230 insertions(+), 218 deletions(-) diff --git a/source/client/main.cpp b/source/client/main.cpp index 35bf5de..d5df140 100644 --- a/source/client/main.cpp +++ b/source/client/main.cpp @@ -1,16 +1,8 @@ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - #include "game.h" +#include "server.h" + +#include +#include #define STRINGIFY(x) _STRINGIFY(x) #define _STRINGIFY(x) #x @@ -18,45 +10,6 @@ static const char* sk_usage = #include "usage.h" ; - -// Verbose mode -static const bool env_verbose = getenv("VERBOSE"); - -// time for waiting between file stats -static const std::chrono::milliseconds sk_waitTime = std::chrono::milliseconds(100); - -// Check if a file exists -inline bool FileExists( const std::string& name ) -{ - struct stat buffer; - return (stat (name.c_str(), &buffer) == 0); -} - -// Wait for a file to exist -inline void WaitForFile( const std::string& name, const std::chrono::milliseconds& time ) -{ - while( !FileExists(name) ) std::this_thread::sleep_for(time); -} - -bool OutputGameStateFile(CTTRTSGame &game, std::string &gameDir) -{ - char turnFileName[128]; - snprintf(turnFileName,128,"%s/Turn_%i.txt",gameDir.c_str(),game.GetTurn()); - std::ofstream turnFile(turnFileName, std::ios_base::trunc); // truncate to overwrite if a file exists - - if ( turnFile.bad() ) - { - return false; - } - - // Output the turn description - std::string turnDescriptor = GetStringFromGame(game); - - turnFile<(file)),std::istreambuf_iterator()); - - if( gameDescriptor.size() == 0 ) - { - std::cerr<<"Error: failed to read in any information from "<>input; - if( !input.size() || std::tolower(input[0]) != 'y' ) - { - std::cerr<<"Aborting..."<(turnFile)),std::istreambuf_iterator()); - - // Issue the orders to the game - if( game.IssueOrders(player, orders) ) - std::cerr<<"Warning: Orders for player "<<(int) player <<" failed to correctly parse"< +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +// time for waiting between file stats +static const std::chrono::milliseconds sk_waitTime = std::chrono::milliseconds(100); + +// Check if a file exists +inline bool FileExists( const std::string& name ) +{ + struct stat buffer; + return (stat (name.c_str(), &buffer) == 0); +} + +// Wait for a file to exist +inline void WaitForFile( const std::string& name, const std::chrono::milliseconds& time ) +{ + while( !FileExists(name) ) std::this_thread::sleep_for(time); +} + +bool OutputGameStateFile(CTTRTSGame &game, const std::string &gameDir) +{ + char turnFileName[128]; + snprintf(turnFileName,128,"%s/Turn_%i.txt",gameDir.c_str(),game.GetTurn()); + std::ofstream turnFile(turnFileName, std::ios_base::trunc); // truncate to overwrite if a file exists + + if ( turnFile.bad() ) + { + return false; + } + + // Output the turn description + std::string turnDescriptor = GetStringFromGame(game); + + turnFile<(file)),std::istreambuf_iterator()); + + if( gameDescriptor.size() == 0 ) + { + std::cerr<<"Error: failed to read in any information from "<>input; + if( !input.size() || std::tolower(input[0]) != 'y' ) + { + std::cerr<<"Aborting..."<(turnFile)),std::istreambuf_iterator()); + + // Issue the orders to the game + if( game.IssueOrders(player, orders) ) + std::cerr<<"Warning: Orders for player "<<(int) player <<" failed to correctly parse"< + +int runServer(const std::string& dir,const std::string& file); + #endif \ No newline at end of file From 8835bfb82aa4af52b7d1ac106b82adaa3450dd94 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Fri, 2 Jan 2015 14:09:29 +0000 Subject: [PATCH 56/95] On second thoughts move filesystem game code out to a filesystem cpp --- source/client/CMakeLists.txt | 1 + source/client/filesystem.cpp | 222 +++++++++++++++++++++++++++++++++++ source/client/filesystem.h | 8 ++ source/client/main.cpp | 4 +- source/client/server.cpp | 222 +---------------------------------- source/client/server.h | 4 - 6 files changed, 234 insertions(+), 227 deletions(-) create mode 100644 source/client/filesystem.cpp create mode 100644 source/client/filesystem.h diff --git a/source/client/CMakeLists.txt b/source/client/CMakeLists.txt index 8fb0953..e524304 100644 --- a/source/client/CMakeLists.txt +++ b/source/client/CMakeLists.txt @@ -13,6 +13,7 @@ set( SOURCES client.cpp server.cpp net.cpp + filesystem.cpp ) # Set defaults for ttrts variables diff --git a/source/client/filesystem.cpp b/source/client/filesystem.cpp new file mode 100644 index 0000000..59ac6b8 --- /dev/null +++ b/source/client/filesystem.cpp @@ -0,0 +1,222 @@ +#include "filesystem.h" + + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +// time for waiting between file stats +static const std::chrono::milliseconds sk_waitTime = std::chrono::milliseconds(100); + +// Check if a file exists +inline bool FileExists( const std::string& name ) +{ + struct stat buffer; + return (stat (name.c_str(), &buffer) == 0); +} + +// Wait for a file to exist +inline void WaitForFile( const std::string& name, const std::chrono::milliseconds& time ) +{ + while( !FileExists(name) ) std::this_thread::sleep_for(time); +} + +bool OutputGameStateFile(CTTRTSGame &game, const std::string &gameDir) +{ + char turnFileName[128]; + snprintf(turnFileName,128,"%s/Turn_%i.txt",gameDir.c_str(),game.GetTurn()); + std::ofstream turnFile(turnFileName, std::ios_base::trunc); // truncate to overwrite if a file exists + + if ( turnFile.bad() ) + { + return false; + } + + // Output the turn description + std::string turnDescriptor = GetStringFromGame(game); + + turnFile<(file)),std::istreambuf_iterator()); + + if( gameDescriptor.size() == 0 ) + { + std::cerr<<"Error: failed to read in any information from "<>input; + if( !input.size() || std::tolower(input[0]) != 'y' ) + { + std::cerr<<"Aborting..."<(turnFile)),std::istreambuf_iterator()); + + // Issue the orders to the game + if( game.IssueOrders(player, orders) ) + std::cerr<<"Warning: Orders for player "<<(int) player <<" failed to correctly parse"< + +int runFromFilesystem( const std::string& directory, const std::string gamefile ); + +#endif \ No newline at end of file diff --git a/source/client/main.cpp b/source/client/main.cpp index d5df140..8c31966 100644 --- a/source/client/main.cpp +++ b/source/client/main.cpp @@ -1,5 +1,5 @@ #include "game.h" -#include "server.h" +#include "filesystem.h" #include #include @@ -60,6 +60,6 @@ int main(int argc, char* argv[]) return -1; } - return runServer(ttrts_games_dir, gameFile); + return runFromFilesystem(ttrts_games_dir, gameFile); }; diff --git a/source/client/server.cpp b/source/client/server.cpp index 678d4f1..e9ea187 100644 --- a/source/client/server.cpp +++ b/source/client/server.cpp @@ -1,221 +1 @@ -#include "server.h" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -// time for waiting between file stats -static const std::chrono::milliseconds sk_waitTime = std::chrono::milliseconds(100); - -// Check if a file exists -inline bool FileExists( const std::string& name ) -{ - struct stat buffer; - return (stat (name.c_str(), &buffer) == 0); -} - -// Wait for a file to exist -inline void WaitForFile( const std::string& name, const std::chrono::milliseconds& time ) -{ - while( !FileExists(name) ) std::this_thread::sleep_for(time); -} - -bool OutputGameStateFile(CTTRTSGame &game, const std::string &gameDir) -{ - char turnFileName[128]; - snprintf(turnFileName,128,"%s/Turn_%i.txt",gameDir.c_str(),game.GetTurn()); - std::ofstream turnFile(turnFileName, std::ios_base::trunc); // truncate to overwrite if a file exists - - if ( turnFile.bad() ) - { - return false; - } - - // Output the turn description - std::string turnDescriptor = GetStringFromGame(game); - - turnFile<(file)),std::istreambuf_iterator()); - - if( gameDescriptor.size() == 0 ) - { - std::cerr<<"Error: failed to read in any information from "<>input; - if( !input.size() || std::tolower(input[0]) != 'y' ) - { - std::cerr<<"Aborting..."<(turnFile)),std::istreambuf_iterator()); - - // Issue the orders to the game - if( game.IssueOrders(player, orders) ) - std::cerr<<"Warning: Orders for player "<<(int) player <<" failed to correctly parse"< - -int runServer(const std::string& dir,const std::string& file); - #endif \ No newline at end of file From 2281bcb6cd7affcc6d0d8a6c2b74147c6bfbe928 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Fri, 2 Jan 2015 15:03:29 +0000 Subject: [PATCH 57/95] More refactoring of functionality into seperate files, with stubs for server and client --- source/client/client.cpp | 8 ++++- source/client/client.h | 4 +++ source/client/filesystem.cpp | 60 +++++++++++++++++++++++++++++++++--- source/client/filesystem.h | 17 +++++++++- source/client/main.cpp | 48 ++++++----------------------- source/client/server.cpp | 7 ++++- source/client/server.h | 2 ++ 7 files changed, 101 insertions(+), 45 deletions(-) diff --git a/source/client/client.cpp b/source/client/client.cpp index a7f5447..8a59232 100644 --- a/source/client/client.cpp +++ b/source/client/client.cpp @@ -1 +1,7 @@ -#include "client.h" \ No newline at end of file +#include "client.h" + + +int runClient( const std::string& host_address ) +{ + return 0; +} \ No newline at end of file diff --git a/source/client/client.h b/source/client/client.h index cb8909f..bd30a06 100644 --- a/source/client/client.h +++ b/source/client/client.h @@ -1,4 +1,8 @@ #ifndef _TTRTS_CLIENT_H_ #define _TTRTS_CLIENT_H_ +#include + +int runClient( const std::string& host_address ); + #endif \ No newline at end of file diff --git a/source/client/filesystem.cpp b/source/client/filesystem.cpp index 59ac6b8..a2abd1f 100644 --- a/source/client/filesystem.cpp +++ b/source/client/filesystem.cpp @@ -13,18 +13,19 @@ #include #include +// ===================================================================================================================== // time for waiting between file stats static const std::chrono::milliseconds sk_waitTime = std::chrono::milliseconds(100); // Check if a file exists -inline bool FileExists( const std::string& name ) +bool FileExists( const std::string& name ) { struct stat buffer; return (stat (name.c_str(), &buffer) == 0); } // Wait for a file to exist -inline void WaitForFile( const std::string& name, const std::chrono::milliseconds& time ) +void WaitForFile( const std::string& name, const std::chrono::milliseconds& time ) { while( !FileExists(name) ) std::this_thread::sleep_for(time); } @@ -49,8 +50,59 @@ bool OutputGameStateFile(CTTRTSGame &game, const std::string &gameDir) return true; } -int runFromFilesystem( const std::string& directory, const std::string gamefile ) +std::string getMapsDir() { + std::string maps = STRINGIFY(TTRTS_MAPS); + if( getenv("TTRTS_MAPS") ) + { + maps = getenv("TTRTS_MAPS"); + + // Additional trailing slash + if( maps.back() != '/' ) + maps += "/"; + } + + return maps; +} + +std::string getGamesDir() +{ + std::string dir = STRINGIFY(TTRTS_GAMES); + if( getenv("TTRTS_GAMES") ) + { + dir = getenv("TTRTS_GAMES"); + + // Additional trailing slash + if( dir.back() != '/' ) + dir += "/"; + } + return dir; +} + +// ===================================================================================================================== +int runFromFilesystem( const std::string& gamestring ) +{ + std::string gamefile = gamestring; + + // Default for maps + std::string ttrts_maps_dir = getMapsDir(); + + // Default for games + std::string ttrts_games_dir = getGamesDir(); + + // If file path is not local path and file doesn't exist + if( gamefile.find("/") == std::string::npos + && access( gamefile.c_str(), F_OK ) == -1 ) + { + gamefile = ttrts_maps_dir + gamefile; + } + + // If still not good + if( access( gamefile.c_str(), F_OK ) == -1 ) + { + std::cerr<<"Error: "<< gamefile <<" file not found"< +#include -int runFromFilesystem( const std::string& directory, const std::string gamefile ); +#include "game.h" + +#define STRINGIFY(x) _STRINGIFY(x) +#define _STRINGIFY(x) #x + +bool FileExists( const std::string& name ); + +void WaitForFile( const std::string& name, const std::chrono::milliseconds& time ); + +int runFromFilesystem( const std::string& gamefile ); + +bool OutputGameStateFile(CTTRTSGame &game, const std::string &gameDir); + +std::string getMapsDir(); +std::string getGamesDir(); #endif \ No newline at end of file diff --git a/source/client/main.cpp b/source/client/main.cpp index 8c31966..0d78823 100644 --- a/source/client/main.cpp +++ b/source/client/main.cpp @@ -1,11 +1,9 @@ #include "game.h" #include "filesystem.h" +#include "server.h" +#include "client.h" #include -#include - -#define STRINGIFY(x) _STRINGIFY(x) -#define _STRINGIFY(x) #x static const char* sk_usage = #include "usage.h" @@ -22,44 +20,18 @@ int main(int argc, char* argv[]) } // Attempt to open the game file - std::string gameFile = argv[1]; + std::string arg1 = argv[1]; - // Default for maps - std::string ttrts_maps_dir = STRINGIFY(TTRTS_MAPS); - if( getenv("TTRTS_MAPS") ) + if( arg1 == "client" ) { - ttrts_maps_dir = getenv("TTRTS_MAPS"); - - // Additional trailing slash - if( ttrts_maps_dir.back() != '/' ) - ttrts_maps_dir += "/"; + if( argc == 3 ) + return runClient(argv[2]); } - - // Default for games - std::string ttrts_games_dir = STRINGIFY(TTRTS_GAMES); - if( getenv("TTRTS_GAMES") ) + else if ( arg1 == "server" ) { - ttrts_games_dir = getenv("TTRTS_GAMES"); - - // Additional trailing slash - if( ttrts_games_dir.back() != '/' ) - ttrts_games_dir += "/"; + return runServer(); } - - // If file path is not local path and file doesn't exist - if( gameFile.find("/") == std::string::npos - && access( gameFile.c_str(), F_OK ) == -1 ) - { - gameFile = ttrts_maps_dir + gameFile; - } - - // If still not good - if( access( gameFile.c_str(), F_OK ) == -1 ) - { - std::cerr<<"Error: "< Date: Fri, 2 Jan 2015 15:06:04 +0000 Subject: [PATCH 58/95] Use argc and argv passed down --- source/client/client.cpp | 2 +- source/client/client.h | 2 +- source/client/filesystem.cpp | 4 ++-- source/client/filesystem.h | 4 ++-- source/client/main.cpp | 12 ++++-------- source/client/server.cpp | 4 ++-- source/client/server.h | 2 +- 7 files changed, 13 insertions(+), 17 deletions(-) diff --git a/source/client/client.cpp b/source/client/client.cpp index 8a59232..fdfeeb1 100644 --- a/source/client/client.cpp +++ b/source/client/client.cpp @@ -1,7 +1,7 @@ #include "client.h" -int runClient( const std::string& host_address ) +int runClient(int argc, char* argv[]) { return 0; } \ No newline at end of file diff --git a/source/client/client.h b/source/client/client.h index bd30a06..ab1e336 100644 --- a/source/client/client.h +++ b/source/client/client.h @@ -3,6 +3,6 @@ #include -int runClient( const std::string& host_address ); +int runClient(int argc, char* argv[]); #endif \ No newline at end of file diff --git a/source/client/filesystem.cpp b/source/client/filesystem.cpp index a2abd1f..6bd7111 100644 --- a/source/client/filesystem.cpp +++ b/source/client/filesystem.cpp @@ -80,9 +80,9 @@ std::string getGamesDir() } // ===================================================================================================================== -int runFromFilesystem( const std::string& gamestring ) +int runFromFilesystem(int argc, char* argv[]) { - std::string gamefile = gamestring; + std::string gamefile = argv[1]; // Default for maps std::string ttrts_maps_dir = getMapsDir(); diff --git a/source/client/filesystem.h b/source/client/filesystem.h index 4204ef9..d6a2ff9 100644 --- a/source/client/filesystem.h +++ b/source/client/filesystem.h @@ -13,11 +13,11 @@ bool FileExists( const std::string& name ); void WaitForFile( const std::string& name, const std::chrono::milliseconds& time ); -int runFromFilesystem( const std::string& gamefile ); - bool OutputGameStateFile(CTTRTSGame &game, const std::string &gameDir); std::string getMapsDir(); std::string getGamesDir(); +int runFromFilesystem(int argc, char* argv[]); + #endif \ No newline at end of file diff --git a/source/client/main.cpp b/source/client/main.cpp index 0d78823..218cab5 100644 --- a/source/client/main.cpp +++ b/source/client/main.cpp @@ -22,16 +22,12 @@ int main(int argc, char* argv[]) // Attempt to open the game file std::string arg1 = argv[1]; + // Either run the client, the server, or from local filesystem if( arg1 == "client" ) - { - if( argc == 3 ) - return runClient(argv[2]); - } + return runClient(argc,argv+1); else if ( arg1 == "server" ) - { - return runServer(); - } + return runServer(argc,argv+1); else - return runFromFilesystem(arg1); + return runFromFilesystem(argc,argv); }; diff --git a/source/client/server.cpp b/source/client/server.cpp index 1e62b61..be07929 100644 --- a/source/client/server.cpp +++ b/source/client/server.cpp @@ -1,6 +1,6 @@ #include "server.h" -int runServer() +int runServer(int argc, char* argv[]) { - + return 0; } \ No newline at end of file diff --git a/source/client/server.h b/source/client/server.h index 4f3af0e..54452c7 100644 --- a/source/client/server.h +++ b/source/client/server.h @@ -1,6 +1,6 @@ #ifndef _TTRTS_SERVER_H_ #define _TTRTS_SERVER_H_ -int runServer(); +int runServer(int argc, char* argv[]); #endif \ No newline at end of file From b4240cf1c80caf5e64dd444baf0f31429bb923d5 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Fri, 2 Jan 2015 15:13:05 +0000 Subject: [PATCH 59/95] pull in very simple client/server demo code inspired by http://www.linuxhowtos.org/C_C++/socket.htm --- source/client/client.cpp | 78 +++++++++++++++++++++++++++++++++++ source/client/client.h | 2 - source/client/main.cpp | 4 +- source/client/net.h | 9 +++++ source/client/server.cpp | 87 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 176 insertions(+), 4 deletions(-) diff --git a/source/client/client.cpp b/source/client/client.cpp index fdfeeb1..3e846de 100644 --- a/source/client/client.cpp +++ b/source/client/client.cpp @@ -1,7 +1,85 @@ #include "client.h" +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "net.h" int runClient(int argc, char* argv[]) { + int sockfd; // socket File descriptor + int portno; // Port number + int n = 0; // return value for read and write calls + + struct sockaddr_in serv_addr; // Server address + + struct hostent *server; // pointer to host information + + char buffer[1028]; // buffer for socked read + memset(buffer,0,sizeof(buffer)); + + // must provide information + if (argc < 2) + { + fprintf(stderr,"usage %s hostname\n", argv[0]); + exit(0); + } + + // Get port number + portno = 11715; + + // Create a new socket + // AF_INET is general internetsocked domain + // SOCK_STREAM as messages will be read in on this socket, SOCK_DGRAM would be for packets + // 0 is for default protocol + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd < 0) + error("ERROR opening socket"); + + // Get the hostent information for the host by name + server = gethostbyname(argv[1]); + if (server == NULL) + error("ERROR, no such host"); + + // Empty the server address struct + memset(&serv_addr,0, sizeof(serv_addr)); + + // Set the server to AF_INET + serv_addr.sin_family = AF_INET; + + // copy the server address into our server_addr struct + memcpy(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length); + + // Set our server address port to the port number provided + serv_addr.sin_port = htons(portno); + + // Attempt to connect to the server using the socket and server address info + if (connect(sockfd, (const sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) + error("ERROR connecting"); + + while ( n >= 0 ) + { + // Get the message to send + printf("Please enter the message: "); + memset(buffer,0,sizeof(buffer)); + fgets(buffer,sizeof(buffer)-1,stdin); + + // Place a test message into the buffer + strncpy(buffer,buffer,sizeof(buffer)); + + // Write to the socket with the buffer + n = write(sockfd,buffer,strlen(buffer)); + if (n < 0) + error("ERROR writing to socket"); + } + return 0; } \ No newline at end of file diff --git a/source/client/client.h b/source/client/client.h index ab1e336..201c0d9 100644 --- a/source/client/client.h +++ b/source/client/client.h @@ -1,8 +1,6 @@ #ifndef _TTRTS_CLIENT_H_ #define _TTRTS_CLIENT_H_ -#include - int runClient(int argc, char* argv[]); #endif \ No newline at end of file diff --git a/source/client/main.cpp b/source/client/main.cpp index 218cab5..cfa69e3 100644 --- a/source/client/main.cpp +++ b/source/client/main.cpp @@ -24,9 +24,9 @@ int main(int argc, char* argv[]) // Either run the client, the server, or from local filesystem if( arg1 == "client" ) - return runClient(argc,argv+1); + return runClient(argc-1,argv+1); else if ( arg1 == "server" ) - return runServer(argc,argv+1); + return runServer(argc-1,argv+1); else return runFromFilesystem(argc,argv); diff --git a/source/client/net.h b/source/client/net.h index 26fdbf0..613486f 100644 --- a/source/client/net.h +++ b/source/client/net.h @@ -1,4 +1,13 @@ #ifndef _TTRTS_NET_H_ #define _TTRTS_NET_H_ +#include +#include + +inline void error(const char *msg) +{ + perror(msg); + exit(1); +} + #endif \ No newline at end of file diff --git a/source/client/server.cpp b/source/client/server.cpp index be07929..dfac689 100644 --- a/source/client/server.cpp +++ b/source/client/server.cpp @@ -1,6 +1,93 @@ #include "server.h" +#include +#include +#include +#include + +#include +#include + +#include + +#include "net.h" + int runServer(int argc, char* argv[]) { + int sockfd; // socket File descriptor + int newsockfd; // new socket File descriptor + + int portno; // Port number + socklen_t clilen; // length of client address + clilen = sizeof(sockaddr_in); + + int n = 0; // return value for read and write calls + + char buffer[1028]; // buffer for socked read + memset(buffer,0,sizeof(buffer)); + + struct sockaddr_in serv_addr; // Server address + struct sockaddr_in cli_addr; // Client address + + // Create a new socket + // AF_INET is general internetsocked domain + // SOCK_STREAM as messages will be read in on this socket, SOCK_DGRAM would be for packets + // 0 is for default protocol + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd < 0) + error("ERROR opening socket"); + + // empty the server address + memset(&serv_addr,0, sizeof(serv_addr)); + + // Grab the port number + portno = 11715; + + // Set the server address family to AF_INET + serv_addr.sin_family = AF_INET; + + // Set the port number + // htons swaps from host byte order to network byte order + serv_addr.sin_port = htons(portno); + + // The host for this address is this current machines's IP + // INADDR_ANY fetches this + serv_addr.sin_addr.s_addr = INADDR_ANY; + + // bind out socket to this server address + if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) + error("ERROR on binding"); + + // Listen on the socket for messages + // Second param is length of backlog queue, the maximum number of connections + // that can be waiting while the process is handling a single connection + // max is usually set to 5 + listen(sockfd,5); + + // accept waits for a connection from a client + // it returns a new socket file descriptor for this connection + // client information will be stored in cli_addr + newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); + if (newsockfd < 0) + error("ERROR on accept"); + + // loop + while( n >= 0 ) + { + // empty the buffer + memset(buffer,0,sizeof(buffer)); + + // Read in the new socket + // read will block until the client has called write + // up to the full size of the buffer + n = read(newsockfd,buffer,sizeof(buffer)-1); + if (n < 0) + error("ERROR reading from socket"); + + // print the message recieved + printf("%s",buffer); + } + + // Return return 0; } \ No newline at end of file From 83b9990bcc27960fc42ac3c32fe9db8e4a2d3054 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Fri, 2 Jan 2015 15:25:30 +0000 Subject: [PATCH 60/95] some more cleanup and using TTRTS_PORT --- source/client/client.cpp | 2 +- source/client/server.cpp | 24 +++++++++++++----------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/source/client/client.cpp b/source/client/client.cpp index 3e846de..dccaeff 100644 --- a/source/client/client.cpp +++ b/source/client/client.cpp @@ -34,7 +34,7 @@ int runClient(int argc, char* argv[]) } // Get port number - portno = 11715; + portno = TTRTS_PORT; // Create a new socket // AF_INET is general internetsocked domain diff --git a/source/client/server.cpp b/source/client/server.cpp index dfac689..f9ed4b5 100644 --- a/source/client/server.cpp +++ b/source/client/server.cpp @@ -14,23 +14,25 @@ int runServer(int argc, char* argv[]) { - int sockfd; // socket File descriptor - int newsockfd; // new socket File descriptor + // Server side information + int sockfd; // socket File descriptor + sockaddr_in serv_addr; // Server address + int portno; // Port number - int portno; // Port number + // information for each client + sockaddr_in cli_addr; // Client address socklen_t clilen; // length of client address - clilen = sizeof(sockaddr_in); + int clientsockfd; // new socket File descriptor + int n = 0; // return value for read and write calls char buffer[1028]; // buffer for socked read memset(buffer,0,sizeof(buffer)); - struct sockaddr_in serv_addr; // Server address - struct sockaddr_in cli_addr; // Client address // Create a new socket - // AF_INET is general internetsocked domain + // AF_INET is general internet socket domain // SOCK_STREAM as messages will be read in on this socket, SOCK_DGRAM would be for packets // 0 is for default protocol sockfd = socket(AF_INET, SOCK_STREAM, 0); @@ -41,7 +43,7 @@ int runServer(int argc, char* argv[]) memset(&serv_addr,0, sizeof(serv_addr)); // Grab the port number - portno = 11715; + portno = TTRTS_PORT; // Set the server address family to AF_INET serv_addr.sin_family = AF_INET; @@ -67,8 +69,8 @@ int runServer(int argc, char* argv[]) // accept waits for a connection from a client // it returns a new socket file descriptor for this connection // client information will be stored in cli_addr - newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); - if (newsockfd < 0) + clientsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); + if (clientsockfd < 0) error("ERROR on accept"); // loop @@ -80,7 +82,7 @@ int runServer(int argc, char* argv[]) // Read in the new socket // read will block until the client has called write // up to the full size of the buffer - n = read(newsockfd,buffer,sizeof(buffer)-1); + n = read(clientsockfd,buffer,sizeof(buffer)-1); if (n < 0) error("ERROR reading from socket"); From dcb9d68fb48e7086f52859dcd3afd04daae74705 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Fri, 2 Jan 2015 16:09:24 +0000 Subject: [PATCH 61/95] Revert back to cleaner copy of server code --- source/client/CMakeLists.txt | 6 +++--- source/client/client.cpp | 4 ++++ source/client/server.cpp | 29 ++++++++++++++--------------- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/source/client/CMakeLists.txt b/source/client/CMakeLists.txt index e524304..92360c6 100644 --- a/source/client/CMakeLists.txt +++ b/source/client/CMakeLists.txt @@ -17,9 +17,9 @@ set( SOURCES ) # Set defaults for ttrts variables -set( TTRTS_MAPS "/usr/local/share/ttrts/maps/" ) -set( TTRTS_GAMES "/tmp/" ) -set( TTRTS_PORT 11715 ) +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}" ) diff --git a/source/client/client.cpp b/source/client/client.cpp index dccaeff..ab20334 100644 --- a/source/client/client.cpp +++ b/source/client/client.cpp @@ -1,5 +1,7 @@ #include "client.h" +#include + #include #include #include @@ -49,6 +51,8 @@ int runClient(int argc, char* argv[]) if (server == NULL) error("ERROR, no such host"); + std::cout<<"Connecting to "< + #include #include #include @@ -9,21 +11,21 @@ #include #include +#include #include "net.h" int runServer(int argc, char* argv[]) { - // Server side information - int sockfd; // socket File descriptor - sockaddr_in serv_addr; // Server address - int portno; // Port number + sockaddr_in serv_addr; // Server address + int sockfd; // socket File descriptor + int portno = TTRTS_PORT; // Port number - // information for each client - sockaddr_in cli_addr; // Client address + struct sockaddr_in cli_addr; // Client address + int newsockfd; // new socket File descriptor socklen_t clilen; // length of client address - int clientsockfd; // new socket File descriptor + clilen = sizeof(sockaddr_in); int n = 0; // return value for read and write calls @@ -32,7 +34,7 @@ int runServer(int argc, char* argv[]) // Create a new socket - // AF_INET is general internet socket domain + // AF_INET is general internetsocked domain // SOCK_STREAM as messages will be read in on this socket, SOCK_DGRAM would be for packets // 0 is for default protocol sockfd = socket(AF_INET, SOCK_STREAM, 0); @@ -41,10 +43,7 @@ int runServer(int argc, char* argv[]) // empty the server address memset(&serv_addr,0, sizeof(serv_addr)); - - // Grab the port number - portno = TTRTS_PORT; - + // Set the server address family to AF_INET serv_addr.sin_family = AF_INET; @@ -69,8 +68,8 @@ int runServer(int argc, char* argv[]) // accept waits for a connection from a client // it returns a new socket file descriptor for this connection // client information will be stored in cli_addr - clientsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); - if (clientsockfd < 0) + newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); + if (newsockfd < 0) error("ERROR on accept"); // loop @@ -82,7 +81,7 @@ int runServer(int argc, char* argv[]) // Read in the new socket // read will block until the client has called write // up to the full size of the buffer - n = read(clientsockfd,buffer,sizeof(buffer)-1); + n = read(newsockfd,buffer,sizeof(buffer)-1); if (n < 0) error("ERROR reading from socket"); From 4285770d529f2102fb55ecdc1ea3852d4ee2a6a2 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Fri, 2 Jan 2015 16:18:18 +0000 Subject: [PATCH 62/95] Allow multiple client connections on different threads --- source/client/CMakeLists.txt | 2 +- source/client/server.cpp | 143 ++++++++++++++++++++++------------- 2 files changed, 91 insertions(+), 54 deletions(-) diff --git a/source/client/CMakeLists.txt b/source/client/CMakeLists.txt index 92360c6..7f26ed1 100644 --- a/source/client/CMakeLists.txt +++ b/source/client/CMakeLists.txt @@ -33,7 +33,7 @@ add_executable( ${PROJECT_NAME} ${SOURCES} ) set_target_properties( ${PROJECT_NAME} PROPERTIES OUTPUT_NAME ttrts ) # dependent on main ttrts libary -target_link_libraries( ${PROJECT_NAME} ttrts ) +target_link_libraries( ${PROJECT_NAME} ttrts pthread ) # Installation target install( TARGETS ${PROJECT_NAME} DESTINATION bin ) diff --git a/source/client/server.cpp b/source/client/server.cpp index 2a4edf7..9dabe82 100644 --- a/source/client/server.cpp +++ b/source/client/server.cpp @@ -1,5 +1,7 @@ #include "server.h" +#include +#include #include #include @@ -15,64 +17,17 @@ #include "net.h" -int runServer(int argc, char* argv[]) +std::vector gClientThreads; + +int clientHandler( sockaddr_in cli_addr, socklen_t clilen, int clientsockfd) { - sockaddr_in serv_addr; // Server address - int sockfd; // socket File descriptor - int portno = TTRTS_PORT; // Port number - - struct sockaddr_in cli_addr; // Client address - int newsockfd; // new socket File descriptor - socklen_t clilen; // length of client address - - clilen = sizeof(sockaddr_in); - - int n = 0; // return value for read and write calls + std::cout<<"Client connected from "<= 0 ) { // empty the buffer @@ -81,7 +36,7 @@ int runServer(int argc, char* argv[]) // Read in the new socket // read will block until the client has called write // up to the full size of the buffer - n = read(newsockfd,buffer,sizeof(buffer)-1); + n = read(clientsockfd,buffer,sizeof(buffer)-1); if (n < 0) error("ERROR reading from socket"); @@ -89,6 +44,88 @@ int runServer(int argc, char* argv[]) printf("%s",buffer); } + return 0; +} + +int runServer(int argc, char* argv[]) +{ + std::cout<<"Setting up server on port "< 10) + { + error("Binding failed after retries"); + } + + if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) >= 0) + break; + + std::cout<<"Binding failed on try "< Date: Fri, 2 Jan 2015 17:14:16 +0000 Subject: [PATCH 63/95] Clients now connect and recieve gamestate information --- source/client/client.cpp | 13 ++++- source/client/filesystem.cpp | 28 +++++---- source/client/filesystem.h | 2 + source/client/server.cpp | 109 +++++++++++++++++++++++++---------- source/gen/gen.cpp | 2 +- 5 files changed, 109 insertions(+), 45 deletions(-) diff --git a/source/client/client.cpp b/source/client/client.cpp index ab20334..9401df2 100644 --- a/source/client/client.cpp +++ b/source/client/client.cpp @@ -71,10 +71,17 @@ int runClient(int argc, char* argv[]) while ( n >= 0 ) { - // Get the message to send - printf("Please enter the message: "); memset(buffer,0,sizeof(buffer)); - fgets(buffer,sizeof(buffer)-1,stdin); + + // Receive gamestate + if (read(sockfd,buffer,sizeof(buffer)-1) < 0) + error("ERROR reading from client"); + + std::cout< #include #include +#include #include #include @@ -14,35 +15,35 @@ #include #include +#include +#include #include "net.h" +#include "filesystem.h" -std::vector gClientThreads; - -int clientHandler( sockaddr_in cli_addr, socklen_t clilen, int clientsockfd) +// Struct for net client info +struct ClientInfo { - std::cout<<"Client connected from "<= 0 ) - { - // empty the buffer - memset(buffer,0,sizeof(buffer)); + // Read in the new socket + // read will block until the client has called write + // up to the full size of the buffer + if (read(info.clientsockfd,buffer,sizeof(buffer)-1) < 0) + error("ERROR reading from client"); - // Read in the new socket - // read will block until the client has called write - // up to the full size of the buffer - n = read(clientsockfd,buffer,sizeof(buffer)-1); - if (n < 0) - error("ERROR reading from socket"); + std::cout<<"Recieved orders from "< myClients; + std::cout<<"Waiting for clients"< clientThreads; + for(auto client : myClients) + { + std::thread clientThread(waitForOrdersFromClient,std::ref(client), std::ref(gameMutex), std::ref(game)); + clientThreads.push_back(std::move(clientThread)); + } + + // Join up all the threads + for ( std::thread& thread : clientThreads ) + { + thread.join(); + } + + // Step to the next turn + gameMutex.lock(); + game.SimulateToNextTurn(); + gameMutex.unlock(); + } + + + // end game and disconnect clients + // Return return 0; } \ No newline at end of file diff --git a/source/gen/gen.cpp b/source/gen/gen.cpp index 8265a53..0f782b8 100644 --- a/source/gen/gen.cpp +++ b/source/gen/gen.cpp @@ -33,7 +33,7 @@ int main() //------ { CTTRTSGame game(6, 6); - game.SetName("Tiny2player"); + game.SetName("Tiny2Player"); AddUnitToGame( player_t::Red, '<', uvector2(4, 2), game); AddUnitToGame( player_t::Red, '<', uvector2(4, 4), game); From e01a718ac6240e9e58a3e49012727b06052dd3ad Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Fri, 2 Jan 2015 18:57:47 +0000 Subject: [PATCH 64/95] Fix bug where we passed client info to the thread by ref, like an ape --- source/client/client.cpp | 17 ++++++++++------- source/client/server.cpp | 10 +++++++--- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/source/client/client.cpp b/source/client/client.cpp index 9401df2..241c002 100644 --- a/source/client/client.cpp +++ b/source/client/client.cpp @@ -39,13 +39,15 @@ int runClient(int argc, char* argv[]) portno = TTRTS_PORT; // Create a new socket - // AF_INET is general internetsocked domain + // AF_INET is general internetsocket domain // SOCK_STREAM as messages will be read in on this socket, SOCK_DGRAM would be for packets // 0 is for default protocol sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) error("ERROR opening socket"); + std::cout<<"Opened socket on "< clientThreads; for(auto client : myClients) { - std::thread clientThread(waitForOrdersFromClient,std::ref(client), std::ref(gameMutex), std::ref(game)); + std::thread clientThread(waitForOrdersFromClient, client, std::ref(gameMutex), std::ref(game)); clientThreads.push_back(std::move(clientThread)); } @@ -166,6 +169,7 @@ int runServer(int argc, char* argv[]) thread.join(); } + std::cout<<"Orders recieved, simulating turn"< Date: Fri, 2 Jan 2015 19:00:28 +0000 Subject: [PATCH 65/95] Handle end game state properly --- source/client/server.cpp | 46 ++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/source/client/server.cpp b/source/client/server.cpp index 7c291b1..89cef9e 100644 --- a/source/client/server.cpp +++ b/source/client/server.cpp @@ -28,6 +28,23 @@ struct ClientInfo int clientsockfd; }; +void SendGameInfoToClients(std::vector &myClients, const CTTRTSGame &game, std::mutex &gameMutex) +{ + // Spawn threads + std::vector clientThreads; + for(auto client : myClients) + { + std::thread clientThread(waitForOrdersFromClient, client, ref(gameMutex), std::ref(game)); + clientThreads.push_back(move(clientThread)); + } + + // Join up all the threads + for ( std::thread& thread : clientThreads ) + { + thread.join(); + } +} + int waitForOrdersFromClient(const ClientInfo info, std::mutex& mut, CTTRTSGame& game ) { char buffer[1028]; // buffer for orders @@ -156,28 +173,31 @@ int runServer(int argc, char* argv[]) // Wait for orders from clients std::cout<<"Waiting for client orders"< clientThreads; - for(auto client : myClients) - { - std::thread clientThread(waitForOrdersFromClient, client, std::ref(gameMutex), std::ref(game)); - clientThreads.push_back(std::move(clientThread)); - } - - // Join up all the threads - for ( std::thread& thread : clientThreads ) - { - thread.join(); - } + SendGameInfoToClients(myClients, game, gameMutex); std::cout<<"Orders recieved, simulating turn"< Date: Fri, 2 Jan 2015 19:05:58 +0000 Subject: [PATCH 66/95] Fix server functions being used wrongly --- source/client/server.cpp | 65 +++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/source/client/server.cpp b/source/client/server.cpp index 89cef9e..ecfef7f 100644 --- a/source/client/server.cpp +++ b/source/client/server.cpp @@ -28,24 +28,7 @@ struct ClientInfo int clientsockfd; }; -void SendGameInfoToClients(std::vector &myClients, const CTTRTSGame &game, std::mutex &gameMutex) -{ - // Spawn threads - std::vector clientThreads; - for(auto client : myClients) - { - std::thread clientThread(waitForOrdersFromClient, client, ref(gameMutex), std::ref(game)); - clientThreads.push_back(move(clientThread)); - } - - // Join up all the threads - for ( std::thread& thread : clientThreads ) - { - thread.join(); - } -} - -int waitForOrdersFromClient(const ClientInfo info, std::mutex& mut, CTTRTSGame& game ) +int WaitForOrdersFromClient(const ClientInfo info, std::mutex &mut, CTTRTSGame &game) { char buffer[1028]; // buffer for orders memset(buffer,0,sizeof(buffer)); @@ -68,6 +51,37 @@ int waitForOrdersFromClient(const ClientInfo info, std::mutex& mut, CTTRTSGame& return 0; } +void GetOrdersFromClients(std::vector &myClients, CTTRTSGame &game, std::mutex &gameMutex) +{ + // Spawn threads + std::vector clientThreads; + for(auto client : myClients) + { + std::thread clientThread(WaitForOrdersFromClient, client, ref(gameMutex), std::ref(game)); + clientThreads.push_back(move(clientThread)); + } + + // Join up all the threads + for ( std::thread& thread : clientThreads ) + { + thread.join(); + } +} + +void SendGameInfoToClients(std::vector &myClients, const CTTRTSGame &game, std::mutex &gameMutex) +{ + gameMutex.lock(); + std::string gamestate_string = GetStringFromGame(game); + gameMutex.unlock(); + + for (auto client : myClients) + { + // Write to the socket with the buffer + if ( write( client.clientsockfd, gamestate_string.c_str(), gamestate_string.length() ) < 0 ) + error("ERROR sending to client"); + } +} + int runServer(int argc, char* argv[]) { std::cout<<"Setting up server on port "< Date: Fri, 2 Jan 2015 19:31:14 +0000 Subject: [PATCH 67/95] Make client and server perform a handshake to agree on player IDs --- source/client/client.cpp | 27 ++++++++++++++++++++++++++ source/client/server.cpp | 41 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/source/client/client.cpp b/source/client/client.cpp index 241c002..8eda536 100644 --- a/source/client/client.cpp +++ b/source/client/client.cpp @@ -14,9 +14,12 @@ #include #include "net.h" +#include "game.h" int runClient(int argc, char* argv[]) { + player_t myPlayer; + int sockfd; // socket File descriptor int portno; // Port number int n = 0; // return value for read and write calls @@ -71,6 +74,30 @@ int runClient(int argc, char* argv[]) if (connect(sockfd, (const sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) error("ERROR connecting"); + std::cout<<"Waiting for handshake"<= 0 ) { memset(buffer,0,sizeof(buffer)); diff --git a/source/client/server.cpp b/source/client/server.cpp index ecfef7f..f66408d 100644 --- a/source/client/server.cpp +++ b/source/client/server.cpp @@ -26,6 +26,7 @@ struct ClientInfo { sockaddr_in cli_addr; int clientsockfd; + player_t player; }; int WaitForOrdersFromClient(const ClientInfo info, std::mutex &mut, CTTRTSGame &game) @@ -45,7 +46,7 @@ int WaitForOrdersFromClient(const ClientInfo info, std::mutex &mut, CTTRTSGame & std::cout< players = game.GetPlayers(); unsigned int numClients = game.GetPlayers().size(); + auto player_iterator = players.begin(); // game mutex std::mutex gameMutex; @@ -162,9 +166,44 @@ int runServer(int argc, char* argv[]) error("ERROR on accept"); std::cout<<"Client connected from "< Date: Fri, 2 Jan 2015 19:46:09 +0000 Subject: [PATCH 68/95] add user input for starting the game --- source/client/client.cpp | 1 + source/client/server.cpp | 3 +++ 2 files changed, 4 insertions(+) diff --git a/source/client/client.cpp b/source/client/client.cpp index 8eda536..a5fe5ba 100644 --- a/source/client/client.cpp +++ b/source/client/client.cpp @@ -15,6 +15,7 @@ #include "net.h" #include "game.h" +#include "filesystem.h" int runClient(int argc, char* argv[]) { diff --git a/source/client/server.cpp b/source/client/server.cpp index f66408d..b0b2c82 100644 --- a/source/client/server.cpp +++ b/source/client/server.cpp @@ -206,6 +206,9 @@ int runServer(int argc, char* argv[]) std::cout<<"All clients connected"< Date: Fri, 2 Jan 2015 19:51:14 +0000 Subject: [PATCH 69/95] Pull base netcode functions out into net files --- source/client/net.cpp | 64 +++++++++++++++++++++++++++++++++++- source/client/net.h | 25 ++++++++++++++ source/client/server.cpp | 70 ---------------------------------------- 3 files changed, 88 insertions(+), 71 deletions(-) diff --git a/source/client/net.cpp b/source/client/net.cpp index 35b5308..967aa73 100644 --- a/source/client/net.cpp +++ b/source/client/net.cpp @@ -1 +1,63 @@ -#include "net.h" \ No newline at end of file +#include "net.h" + +#include +#include + +#include +#include +#include +#include + +int WaitForOrdersFromClient(const ClientInfo info, std::mutex &mut, CTTRTSGame &game) +{ + char buffer[1028]; // buffer for orders + memset(buffer,0,sizeof(buffer)); + + std::cout<<"Waiting for "< &myClients, CTTRTSGame &game, std::mutex &gameMutex) +{ + // Spawn threads + std::vector clientThreads; + for(auto client : myClients) + { + std::thread clientThread(WaitForOrdersFromClient, client, ref(gameMutex), std::ref(game)); + clientThreads.push_back(move(clientThread)); + } + + // Join up all the threads + for ( std::thread& thread : clientThreads ) + { + thread.join(); + } +} + +void SendGameInfoToClients(std::vector &myClients, const CTTRTSGame &game, std::mutex &gameMutex) +{ + gameMutex.lock(); + std::string gamestate_string = GetStringFromGame(game); + gameMutex.unlock(); + + for (auto client : myClients) + { + // Write to the socket with the buffer + if ( write( client.clientsockfd, gamestate_string.c_str(), gamestate_string.length() ) < 0 ) + error("ERROR sending to client"); + } +} diff --git a/source/client/net.h b/source/client/net.h index 613486f..fdab7d1 100644 --- a/source/client/net.h +++ b/source/client/net.h @@ -1,9 +1,34 @@ #ifndef _TTRTS_NET_H_ #define _TTRTS_NET_H_ +#include +#include + +#include +#include + +#include +#include +#include +#include + #include #include +// Struct for net client info +struct ClientInfo +{ + sockaddr_in cli_addr; + int clientsockfd; + player_t player; +}; + +int WaitForOrdersFromClient(const ClientInfo info, std::mutex &mut, CTTRTSGame &game); + +void GetOrdersFromClients(std::vector &myClients, CTTRTSGame &game, std::mutex &gameMutex); + +void SendGameInfoToClients(std::vector &myClients, const CTTRTSGame &game, std::mutex &gameMutex); + inline void error(const char *msg) { perror(msg); diff --git a/source/client/server.cpp b/source/client/server.cpp index b0b2c82..f9238b8 100644 --- a/source/client/server.cpp +++ b/source/client/server.cpp @@ -10,79 +10,9 @@ #include #include -#include -#include - -#include -#include -#include -#include - #include "net.h" #include "filesystem.h" -// Struct for net client info -struct ClientInfo -{ - sockaddr_in cli_addr; - int clientsockfd; - player_t player; -}; - -int WaitForOrdersFromClient(const ClientInfo info, std::mutex &mut, CTTRTSGame &game) -{ - char buffer[1028]; // buffer for orders - memset(buffer,0,sizeof(buffer)); - - std::cout<<"Waiting for "< &myClients, CTTRTSGame &game, std::mutex &gameMutex) -{ - // Spawn threads - std::vector clientThreads; - for(auto client : myClients) - { - std::thread clientThread(WaitForOrdersFromClient, client, ref(gameMutex), std::ref(game)); - clientThreads.push_back(move(clientThread)); - } - - // Join up all the threads - for ( std::thread& thread : clientThreads ) - { - thread.join(); - } -} - -void SendGameInfoToClients(std::vector &myClients, const CTTRTSGame &game, std::mutex &gameMutex) -{ - gameMutex.lock(); - std::string gamestate_string = GetStringFromGame(game); - gameMutex.unlock(); - - for (auto client : myClients) - { - // Write to the socket with the buffer - if ( write( client.clientsockfd, gamestate_string.c_str(), gamestate_string.length() ) < 0 ) - error("ERROR sending to client"); - } -} - int runServer(int argc, char* argv[]) { std::cout<<"Setting up server on port "< Date: Sat, 3 Jan 2015 18:55:44 +0000 Subject: [PATCH 70/95] Improve both client and server code to account for END of messages, allowing for incomplete packets with TCP --- source/client/client.cpp | 20 +++++++++++++------- source/client/net.cpp | 24 ++++++++++++++++-------- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/source/client/client.cpp b/source/client/client.cpp index a5fe5ba..d781ce3 100644 --- a/source/client/client.cpp +++ b/source/client/client.cpp @@ -101,17 +101,23 @@ int runClient(int argc, char* argv[]) while ( n >= 0 ) { - memset(buffer,0,sizeof(buffer)); - std::cout<<"Waiting for gamestate"< Date: Sat, 3 Jan 2015 19:27:08 +0000 Subject: [PATCH 71/95] Make client output and read in game state and order files --- source/client/client.cpp | 8 +- source/client/filesystem.cpp | 142 +++++++++++++++++++---------------- source/client/filesystem.h | 2 + source/client/server.cpp | 7 +- 4 files changed, 88 insertions(+), 71 deletions(-) diff --git a/source/client/client.cpp b/source/client/client.cpp index d781ce3..668efcb 100644 --- a/source/client/client.cpp +++ b/source/client/client.cpp @@ -114,10 +114,12 @@ int runClient(int argc, char* argv[]) gamestate+=buffer; } - std::cout<(turnFile)), std::istreambuf_iterator()); + return orders; +} + +int CreateAndCleanGameDir(const std::string& gameDir) +{ struct stat info; int ret = stat( gameDir.c_str(), &info ); if( ret == 0 && info.st_mode & S_IFDIR ) @@ -178,6 +219,30 @@ int runFromFilesystem(int argc, char* argv[]) return -1; } + return 0; +} + +// ===================================================================================================================== +int runFromFilesystem(int argc, char* argv[]) +{ + std::string gamefile = argv[1]; + + std::cout<<"Launching TTRTS with "<(turnFile)),std::istreambuf_iterator()); + std::string orders = GetOrdersFromPlayerFile(game, player); // Issue the orders to the game if( game.IssueOrders(player, orders) ) diff --git a/source/client/filesystem.h b/source/client/filesystem.h index 851da73..aae2e14 100644 --- a/source/client/filesystem.h +++ b/source/client/filesystem.h @@ -15,6 +15,8 @@ void WaitForFile( const std::string& name, const std::chrono::milliseconds& time bool OutputGameStateFile(CTTRTSGame &game, const std::string &gameDir); +std::string GetOrdersFromPlayerFile(const CTTRTSGame &game, player_t &player); + CTTRTSGame GetGameFromFile( const std::string& file ); std::string getMapsDir(); diff --git a/source/client/server.cpp b/source/client/server.cpp index f9238b8..5c07804 100644 --- a/source/client/server.cpp +++ b/source/client/server.cpp @@ -68,7 +68,7 @@ int runServer(int argc, char* argv[]) CTTRTSGame game = GetGameFromFile("Tiny2Player.txt"); std::vector players = game.GetPlayers(); - unsigned int numClients = game.GetPlayers().size(); + unsigned int numClients = players.size(); auto player_iterator = players.begin(); // game mutex @@ -103,10 +103,7 @@ int runServer(int argc, char* argv[]) clientInfo.player = *player_iterator; player_iterator++; - - // Could verify if player is valid here - - myClients.push_back({cli_addr,clientsockfd}); + myClients.push_back(clientInfo); } // Perform the initial handshake with clients From 61c012370db08eb946dda466c709ef5d0ddb486d Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Sat, 3 Jan 2015 19:31:42 +0000 Subject: [PATCH 72/95] Fix filesystem game method --- source/client/client.cpp | 2 +- source/client/filesystem.cpp | 10 +++++----- source/client/filesystem.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/source/client/client.cpp b/source/client/client.cpp index 668efcb..1fd192b 100644 --- a/source/client/client.cpp +++ b/source/client/client.cpp @@ -116,7 +116,7 @@ int runClient(int argc, char* argv[]) // Output the gamestate file for this game CTTRTSGame thisGame = GetGameFromString(gamestate); - OutputGameStateFile(thisGame, getGamesDir()); + OutputGameStateFile(thisGame); // Get the order file for this turn std::string orders = GetOrdersFromPlayerFile(thisGame,myPlayer); diff --git a/source/client/filesystem.cpp b/source/client/filesystem.cpp index a692324..061303d 100644 --- a/source/client/filesystem.cpp +++ b/source/client/filesystem.cpp @@ -30,10 +30,10 @@ void WaitForFile( const std::string& name, const std::chrono::milliseconds& time while( !FileExists(name) ) std::this_thread::sleep_for(time); } -bool OutputGameStateFile(CTTRTSGame &game, const std::string &gameDir) +bool OutputGameStateFile(CTTRTSGame &game) { char turnFileName[128]; - snprintf(turnFileName,128,"%s/%s/Turn_%i.txt",gameDir.c_str(),game.GetName().c_str(),game.GetTurn()); + snprintf(turnFileName,128,"%s%s/Turn_%i.txt", getGamesDir().c_str(),game.GetName().c_str(),game.GetTurn()); std::ofstream turnFile(turnFileName, std::ios_base::trunc); // truncate to overwrite if a file exists if ( turnFile.bad() ) @@ -127,7 +127,7 @@ std::string GetOrdersFromPlayerFile(const CTTRTSGame &game, player_t &player) std::string gameDir = getGamesDir(); char playerOrderFileName[128]; - snprintf(playerOrderFileName, 128, "%s/%s/Player_%i_Turn_%i.txt", gameDir.c_str(),game.GetName().c_str(),(int) player, game.GetTurn()); + snprintf(playerOrderFileName, 128, "%s%s/Player_%i_Turn_%i.txt", gameDir.c_str(),game.GetName().c_str(),(int) player, game.GetTurn()); // Wait for the player order file to be created std::cout<<"Waiting for "<< playerOrderFileName << std::endl; @@ -249,7 +249,7 @@ int runFromFilesystem(int argc, char* argv[]) std::cout<<"Starting turn "< Date: Sat, 3 Jan 2015 20:04:31 +0000 Subject: [PATCH 73/95] Add game name to handshake and formalise handshake format --- source/client/client.cpp | 22 +++++++++++----------- source/client/filesystem.cpp | 8 +++----- source/client/filesystem.h | 2 ++ source/client/net.h | 2 ++ source/client/server.cpp | 11 +++++++---- 5 files changed, 25 insertions(+), 20 deletions(-) diff --git a/source/client/client.cpp b/source/client/client.cpp index 1fd192b..2776971 100644 --- a/source/client/client.cpp +++ b/source/client/client.cpp @@ -82,22 +82,22 @@ int runClient(int argc, char* argv[]) error("ERROR recieving handshake from server"); std::string handshake(buffer); + std::cout<<"Handshake:"<= 0 ) { diff --git a/source/client/filesystem.cpp b/source/client/filesystem.cpp index 061303d..1ab70f5 100644 --- a/source/client/filesystem.cpp +++ b/source/client/filesystem.cpp @@ -179,8 +179,9 @@ std::string GetOrdersFromPlayerFile(const CTTRTSGame &game, player_t &player) return orders; } -int CreateAndCleanGameDir(const std::string& gameDir) +int CreateAndCleanGameDir(const std::string& gameName) { + std::string gameDir = getGamesDir()+gameName; struct stat info; int ret = stat( gameDir.c_str(), &info ); if( ret == 0 && info.st_mode & S_IFDIR ) @@ -236,11 +237,8 @@ int runFromFilesystem(int argc, char* argv[]) // Default for games std::string ttrts_games_dir = getGamesDir(); - // Current game directory - std::string gameDir = ttrts_games_dir + game.GetName(); - // Empty the current game directory - if ( CreateAndCleanGameDir(gameDir) < 0) + if ( CreateAndCleanGameDir(game.GetName()) < 0) return -1; // While the game isn't finished diff --git a/source/client/filesystem.h b/source/client/filesystem.h index 8d63fc1..7b7c338 100644 --- a/source/client/filesystem.h +++ b/source/client/filesystem.h @@ -24,4 +24,6 @@ std::string getGamesDir(); int runFromFilesystem(int argc, char* argv[]); +int CreateAndCleanGameDir(const std::string& gameName); + #endif \ No newline at end of file diff --git a/source/client/net.h b/source/client/net.h index fdab7d1..af8b64e 100644 --- a/source/client/net.h +++ b/source/client/net.h @@ -15,6 +15,8 @@ #include #include +#define TTRTS_HANDSHAKE_FORMAT "player %u name %s" + // Struct for net client info struct ClientInfo { diff --git a/source/client/server.cpp b/source/client/server.cpp index 5c07804..17fb421 100644 --- a/source/client/server.cpp +++ b/source/client/server.cpp @@ -110,13 +110,14 @@ int runServer(int argc, char* argv[]) for( auto client : myClients ) { // Handshake currently just player - std::string handshake = std::string("player ")+std::to_string((int)client.player); + char handshake[64]; + snprintf(handshake, sizeof(handshake), TTRTS_HANDSHAKE_FORMAT,(unsigned int)client.player,game.GetName().c_str()); // Output the handshake - std::cout<<"Handshaking with "< Date: Sat, 3 Jan 2015 22:30:52 +0000 Subject: [PATCH 74/95] Use new fatal_error and fatal_perror functions for errors --- source/client/client.cpp | 18 +++++++++--------- source/client/net.cpp | 4 ++-- source/client/net.h | 9 ++++++++- source/client/server.cpp | 12 ++++++------ 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/source/client/client.cpp b/source/client/client.cpp index 2776971..1184678 100644 --- a/source/client/client.cpp +++ b/source/client/client.cpp @@ -48,14 +48,14 @@ int runClient(int argc, char* argv[]) // 0 is for default protocol sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) - error("ERROR opening socket"); + fatal_perror("ERROR opening socket"); std::cout<<"Opened socket on "< &myClients, const CTTRTSGame { // Write to the socket with the buffer if ( write( client.clientsockfd, gamestate_string.c_str(), gamestate_string.length() ) < 0 ) - error("ERROR sending to client"); + fatal_perror("ERROR sending to client"); } } diff --git a/source/client/net.h b/source/client/net.h index af8b64e..5ac3f55 100644 --- a/source/client/net.h +++ b/source/client/net.h @@ -14,6 +14,7 @@ #include #include +#include #define TTRTS_HANDSHAKE_FORMAT "player %u name %s" @@ -31,7 +32,13 @@ void GetOrdersFromClients(std::vector &myClients, CTTRTSGame &game, void SendGameInfoToClients(std::vector &myClients, const CTTRTSGame &game, std::mutex &gameMutex); -inline void error(const char *msg) +inline void fatal_error(const char *msg) +{ + std::cerr< 10) { - error("Binding failed after retries"); + fatal_error("Binding failed after retries"); } if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) >= 0) @@ -93,7 +93,7 @@ int runServer(int argc, char* argv[]) // client information will be stored in cli_addr clientsockfd = accept(sockfd, (sockaddr *) &cli_addr, &clilen); if (clientsockfd < 0) - error("ERROR on accept"); + fatal_perror("ERROR on accept"); std::cout<<"Client connected from "< Date: Sat, 3 Jan 2015 22:43:39 +0000 Subject: [PATCH 75/95] Refactor running game server into own function --- source/client/server.cpp | 51 ++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/source/client/server.cpp b/source/client/server.cpp index 4f8d16b..c11035c 100644 --- a/source/client/server.cpp +++ b/source/client/server.cpp @@ -9,16 +9,17 @@ #include #include #include +#include #include "net.h" #include "filesystem.h" -int runServer(int argc, char* argv[]) +CTTRTSGame &RunServerForGame(CTTRTSGame &game) { - std::cout<<"Setting up server on port "<= 0) break; - std::cout<<"Binding failed on try "< players = game.GetPlayers(); unsigned int numClients = players.size(); auto player_iterator = players.begin(); @@ -77,7 +75,7 @@ int runServer(int argc, char* argv[]) // Set of clients std::vector myClients; - std::cout<<"Waiting for clients"< Date: Sun, 4 Jan 2015 11:08:35 +0000 Subject: [PATCH 76/95] More refactoring by pulling code out of client and server files --- source/client/client.cpp | 24 ++++---------- source/client/net.cpp | 71 ++++++++++++++++++++++++++++++++++++++-- source/client/net.h | 8 ++++- source/client/server.cpp | 44 +++---------------------- 4 files changed, 86 insertions(+), 61 deletions(-) diff --git a/source/client/client.cpp b/source/client/client.cpp index 1184678..8619898 100644 --- a/source/client/client.cpp +++ b/source/client/client.cpp @@ -19,7 +19,7 @@ int runClient(int argc, char* argv[]) { - player_t myPlayer; + player_t myPlayer = player_t::NUM_INVALID; // My player int sockfd; // socket File descriptor int portno; // Port number @@ -29,7 +29,7 @@ int runClient(int argc, char* argv[]) struct hostent *server; // pointer to host information - char buffer[1028]; // buffer for socked read + char buffer[1028]; // buffer for socket read memset(buffer,0,sizeof(buffer)); // must provide information @@ -77,27 +77,17 @@ int runClient(int argc, char* argv[]) std::cout<<"Waiting for handshake"<= 0 ) { diff --git a/source/client/net.cpp b/source/client/net.cpp index 2de2e77..ed171f6 100644 --- a/source/client/net.cpp +++ b/source/client/net.cpp @@ -8,7 +8,7 @@ #include #include -int WaitForOrdersFromClient(const ClientInfo info, std::mutex &mut, CTTRTSGame &game) +void WaitForOrdersFromClient(const ClientInfo info, std::mutex &mut, CTTRTSGame &game) { char buffer[1028]; // buffer for orders @@ -35,8 +35,6 @@ int WaitForOrdersFromClient(const ClientInfo info, std::mutex &mut, CTTRTSGame & mut.lock(); game.IssueOrders(info.player , orders); mut.unlock(); - - return 0; } void GetOrdersFromClients(std::vector &myClients, CTTRTSGame &game, std::mutex &gameMutex) @@ -69,3 +67,70 @@ void SendGameInfoToClients(std::vector &myClients, const CTTRTSGame fatal_perror("ERROR sending to client"); } } + + +void PerformClientHandshake(int sockfd, unsigned int &player, std::string &gameNameString) +{ + char handshakeBuffer[128]; + memset(handshakeBuffer,0,sizeof(handshakeBuffer)); + + if (read(sockfd, handshakeBuffer,sizeof(handshakeBuffer)-1) < 0) + fatal_perror("ERROR recieving handshake from server"); + + std::string handshake(handshakeBuffer); + std::cout<<"Handshake:"< 10) + fatal_error("Binding failed"); + + // Attempt to bind our listening socket + if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) >= 0) + break; + + std::cout<<"Binding failed on try "< &myClients, CTTRTSGame &game, std::mutex &gameMutex); void SendGameInfoToClients(std::vector &myClients, const CTTRTSGame &game, std::mutex &gameMutex); +void TryBindSocket(int sockfd, sockaddr_in &serv_addr); + +void PerformServerHandshakeWithClient(const ClientInfo &client, const CTTRTSGame &game); + +void PerformClientHandshake(int sockfd, unsigned int &player, std::string &gameNameString); + inline void fatal_error(const char *msg) { std::cerr< 10) - { - fatal_error("Binding failed after retries"); - } - - if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) >= 0) - break; - - std::cout<<"Binding failed on try "< players = game.GetPlayers(); unsigned int numClients = players.size(); auto player_iterator = players.begin(); @@ -108,28 +94,7 @@ CTTRTSGame &RunServerForGame(CTTRTSGame &game) for( auto client : myClients ) { // Handshake currently just player - char handshake[64]; - snprintf(handshake, sizeof(handshake), TTRTS_HANDSHAKE_FORMAT,(unsigned int)client.player,game.GetName().c_str()); - - // Output the handshake - std::cout<<"Handshaking:"< Date: Sun, 4 Jan 2015 11:22:54 +0000 Subject: [PATCH 77/95] Some more refactoring with additional comments Server now performs handshake instantly --- source/client/net.cpp | 10 +++++----- source/client/net.h | 17 +++++++++++++---- source/client/server.cpp | 28 ++++++++++++++-------------- 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/source/client/net.cpp b/source/client/net.cpp index ed171f6..0fc85ba 100644 --- a/source/client/net.cpp +++ b/source/client/net.cpp @@ -8,7 +8,7 @@ #include #include -void WaitForOrdersFromClient(const ClientInfo info, std::mutex &mut, CTTRTSGame &game) +void WaitForOrdersFromClient(const ClientInfo info, CTTRTSGame &game, std::mutex &mut) { char buffer[1028]; // buffer for orders @@ -37,13 +37,13 @@ void WaitForOrdersFromClient(const ClientInfo info, std::mutex &mut, CTTRTSGame mut.unlock(); } -void GetOrdersFromClients(std::vector &myClients, CTTRTSGame &game, std::mutex &gameMutex) +void WaitForOrdersFromClients(std::vector &myClients, CTTRTSGame &game, std::mutex &gameMutex) { // Spawn threads std::vector clientThreads; for(auto client : myClients) { - std::thread clientThread(WaitForOrdersFromClient, client, ref(gameMutex), std::ref(game)); + std::thread clientThread(WaitForOrdersFromClient, client, std::ref(game), ref(gameMutex)); clientThreads.push_back(move(clientThread)); } @@ -54,7 +54,7 @@ void GetOrdersFromClients(std::vector &myClients, CTTRTSGame &game, } } -void SendGameInfoToClients(std::vector &myClients, const CTTRTSGame &game, std::mutex &gameMutex) +void SendGamestateToClients(std::vector &myClients, const CTTRTSGame &game, std::mutex &gameMutex) { gameMutex.lock(); std::string gamestate_string = GetStringFromGame(game); @@ -90,7 +90,7 @@ void PerformClientHandshake(int sockfd, unsigned int &player, std::string &gameN gameNameString = gameName; } -void PerformServerHandshakeWithClient(const ClientInfo &client, const CTTRTSGame &game) +void PerformServerHandshake(const ClientInfo &client, const CTTRTSGame &game) { char handshake[64]; snprintf(handshake, sizeof(handshake), TTRTS_HANDSHAKE_FORMAT,(unsigned int)client.player,game.GetName().c_str()); diff --git a/source/client/net.h b/source/client/net.h index eaa8737..e80c091 100644 --- a/source/client/net.h +++ b/source/client/net.h @@ -26,24 +26,33 @@ struct ClientInfo player_t player; }; -void WaitForOrdersFromClient(const ClientInfo info, std::mutex &mut, CTTRTSGame &game); +// Wait for orders from a client, will not return until client has send valid orders +// Will automatically add orders to the game +void WaitForOrdersFromClient(const ClientInfo info, CTTRTSGame &game, std::mutex &mut); -void GetOrdersFromClients(std::vector &myClients, CTTRTSGame &game, std::mutex &gameMutex); +// Iterates through a list of clients calling WaitForOrdersFromClient +void WaitForOrdersFromClients(std::vector &myClients, CTTRTSGame &game, std::mutex &gameMutex); -void SendGameInfoToClients(std::vector &myClients, const CTTRTSGame &game, std::mutex &gameMutex); +// Sends current gamestate to each client +void SendGamestateToClients(std::vector &myClients, const CTTRTSGame &game, std::mutex &gameMutex); +// Tries to bind to a socket, will attempt 10 times with longer waits between void TryBindSocket(int sockfd, sockaddr_in &serv_addr); -void PerformServerHandshakeWithClient(const ClientInfo &client, const CTTRTSGame &game); +// Perform the server side handshake with a client +void PerformServerHandshake(const ClientInfo &client, const CTTRTSGame &game); +// Perform the client side handshake with the server void PerformClientHandshake(int sockfd, unsigned int &player, std::string &gameNameString); +// For local fatal errors inline void fatal_error(const char *msg) { std::cerr< Date: Sun, 4 Jan 2015 11:59:58 +0000 Subject: [PATCH 78/95] Fix up all logging output Remove debug logging Use cerr or clog in the correct places refactor a few more functions --- bootstrap.sh | 2 +- source/client/client.cpp | 16 +++---- source/client/filesystem.cpp | 55 ++++++++---------------- source/client/main.cpp | 1 + source/client/net.cpp | 81 +++++++++++++++++++++++++++++------- source/client/net.h | 14 ++++++- source/client/server.cpp | 77 ++++++++-------------------------- 7 files changed, 121 insertions(+), 125 deletions(-) diff --git a/bootstrap.sh b/bootstrap.sh index 26e306d..701f47b 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -16,7 +16,7 @@ if [[ $? != 0 ]]; then exit fi -echo "Performing install" +echo "TTRTS: Performing install" sudo make install if [[ $? != 0 ]]; then echo "TTRTS: Install failed, check output" diff --git a/source/client/client.cpp b/source/client/client.cpp index 8619898..f052ad2 100644 --- a/source/client/client.cpp +++ b/source/client/client.cpp @@ -50,14 +50,12 @@ int runClient(int argc, char* argv[]) if (sockfd < 0) fatal_perror("ERROR opening socket"); - std::cout<<"Opened socket on "<= 0 ) { - std::cout<<"Waiting for gamestate"< @@ -95,10 +96,7 @@ CTTRTSGame GetGameFromFile( const std::string& filename ) // If still not good if( access( gamefile.c_str(), F_OK ) == -1 ) - { - std::cerr<<"Error: "<< gamefile <<" file not found"<(file)),std::istreambuf_iterator()); if( gameDescriptor.size() == 0 ) - { - std::cerr<<"Error: failed to read in any information from "<>input; if( !input.size() || std::tolower(input[0]) != 'y' ) - { - std::cerr<<"Aborting..."<= 0) break; - std::cout<<"Binding failed on try "< &myClients, CTTRTSGame &ga void SendGamestateToClients(std::vector &myClients, const CTTRTSGame &game, std::mutex &gameMutex); // Tries to bind to a socket, will attempt 10 times with longer waits between -void TryBindSocket(int sockfd, sockaddr_in &serv_addr); +void TryBindSocket(int sockfd, const sockaddr_in &serv_addr); // Perform the server side handshake with a client -void PerformServerHandshake(const ClientInfo &client, const CTTRTSGame &game); +void PerformServerHandshake(const ClientInfo &client, const std::string &game); // Perform the client side handshake with the server void PerformClientHandshake(int sockfd, unsigned int &player, std::string &gameNameString); diff --git a/source/client/server.cpp b/source/client/server.cpp index f5ff5e0..b54a541 100644 --- a/source/client/server.cpp +++ b/source/client/server.cpp @@ -16,39 +16,13 @@ void RunServerForGame(CTTRTSGame &game) { - std::cout<<"Setting up server on port "< players = game.GetPlayers(); @@ -61,59 +35,40 @@ void RunServerForGame(CTTRTSGame &game) // Set of clients std::vector myClients; - std::cout<<"Waiting for clients"<< std::endl; + std::cout<<"TTRTS: Waiting for "< Date: Sun, 4 Jan 2015 13:09:37 +0000 Subject: [PATCH 79/95] Major cleanup of client code, extracting various functionality --- source/client/client.cpp | 92 +++++++++--------------------------- source/client/filesystem.cpp | 55 ++++++++++++++------- source/client/net.cpp | 73 +++++++++++++++++++++++++++- source/client/net.h | 26 ++++++++++ source/client/server.cpp | 15 +----- 5 files changed, 161 insertions(+), 100 deletions(-) diff --git a/source/client/client.cpp b/source/client/client.cpp index f052ad2..d5de77f 100644 --- a/source/client/client.cpp +++ b/source/client/client.cpp @@ -2,117 +2,69 @@ #include -#include -#include -#include -#include - -#include -#include -#include - -#include - #include "net.h" + #include "game.h" #include "filesystem.h" int runClient(int argc, char* argv[]) { - player_t myPlayer = player_t::NUM_INVALID; // My player - - int sockfd; // socket File descriptor - int portno; // Port number - int n = 0; // return value for read and write calls - - struct sockaddr_in serv_addr; // Server address - - struct hostent *server; // pointer to host information - - char buffer[1028]; // buffer for socket read - memset(buffer,0,sizeof(buffer)); - // must provide information if (argc < 2) - { - fprintf(stderr,"usage %s hostname\n", argv[0]); - exit(0); - } + fatal_error("Usage: ttrts client HOST"); - // Get port number - portno = TTRTS_PORT; + std::string hostname = argv[1]; - // Create a new socket - // AF_INET is general internetsocket domain - // SOCK_STREAM as messages will be read in on this socket, SOCK_DGRAM would be for packets - // 0 is for default protocol - sockfd = socket(AF_INET, SOCK_STREAM, 0); - if (sockfd < 0) - fatal_perror("ERROR opening socket"); - - // Get the hostent information for the host by name - server = gethostbyname(argv[1]); - if (server == NULL) - fatal_error("ERROR, no such host"); - - std::cout<<"TTRTS: Connecting to "<h_addr, server->h_length); - // Set our server address port to the port number provided - serv_addr.sin_port = htons(portno); + serv_addr.sin_port = htons(TTRTS_PORT); - // Attempt to connect to the server using the socket and server address info - if (connect(sockfd, (const sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) - fatal_perror("ERROR connecting"); + std::cout<<"TTRTS: Connecting to "<= 0 ) { std::cout<<"TTRTS: Waiting for gamestate"< + #include #include @@ -186,4 +188,73 @@ sockaddr_in GetLocalServerAddress() // The host for this address is this current machine's IP, INADDR_ANY fetches this serv_addr.sin_addr.s_addr = INADDR_ANY; return serv_addr; -} \ No newline at end of file +} + + +int ConnectToHostServer(const std::string &hostname, sockaddr_in &serv_addr) +{ + // Create a new socket + int sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd < 0) + fatal_perror("ERROR opening socket"); + + // Get the hostent information for the host by name + hostent *server = gethostbyname(hostname.c_str()); + if (server == NULL) + fatal_error("ERROR, no such host"); + + // copy the server address into our server_addr struct + memcpy(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length); + + // Attempt to connect to the server using the socket and server address info + if (connect(sockfd, (const sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) + fatal_perror("ERROR connecting"); + + return sockfd; +} + +std::string WaitForGamestateMessage(int sockfd) +{ + std::string gamestate; + char gamestateBuffer[1028]; + while( gamestate.find("END") == std::string::npos ) + { + memset(gamestateBuffer,0,sizeof(gamestateBuffer)); + + // Receive gamestate + if (read(sockfd,gamestateBuffer,sizeof(gamestateBuffer)-1) < 0) + fatal_perror("ERROR reading from client"); + + gamestate+=gamestateBuffer; + } + return gamestate; +} + +int SendOrdersToServer(int sockfd, const std::string &orders) +{ + int n = write(sockfd,orders.c_str(),orders.length()); + if (0 < n) + fatal_perror("ERROR writing to socket"); + return n; +} + + +int OutputGameEnd( CTTRTSGame& game ) +{ + std::cout<<"TTRTS: Game Over!"< Date: Tue, 6 Jan 2015 12:39:56 +0000 Subject: [PATCH 80/95] Guard against missing file param for server --- source/client/server.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/client/server.cpp b/source/client/server.cpp index 7a552fa..e4b1d41 100644 --- a/source/client/server.cpp +++ b/source/client/server.cpp @@ -82,6 +82,10 @@ void RunServerForGame(CTTRTSGame &game) int runServer(int argc, char* argv[]) { + // argv[1] needs to be a valid game file + if( argc < 2 ) + fatal_error("must provide game file argument"); + // Set up game CTTRTSGame game = GetGameFromFile(argv[1]); if(game.GetNumUnits() == 0) From a0ff8680a3e5e4bd3845bfdd8e24f8559cbbc27b Mon Sep 17 00:00:00 2001 From: JackUnthank Date: Tue, 6 Jan 2015 17:01:15 +0000 Subject: [PATCH 81/95] Make the AI print out the walls not the map. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don’t worry I wasn’t doing this all afternoon I had a spare 5 minutes whilst waiting for some .DAT files to md5. =P --- api/perl/ttrts.pm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/api/perl/ttrts.pm b/api/perl/ttrts.pm index 6dc279e..793269b 100644 --- a/api/perl/ttrts.pm +++ b/api/perl/ttrts.pm @@ -238,6 +238,13 @@ sub PrintGameFromGamestateString $map[$invalidPos[0]][$invalidPos[1]] = "~"; } + # Fill with walls + foreach my $wall ( $info[8] =~ /\[(\d+,\d+)\]/g ) + { + $wall =~ /(\d+),(\d+)/; + $map[$1][$2] = "|"; + } + # Fill with units for my $unit (@units) { From 3291bf126e1831645531689c23fd4022fb31ae0d Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Wed, 7 Jan 2015 12:39:27 +0000 Subject: [PATCH 82/95] Compare write result correctly with 0 Fixes client sending of orders --- source/client/net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/client/net.cpp b/source/client/net.cpp index 956c688..1de5847 100644 --- a/source/client/net.cpp +++ b/source/client/net.cpp @@ -233,7 +233,7 @@ std::string WaitForGamestateMessage(int sockfd) int SendOrdersToServer(int sockfd, const std::string &orders) { int n = write(sockfd,orders.c_str(),orders.length()); - if (0 < n) + if (n < 0) fatal_perror("ERROR writing to socket"); return n; } From c51119c3e2c1772cd5385478d0bcf0ca51d341eb Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Wed, 7 Jan 2015 12:40:41 +0000 Subject: [PATCH 83/95] Add TTRTS: Prefix to output --- source/client/net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/client/net.cpp b/source/client/net.cpp index 956c688..9ee7b45 100644 --- a/source/client/net.cpp +++ b/source/client/net.cpp @@ -32,7 +32,7 @@ void WaitForOrdersFromClient(const ClientInfo info, CTTRTSGame &game, std::mute orders+=buffer; } - std::clog<<"Recieved orders from "< Date: Wed, 7 Jan 2015 13:25:16 +0000 Subject: [PATCH 84/95] Fix walls in strings and move constructor --- source/ttrts/formatters.cpp | 2 +- source/ttrts/game.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/source/ttrts/formatters.cpp b/source/ttrts/formatters.cpp index 6d6d03a..332c5ac 100644 --- a/source/ttrts/formatters.cpp +++ b/source/ttrts/formatters.cpp @@ -92,7 +92,7 @@ CTTRTSGame GetGameFromString( const std::string& input ) size_t pos; while ( ( pos = walls_str.find(']') ) != std::string::npos ) { - std::string pos_string = walls_str.substr(0,pos); + std::string pos_string = walls_str.substr(0,pos+1); // Use scanf to extract positions diff --git a/source/ttrts/game.cpp b/source/ttrts/game.cpp index 96800d5..d649060 100644 --- a/source/ttrts/game.cpp +++ b/source/ttrts/game.cpp @@ -17,6 +17,7 @@ CTTRTSGame::CTTRTSGame(CTTRTSGame&& game) , dimensions(std::move(game.dimensions)) , turn(std::move(game.turn)) , name(std::move(game.name)) +, m_walls(std::move(game.m_walls)) { } From 1b2010faba984cf499ac98a08216720f9288cd39 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Sat, 10 Jan 2015 15:11:36 +0000 Subject: [PATCH 85/95] Use some version checking on generator scripts, preventing a full rebuild on every build --- scripts/gen_manpage.sh | 16 ++++++++++++---- scripts/gen_usage.sh | 10 +++++++++- scripts/gen_version_header.sh | 7 ++++++- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/scripts/gen_manpage.sh b/scripts/gen_manpage.sh index 57ad57c..aed24fc 100755 --- a/scripts/gen_manpage.sh +++ b/scripts/gen_manpage.sh @@ -1,10 +1,13 @@ #! /bin/bash # Used to a man page from markdown -echo ".\" Man page for the ttrts project" > $4 -echo ".\" this man page is auto-generated, do not edit directly" >> $4 +FILE="$4" +TEMP="$FILE.tmp" -echo ".TH TTRTS\ v$1.$2.$3 6 $(date +%Y-%m-%d) http://mdiluz.github.io/ttrts/" >> $4 +echo ".\" Man page for the ttrts project" > $TEMP +echo ".\" this man page is auto-generated, do not edit directly" >> $TEMP + +echo ".TH TTRTS\ v$1.$2.$3 6 $(date +%Y-%m-%d) http://mdiluz.github.io/ttrts/" >> $TEMP # NOTE: For the OSX version of sed we use -E, which on linux appears be an undocumented switch for -r # we also have to use [A-Za-z] instead of \w for some reason @@ -32,4 +35,9 @@ cat "$5" \ | sed -E 's/-----+//g' \ | sed -E 's/`(.*)`/\\fB\1\\fR/g' \ | sed -E 's/MAPFILE/\\fImapfile\\fR/g' \ - | sed -E 's/ ttrts -/ ttrts \\-/g' >> $4 + | sed -E 's/ ttrts -/ ttrts \\-/g' >> $TEMP + + +if [ ! -e $FILE ] || [ ! -z $( diff $FILE $TEMP ) ]; then + mv -f $TEMP $FILE +fi diff --git a/scripts/gen_usage.sh b/scripts/gen_usage.sh index efeab0a..5e33166 100755 --- a/scripts/gen_usage.sh +++ b/scripts/gen_usage.sh @@ -1,10 +1,18 @@ #! /bin/bash # Used to generate usage text from markdown +FILE="$1" +TEMP="${FILE}_tmp" + cat README.md \ | sed -E 's/^#+ //g' \ | sed -E 's/^ /\\t/g' \ | sed -E 's/^ /\\t/g' \ | sed -E 's/^/\"/' \ | sed -E 's/$/\\n\"/' \ - > $1 + > $TEMP + +# If no difference +if [ ! -e $FILE ] || [ ! -z "$( diff $TEMP $FILE )" ]; then + mv -f $TEMP $FILE +fi diff --git a/scripts/gen_version_header.sh b/scripts/gen_version_header.sh index 907c2be..69db452 100755 --- a/scripts/gen_version_header.sh +++ b/scripts/gen_version_header.sh @@ -10,4 +10,9 @@ HEADER="// Auto generated ttrts version header #endif //_TTRTS_VERSION_H_" -echo "$HEADER" > "version.h" \ No newline at end of file +echo "$HEADER" > "version.h.tmp" + +# If no difference +if [ ! -e version.h ] || [ ! -z $( diff version.h version.h.tmp ) ]; then + mv -f version.h.tmp version.h +fi From 0ead12c7dd68097ffbb0ab6fdc9e287f972f31a9 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Sat, 10 Jan 2015 16:55:30 +0000 Subject: [PATCH 86/95] Huge refactor, pulling server and local out into their own binaries --- source/client/CMakeLists.txt | 30 +------- source/client/README.md | 98 ------------------------ source/client/client.cpp | 8 +- source/client/client.h | 6 -- source/client/main.cpp | 34 -------- source/client/server.h | 6 -- source/local/CMakeLists.txt | 23 ++++++ source/local/local.cpp | 62 +++++++++++++++ source/server/CMakeLists.txt | 23 ++++++ source/{client => server}/server.cpp | 6 +- source/system/CMakeLists.txt | 21 +++++ source/system/error.h | 25 ++++++ source/{client => system}/filesystem.cpp | 52 +------------ source/{client => system}/filesystem.h | 0 source/{client => system}/net.cpp | 1 + source/{client => system}/net.h | 17 ---- 16 files changed, 165 insertions(+), 247 deletions(-) delete mode 100644 source/client/README.md delete mode 100644 source/client/client.h delete mode 100644 source/client/main.cpp delete mode 100644 source/client/server.h create mode 100644 source/local/CMakeLists.txt create mode 100644 source/local/local.cpp create mode 100644 source/server/CMakeLists.txt rename source/{client => server}/server.cpp (95%) create mode 100644 source/system/CMakeLists.txt create mode 100644 source/system/error.h rename source/{client => system}/filesystem.cpp (82%) rename source/{client => system}/filesystem.h (100%) rename source/{client => system}/net.cpp (99%) rename source/{client => system}/net.h (87%) diff --git a/source/client/CMakeLists.txt b/source/client/CMakeLists.txt index 7f26ed1..1ae8054 100644 --- a/source/client/CMakeLists.txt +++ b/source/client/CMakeLists.txt @@ -3,45 +3,21 @@ project( ttrts-client ) include_directories( - ${CMAKE_CURRENT_BINARY_DIR} + ${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) diff --git a/source/client/README.md b/source/client/README.md deleted file mode 100644 index 9e8cf27..0000000 --- a/source/client/README.md +++ /dev/null @@ -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. diff --git a/source/client/client.cpp b/source/client/client.cpp index d5de77f..116a5a0 100644 --- a/source/client/client.cpp +++ b/source/client/client.cpp @@ -1,17 +1,15 @@ -#include "client.h" - #include #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]; diff --git a/source/client/client.h b/source/client/client.h deleted file mode 100644 index 201c0d9..0000000 --- a/source/client/client.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _TTRTS_CLIENT_H_ -#define _TTRTS_CLIENT_H_ - -int runClient(int argc, char* argv[]); - -#endif \ No newline at end of file diff --git a/source/client/main.cpp b/source/client/main.cpp deleted file mode 100644 index a436d6a..0000000 --- a/source/client/main.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "game.h" -#include "filesystem.h" -#include "server.h" -#include "client.h" - -#include - -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< + +// ===================================================================================================================== +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 "< #include @@ -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]); diff --git a/source/system/CMakeLists.txt b/source/system/CMakeLists.txt new file mode 100644 index 0000000..c17548e --- /dev/null +++ b/source/system/CMakeLists.txt @@ -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 ) diff --git a/source/system/error.h b/source/system/error.h new file mode 100644 index 0000000..2d9cde5 --- /dev/null +++ b/source/system/error.h @@ -0,0 +1,25 @@ +#ifndef _TTRTS_ERROR_H_ +#define _TTRTS_ERROR_H_ + +#include +#include +#include + +//====================================================================================================================== +// Error functions + +// For local fatal errors +inline void fatal_error(const char *msg) +{ + std::cerr< @@ -244,55 +245,4 @@ int OutputgameEnd(const CTTRTSGame &game) { } return (int)winningPlayer; -} - -// ===================================================================================================================== -int runFromFilesystem(int argc, char* argv[]) -{ - std::string gamefile = argv[1]; - - std::cout<<"TTRTS: Launching with "< diff --git a/source/client/net.h b/source/system/net.h similarity index 87% rename from source/client/net.h rename to source/system/net.h index 4d0cc33..bfcc97e 100644 --- a/source/client/net.h +++ b/source/system/net.h @@ -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< Date: Sat, 10 Jan 2015 16:56:01 +0000 Subject: [PATCH 87/95] Update CMakelists to reflect refactor --- CMakeLists.txt | 23 ++++++++++++++--------- source/CMakeLists.txt | 13 +++++++++++++ 2 files changed, 27 insertions(+), 9 deletions(-) create mode 100644 source/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 01d8a13..97a47ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,8 +2,18 @@ cmake_minimum_required( VERSION 2.8.7 ) # Set version information set( TTRTS_VERSION_MAJOR 0 ) -set( TTRTS_VERSION_MINOR 3 ) -set( TTRTS_VERSION_PATCH 2 ) +set( TTRTS_VERSION_MINOR 4 ) +set( TTRTS_VERSION_PATCH 0 ) + +# 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}" ) # Use c++1y (14) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++1y" ) @@ -26,7 +36,7 @@ install( FILES scripts/ttrts_complete DESTINATION /etc/bash_completion.d/ ) # Run the gen_usage script to generate our usage header add_custom_target( ttrts-gen-manpage ALL - ${CMAKE_SOURCE_DIR}/scripts/gen_manpage.sh "${TTRTS_VERSION_MAJOR}" "${TTRTS_VERSION_MINOR}" "${TTRTS_VERSION_PATCH}" "ttrts.6" "${CMAKE_SOURCE_DIR}/source/client/README.md" + ${CMAKE_SOURCE_DIR}/scripts/gen_manpage.sh "${TTRTS_VERSION_MAJOR}" "${TTRTS_VERSION_MINOR}" "${TTRTS_VERSION_PATCH}" "ttrts.6" "${CMAKE_SOURCE_DIR}/source/README.md" ) # Install the ttrts man page @@ -41,9 +51,4 @@ endif() install( FILES "${CMAKE_BINARY_DIR}/ttrts.6" DESTINATION ${MANPAGE_LOC} ) # Subprojects -add_subdirectory( source/ttrts ) -add_subdirectory( source/client ) - -# Auxhilary binaries -add_subdirectory( source/test ) -add_subdirectory( source/gen ) +add_subdirectory( source ) diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt new file mode 100644 index 0000000..d73e509 --- /dev/null +++ b/source/CMakeLists.txt @@ -0,0 +1,13 @@ +# Main libraries +add_subdirectory( ttrts ) +add_subdirectory( system ) + +# Main binaries +add_subdirectory( launcher ) +add_subdirectory( client ) +add_subdirectory( server ) +add_subdirectory( local ) + +# Auxhilary binaries +add_subdirectory( test ) +add_subdirectory( gen ) \ No newline at end of file From 06057e6e5222816959811cbe400704a3662fe940 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Sat, 10 Jan 2015 16:56:27 +0000 Subject: [PATCH 88/95] Add perl launcher script and new Readme --- source/README.md | 105 +++++++++++++++++++++++++++++---- source/launcher/CMakeLists.txt | 6 ++ source/launcher/ttrts.pl | 42 +++++++++++++ 3 files changed, 143 insertions(+), 10 deletions(-) create mode 100644 source/launcher/CMakeLists.txt create mode 100755 source/launcher/ttrts.pl diff --git a/source/README.md b/source/README.md index 5ca2d8e..fa89aec 100644 --- a/source/README.md +++ b/source/README.md @@ -1,13 +1,98 @@ -# Targets -### client -Main TTRTS binary, runs from the command line and acts as host for games +# NAME + ttrts - Tiny Terminal RTS -### test -Test binary, to be compiled and run to test various functionality +# SYNOPSIS + ttrts [--server] [--client] [--host=HOSTNAME] [MAPFILE] + +# DESCRIPTION + ttrts is a tiny terminal based RTS that uses text files as order lists to control the units -### gen -Binary to generate example map files + This means that any user, program or cat that can read and write to text files can play the game -# Libraries -### ttrts -Implementation of the RTS rules and simulation +# 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. diff --git a/source/launcher/CMakeLists.txt b/source/launcher/CMakeLists.txt new file mode 100644 index 0000000..c6726c7 --- /dev/null +++ b/source/launcher/CMakeLists.txt @@ -0,0 +1,6 @@ +# ====================== ttrts ======================= +# Project name +project( ttrts-perl-launch ) + +# Add bash completion to install +install( PROGRAMS ttrts.pl DESTINATION bin RENAME ttrts ) diff --git a/source/launcher/ttrts.pl b/source/launcher/ttrts.pl new file mode 100755 index 0000000..b757ee9 --- /dev/null +++ b/source/launcher/ttrts.pl @@ -0,0 +1,42 @@ +#! /usr/bin/perl +# Main ttrts launcher script + +use strict; +use warnings; +use 5.0; + +use Getopt::Long qw(GetOptions); + +sub print_usage +{ + print "Unknown option: @_\n" if ( @_ ); + print "Usage: ttrts [--server] [--client] [--host=HOSTNAME] [--map=MAPFILE]\n"; + exit; +} + +our $VERBOSE = $ENV{"VERBOSE"}; + +our $server; +our $client; +our $host; +our $map; + +print_usage() if ( @ARGV < 1 or + !GetOptions( + 'client' => \$client, + 'server' => \$server, + 'host=s' => \$host, + 'map=s' => \$map, + ) ); + +print "Cannot run as both client and server\n" and exit if $client and $server; +print "Client requires hostname\n" and exit if $client and not $host; +print "Server requires mapfile\n" and exit if $server and not $map; +print "Running locally requires mapfile\n" and exit if not $server and not $client and not $map; + +# Run client, server or local +system("ttrts-client $host") if $client and $host; +system("ttrts-server $map") if $server and $map; +system("ttrts-local $map") if not $server and not $client and $map; + +print "Success!\n"; \ No newline at end of file From d65ef46634a6f112f424baf463fb2652e25d27d4 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Sat, 10 Jan 2015 16:56:42 +0000 Subject: [PATCH 89/95] Fix some bugs in generation scripts --- scripts/gen_manpage.sh | 2 +- scripts/gen_version_header.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/gen_manpage.sh b/scripts/gen_manpage.sh index aed24fc..0ce6110 100755 --- a/scripts/gen_manpage.sh +++ b/scripts/gen_manpage.sh @@ -38,6 +38,6 @@ cat "$5" \ | sed -E 's/ ttrts -/ ttrts \\-/g' >> $TEMP -if [ ! -e $FILE ] || [ ! -z $( diff $FILE $TEMP ) ]; then +if [ ! -e $FILE ] || [ ! -z "$( diff $FILE $TEMP )" ]; then mv -f $TEMP $FILE fi diff --git a/scripts/gen_version_header.sh b/scripts/gen_version_header.sh index 69db452..aec60e2 100755 --- a/scripts/gen_version_header.sh +++ b/scripts/gen_version_header.sh @@ -13,6 +13,6 @@ HEADER="// Auto generated ttrts version header echo "$HEADER" > "version.h.tmp" # If no difference -if [ ! -e version.h ] || [ ! -z $( diff version.h version.h.tmp ) ]; then +if [ ! -e version.h ] || [ ! -z "$( diff version.h version.h.tmp )" ]; then mv -f version.h.tmp version.h fi From 96f5c08c14071d19048bb7306696884e58a87296 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Sat, 10 Jan 2015 16:59:45 +0000 Subject: [PATCH 90/95] Update completion script with new parameters --- scripts/ttrts_complete | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/ttrts_complete b/scripts/ttrts_complete index 7b884b7..65759a9 100755 --- a/scripts/ttrts_complete +++ b/scripts/ttrts_complete @@ -5,10 +5,11 @@ test ! -z TTRTS_MAPS && TTRTS_MAPS=/usr/share/ttrts/maps/ have ttrts && function _ttrts { - commandnames="" + commandnames="--server --client --map --host localhost " for filename in ${TTRTS_MAPS}/* do map="${filename##*/}" + commandnames+="--map=$map " commandnames+="$map " done From 96153f8c609b4bd9f8b72931ba5300389ac6af9f Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Sat, 10 Jan 2015 17:04:55 +0000 Subject: [PATCH 91/95] Update launcher script with handing of return value --- source/launcher/ttrts.pl | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/source/launcher/ttrts.pl b/source/launcher/ttrts.pl index b757ee9..886fed6 100755 --- a/source/launcher/ttrts.pl +++ b/source/launcher/ttrts.pl @@ -29,14 +29,16 @@ print_usage() if ( @ARGV < 1 or 'map=s' => \$map, ) ); +# Verify we have the right parameters print "Cannot run as both client and server\n" and exit if $client and $server; print "Client requires hostname\n" and exit if $client and not $host; print "Server requires mapfile\n" and exit if $server and not $map; print "Running locally requires mapfile\n" and exit if not $server and not $client and not $map; # Run client, server or local -system("ttrts-client $host") if $client and $host; -system("ttrts-server $map") if $server and $map; -system("ttrts-local $map") if not $server and not $client and $map; +my $res = -1; +$res = system("ttrts-client $host") if $client and $host; +$res = system("ttrts-server $map") if $server and $map; +$res = system("ttrts-local $map") if not $server and not $client and $map; -print "Success!\n"; \ No newline at end of file +return $res \ No newline at end of file From 3bb576606128e8323618788a493f13ccd70521e3 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Sat, 10 Jan 2015 17:06:23 +0000 Subject: [PATCH 92/95] Fix completion script to take into account non-positional arguments --- scripts/ttrts_complete | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/ttrts_complete b/scripts/ttrts_complete index 65759a9..d257ed4 100755 --- a/scripts/ttrts_complete +++ b/scripts/ttrts_complete @@ -5,12 +5,11 @@ test ! -z TTRTS_MAPS && TTRTS_MAPS=/usr/share/ttrts/maps/ have ttrts && function _ttrts { - commandnames="--server --client --map --host localhost " + commandnames="--server --client --host= --host=localhost " for filename in ${TTRTS_MAPS}/* do map="${filename##*/}" commandnames+="--map=$map " - commandnames+="$map " done local cur prev From 5e66596d30b3a42ab1ce0a49f16baec97e9b666d Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Sat, 10 Jan 2015 17:22:34 +0000 Subject: [PATCH 93/95] Update the Readme with new server and client communication options --- source/README.md | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/source/README.md b/source/README.md index fa89aec..22b8dea 100644 --- a/source/README.md +++ b/source/README.md @@ -2,7 +2,7 @@ ttrts - Tiny Terminal RTS # SYNOPSIS - ttrts [--server] [--client] [--host=HOSTNAME] [MAPFILE] + ttrts [--server] [--client] [--host=HOSTNAME] [--map=MAPFILE] # DESCRIPTION ttrts is a tiny terminal based RTS that uses text files as order lists to control the units @@ -13,7 +13,13 @@ 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} + --server - Run in server mode, must provide a map file + + --client - Run in client mode, must provide a hostname for a running server + + --map=MAPFILE - File to read in the initial game state. Local or in ${TTRTS_MAPS} + + --host=HOSTNAME - Name of host to connect to in client mode # USAGE When invoked, ttrts will set up the game in a directory within ${TTRTS_GAMES} by the name of the map @@ -24,6 +30,8 @@ Once all order files have been received ttrts will calculate the turn and output a new gamestate file + In server and client mode, the client will output and read in these files while the server simulates the game + This process repeats until the game is over # ENVIRONMENT @@ -57,6 +65,21 @@ ... {continue for all orders} END +----------------------------------------------------------- +# SERVER/CLIENT + When in server or client mode, the game can be played across a network. If desired, a player could design an AI to act as a client instead of using the client mode and intermediary filesystem. + +## Protocol + The server is accesible on port 11715 + + To perform the handshake the server will write to the socket with the format "player PLAYER_ID name GAME_NAME", it will expect this exact information to be written back to in reply. + + Once handshake is performed, the server will write to the socket in the form of the Gamestate file as above. + + The server will then wait for a new-line delimited and END terminated list of orders + + This will be repeated until the game is over + ----------------------------------------------------------- # GAMEPLAY From f13a8bd5c4a633d56336dc3cbd57740b7704302c Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Sat, 10 Jan 2015 17:25:01 +0000 Subject: [PATCH 94/95] Ensure that hostname is also properly highlighted --- scripts/gen_manpage.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/gen_manpage.sh b/scripts/gen_manpage.sh index 0ce6110..e699063 100755 --- a/scripts/gen_manpage.sh +++ b/scripts/gen_manpage.sh @@ -35,6 +35,7 @@ cat "$5" \ | sed -E 's/-----+//g' \ | sed -E 's/`(.*)`/\\fB\1\\fR/g' \ | sed -E 's/MAPFILE/\\fImapfile\\fR/g' \ + | sed -E 's/HOSTNAME/\\fIhostname\\fR/g' \ | sed -E 's/ ttrts -/ ttrts \\-/g' >> $TEMP From ae8a3bf0c2d6ba944f37972980dbf8f5dc3c6b21 Mon Sep 17 00:00:00 2001 From: mdiluzio Date: Sat, 10 Jan 2015 17:29:22 +0000 Subject: [PATCH 95/95] Update changelog for v0.4.0 --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 1f18053..a6b299b 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,14 @@ TTRTS is from the ground up designed to be a fun way to practice programming. An ----------------------------------------------------------- ## Changelog +#### v0.4.0 +* Updated with network functionality + * Game can now be hosted with ttrts --server option + * Server can be connected to with ttrts --client +* Updated command line interface with new launcher script + * map file must now be specified with --map=FILE +* Slight refactor of libraries to account for new run targets + #### v0.3.2 * Fix bug when loading map files with walls * Fix ttrts on OSX