From 8a486fdd40295bb42aebe872ef5a7546e815703f Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Tue, 16 Dec 2014 13:13:02 +0000 Subject: [PATCH] Use snprintf and sscanf instead of std::string tomfoolery Rename order_c to command_c for better readability --- game/game.cpp | 16 +++--- game/orders.cpp | 34 ++++++------- game/orders.h | 11 +++-- game/unit.cpp | 128 ++++++++++++++---------------------------------- game/unit.h | 3 +- test/test.cpp | 6 +-- 6 files changed, 71 insertions(+), 127 deletions(-) diff --git a/game/game.cpp b/game/game.cpp index 8f4e988..d5eb170 100644 --- a/game/game.cpp +++ b/game/game.cpp @@ -84,10 +84,10 @@ uvector2 CTTRTSGame::GetNewPosition( const OrderUnitPair& pair ) const { // Grab the order - switch ( pair.order.order ) + switch ( pair.order.command) { // For forward orders, grab in front - case order_c::F: + case command_c::F: return pair.unit.getInFront(); break; // For all other orders, just grab the old position @@ -105,9 +105,9 @@ int CTTRTSGame::SimulateToNextTurn() // Attempt all movement orders for ( OrderUnitPair& pair : m_OrderUnitPairs ) { - switch ( pair.order.order ) + switch ( pair.order.command) { - case order_c::F: + case command_c::F: { // Verify new unit position will be on the board uvector2 newpos = GetNewPosition(pair); @@ -147,9 +147,9 @@ int CTTRTSGame::SimulateToNextTurn() // Attempt all actions for ( OrderUnitPair& pair : m_OrderUnitPairs ) { - switch ( pair.order.order ) + switch ( pair.order.command) { - case order_c::A: + case command_c::A: { // Verify that there's a unit in front to attack uvector2 infront = pair.unit.getInFront(); @@ -168,14 +168,14 @@ int CTTRTSGame::SimulateToNextTurn() } } break; - case order_c::L: + case command_c::L: { // Simply turn left pair.unit.turnLeft(); pair.order = COrder(); } break; - case order_c::R: + case command_c::R: { // Simply turn right pair.unit.turnRight(); diff --git a/game/orders.cpp b/game/orders.cpp index 80bd284..ef0c7aa 100644 --- a/game/orders.cpp +++ b/game/orders.cpp @@ -1,3 +1,4 @@ +#include #include "orders.h" #include "mathtypes.h" @@ -5,33 +6,30 @@ // Convert an order to a string std::string GetStringFromOrder(const COrder& order ) { - std::string ret; - ret += "O:"; - ret += (char)order.order; - ret += " U:"; - ret += std::to_string(order.unit); + static char buff[128]; + memset(buff,0,sizeof(buff)); - return ret; + snprintf(buff,128, ORDER_FORMATTER, + order.command, + order.unit); + + return buff; } // Convert a string to an order -COrder GetOrderFromString( const std::string& _order ) +COrder GetOrderFromString( const std::string& order ) { - std::string order = _order; COrder ret; - if( order.substr(0, 2) != "O:" ) - return COrder(); - order.erase(0, 2); // Erase the O: prefix + char corder; + unsigned int unit; - ret.order = (order_c)order[0]; // Grab single char oder - order.erase(0, 2); // Erase the order and a space + sscanf(order.c_str(), ORDER_FORMATTER, + &corder, + &unit); - if( order.substr(0, 2) != "U:" ) - return COrder(); - order.erase(0, 2); // Erase the U: prefix - - ret.unit = (unit_id_t)atoi( order.c_str() ); // Grab the unit ID + ret.command = (command_c)corder; + ret.unit = unit; return ret; } diff --git a/game/orders.h b/game/orders.h index dde304f..cb1cf80 100644 --- a/game/orders.h +++ b/game/orders.h @@ -7,7 +7,7 @@ #include "gametypes.h" // Type for all orders ( as a char ) -enum class order_c : char +enum class command_c : char { F = 'F', L = 'L', @@ -22,14 +22,14 @@ struct COrder // Base constructor makes invalid order COrder() : unit ( unit_id_invalid ) - , order ( order_c::NUM_INVALID ) + , command( command_c::NUM_INVALID ) {} // Unit order is for unit_id_t unit; // Order command issued - order_c order; + command_c command; // Basic operators inline bool operator==( const COrder& rhs ) const; @@ -39,13 +39,14 @@ struct COrder // Simple == operator inline bool COrder::operator== ( const COrder& rhs ) const { - return ( unit == rhs.unit ) && ( order == rhs.order ); + return ( unit == rhs.unit ) && ( command == rhs.command); } // Typedef a vector of orders typedef std::vector COrderVector; -// Order strings stored as simply "O:[order char] U:[unit id]" +#define ORDER_FORMATTER "ORDER co:%c un:%u" + // string <--> order conversion functions std::string GetStringFromOrder(const COrder& order ); COrder GetOrderFromString( const std::string& order ); diff --git a/game/unit.cpp b/game/unit.cpp index 9e5591b..c9b917a 100644 --- a/game/unit.cpp +++ b/game/unit.cpp @@ -1,3 +1,4 @@ +#include #include "unit.h" #include // for std::map @@ -38,108 +39,53 @@ CUnit GetUnitFromVis( unitVis_c vis ) } // Get a string descriptor of a unit -// "U:[unit_id] T:[team_id] P:[player_id] V:[unit_vis] D:[dir] POS:[pos.x],[pos.y]" +// "U id:[unit_id] team:[team_id] player:[player_id] vis:[unit_vis] dir:[dir] pos:[pos.x],[pos.y]" std::string GetStringFromUnit(const CUnit& unit ) { - std::string ret; - ret += "U:"; - ret += std::to_string(unit.getID()); - ret += " T:"; - ret += std::to_string((int)unit.getTeam()); - ret += " P:"; - ret += std::to_string(unit.getPlayer()); - ret += " V:"; - ret += (char)unit.getVisual(); - ret += " D:"; - ret += (char)unit.getDir(); - ret += " POS:"; - ret += std::to_string(unit.getPos().x); - ret += ","; - ret += std::to_string(unit.getPos().y); + static char buff[128]; + memset(buff,0,sizeof(buff)); - return ret; + snprintf(buff,128, UNIT_FORMATTER, + unit.getID(), + (int)unit.getTeam(), + unit.getPlayer(), + unit.getVisual(), + unit.getDir(), + unit.getPos().x, + unit.getPos().y ); + + return buff; } // Get a unit from a string descriptor -// "U:[unit_id] T:[team_id] P:[player_id] V:[unit_vis] D:[dir] POS:[pos.x],[pos.y]" -CUnit GetUnitFromString(const std::string& _unit ) +// "U id:[unit_id] team:[team_id] player:[player_id] vis:[unit_vis] dir:[dir] pos:[pos.x],[pos.y]" +CUnit GetUnitFromString(const std::string& unit ) { - std::string unit = _unit; CUnit ret; - size_t pos; - // UNIT ID - if( unit.substr(0, 2) != "U:" ) - return CUnit(); - unit.erase(0, 2); // Erase the U: prefix + unsigned int id; + int team; + unsigned int player; + char vis; + char dir; + unsigned int posx; + unsigned int posy; - pos = unit.find(' '); - if( pos == std::string::npos ) - return CUnit(); + sscanf(unit.c_str(), UNIT_FORMATTER, + &id, + &team, + &player, + &vis, + &dir, + &posx, + &posy ); - const unit_id_t id = (unit_id_t)atoi( unit.substr(0,pos).c_str() ); // Grab the ID - ret.setIDForced( id ); // Force set the ID - unit.erase(0, pos+1); // Erase the ID and a space - - // TEAM - if( unit.substr(0, 2) != "T:" ) - return CUnit(); - unit.erase(0, 2); // Erase the T: prefix - - pos = unit.find(' '); - if( pos == std::string::npos ) - return CUnit(); - - const Team team = (Team)atoi( unit.substr(0,pos).c_str() ); // Grab the ID - ret.setTeam( team ); // Force set the ID - unit.erase(0, pos+1); // Erase the team and a space - - // PLAYER - if( unit.substr(0, 2) != "P:" ) - return CUnit(); - unit.erase(0, 2); // Erase the P: prefix - - pos = unit.find(' '); - if( pos == std::string::npos ) - return CUnit(); - - const player_id_t player = (player_id_t)atoi( unit.substr(0,pos).c_str() ); // Grab the ID - ret.setPlayer( player ); // Force set the ID - unit.erase(0, pos+1); // Erase the player and a space - - // VISUAL - if( unit.substr(0, 2) != "V:" ) - return CUnit(); - unit.erase(0, 2); // Erase the W: prefix - - unitVis_c vis = unit[0]; - ret.setVisual(vis); - unit.erase(0, 2); // Erase the vis and a space - - // DIRECTION - if( unit.substr(0, 2) != "D:" ) - return CUnit(); - unit.erase(0, 2); // Erase the D: prefix - - dir_t dir = (dir_t)unit[0]; - ret.setDir(dir); - unit.erase(0, 2); // Erase the ID and a space - - // POSITION - if( unit.substr(0, 4) != "POS:" ) - return CUnit(); - unit.erase(0, 4); // Erase the Pos: prefix - - pos = unit.find(','); - if( pos == std::string::npos ) - return CUnit(); - - uvector2 upos; - upos.x = (ucoord_t)atoi( unit.substr(0,pos).c_str() ); // Grab the x - unit.erase(0, pos+1); // Erase the x and the comma - - upos.y = (ucoord_t)atoi( unit.c_str() ); // Grab the y from what's left - ret.setPos( upos ); //Set the position + ret.setIDForced((unit_id_t)id); + ret.setTeam((Team)team); + ret.setPlayer((player_id_t)player); + ret.setVisual((unitVis_c)vis); + ret.setDir((dir_t)dir); + ret.setPos(uvector2(posx,posy)); return ret; } diff --git a/game/unit.h b/game/unit.h index a6ef88d..9c1ee0d 100644 --- a/game/unit.h +++ b/game/unit.h @@ -99,9 +99,8 @@ inline bool CUnit::valid() const // Factory function for creating units from a visual CUnit GetUnitFromVis( unitVis_c vis ); -// Units strings stored as -// "U:[unit_id] T:[team_id] P:[player_id] V:[unit_vis] D:[dir] POS:[pos.x],[pos.y]" // Unit <--> string conversion functions +#define UNIT_FORMATTER "UNIT id:%u tm:%u pl:%u vs:%c dr:%c ps:%u,%u" std::string GetStringFromUnit(const CUnit& unit ); CUnit GetUnitFromString(const std::string& unit ); diff --git a/test/test.cpp b/test/test.cpp index 160f6bb..84e6b39 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -58,7 +58,7 @@ const char* tests() // Test if we can successfully convert orders back and forth { COrder order; - order.order = order_c::F; + order.command = command_c::F; order.unit = 10; std::string order_string = GetStringFromOrder(order); COrder order2 = GetOrderFromString(order_string); @@ -120,7 +120,7 @@ const char* tests() return "Game failed to add valid unit"; order.unit = id; - order.order = order_c::F; + order.command = command_c::F; if( game.IssueOrder(0,order) ) return "Game failed to issue valid order"; @@ -151,7 +151,7 @@ const char* tests() return "Game failed to add valid unit"; order.unit = id; - order.order = order_c::A; + order.command = command_c::A; if( game.IssueOrder(0,order) ) return "Game failed to issue valid order";