Implement conversion of Unit to String and back

This commit is contained in:
Marc Di Luzio 2014-12-16 13:13:02 +00:00
parent 7a75fbd369
commit b77411121a
6 changed files with 188 additions and 31 deletions

View file

@ -6,9 +6,10 @@
std::string GetStringFromOrder(const COrder& order ) std::string GetStringFromOrder(const COrder& order )
{ {
std::string ret; std::string ret;
ret += "O:";
ret += (char)order.order;
ret += " U:";
ret += std::to_string(order.unit); ret += std::to_string(order.unit);
ret += ORDER_DELIMITER;
ret += (char)order.order;
return ret; return ret;
} }
@ -19,19 +20,18 @@ COrder GetOrderFromString( const std::string& _order )
std::string order = _order; std::string order = _order;
COrder ret; COrder ret;
size_t pos = order.find(ORDER_DELIMITER); if( order.substr(0, 2) != "O:" )
if( pos != std::string::npos ) return COrder();
{ order.erase(0, 2); // Erase the O: prefix
const std::string order_unit = order.substr(0, pos);
ret.unit = (unit_id_t)atoi( order_unit.c_str() ); ret.order = (order_c)order[0]; // Grab single char oder
order.erase(0, 2); // Erase the order and a space
// Erase everything up to and including the delimiter if( order.substr(0, 2) != "U:" )
order.erase(0, pos + 1); return COrder();
order.erase(0, 2); // Erase the U: prefix
// Next single char is the order ret.unit = (unit_id_t)atoi( order.c_str() ); // Grab the unit ID
ret.order = (order_c)order[0];
}
return ret; return ret;
} }

View file

@ -6,8 +6,6 @@
#include "gametypes.h" #include "gametypes.h"
#define ORDER_DELIMITER ' '
// Type for all orders ( as a char ) // Type for all orders ( as a char )
enum class order_c : char enum class order_c : char
{ {
@ -47,7 +45,7 @@ inline bool COrder::operator== ( const COrder& rhs ) const
// Typedef a vector of orders // Typedef a vector of orders
typedef std::vector<COrder> COrderVector; typedef std::vector<COrder> COrderVector;
// Order strings stored as simply "[unit id] [order char]" // Order strings stored as simply "O:[order char] U:[unit id]"
// string <--> order conversion functions // string <--> order conversion functions
std::string GetStringFromOrder(const COrder& order ); std::string GetStringFromOrder(const COrder& order );
COrder GetOrderFromString( const std::string& order ); COrder GetOrderFromString( const std::string& order );

View file

@ -29,6 +29,121 @@ namespace
} }
} }
// Get a unit from a visual
CUnit GetUnitFromVis( unitVis_c vis )
{
CUnit unit;
unit.setFromVisual(vis);
return unit;
}
// 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]"
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);
return ret;
}
// 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 )
{
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
pos = unit.find(' ');
if( pos == std::string::npos )
return CUnit();
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
return ret;
}
// Plain constructor // Plain constructor
CUnit::CUnit() CUnit::CUnit()
: unit_id ( get_unique_unit_id() ) : unit_id ( get_unique_unit_id() )
@ -66,12 +181,15 @@ CUnit& CUnit::operator=(CUnit&& unit)
return *this; return *this;
} }
// Get a unit from a visual // Equals operator
CUnit CUnit::getUnitFromVis( unitVis_c vis ) bool CUnit::operator==(const CUnit& rhs)
{ {
CUnit unit; return (unit_id == rhs.unit_id)
unit.setFromVisual(vis); && (team_id == rhs.team_id)
return unit; && (player_id == rhs.player_id)
&& (unit_vis == rhs.unit_vis)
&& (dir == rhs.dir)
&& (pos == rhs.pos);
} }
// Update the visual representation of the unit // Update the visual representation of the unit

View file

@ -15,16 +15,19 @@ public:
// Constructor // Constructor
CUnit(); CUnit();
// Move constructor and move asignement. CUnit cannot be copied // Move constructor and move assignment. CUnit cannot be copied
CUnit(CUnit&& unit); 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 // Default dtor
~CUnit() = default; ~CUnit() = default;
// Getters for all the members // Getters for all the members
inline const unit_id_t& getID() const { return unit_id; } inline const unit_id_t& getID() const { return unit_id; }
inline const Team & getTeam() const { return team_id; } inline const Team & getTeam() const { return team_id; }
inline const player_id_t& getPlayer() const { return player_id; } inline const player_id_t& getPlayer() const { return player_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 dir_t& getDir() const { return dir; }
@ -39,6 +42,9 @@ public:
inline const uvector2& getPos() const { return pos; } inline const uvector2& getPos() const { return pos; }
inline void setPos(const uvector2& v) { pos = v; } inline void setPos(const uvector2& v) { pos = v; }
inline const unit_id_t& setIDForced(const unit_id_t& v) { return (unit_id = v); }
// Get the co-ordinate infront of the unit // Get the co-ordinate infront of the unit
uvector2 getInFront() const; uvector2 getInFront() const;
@ -48,9 +54,6 @@ public:
// Set a unit based solely on it's visual // Set a unit based solely on it's visual
bool setFromVisual( const unitVis_c& vis); bool setFromVisual( const unitVis_c& vis);
// Factory function for creating units from a visual
static CUnit getUnitFromVis( unitVis_c vis );
// Orientation methods // Orientation methods
dir_t turnLeft(); dir_t turnLeft();
dir_t turnRight(); dir_t turnRight();
@ -92,4 +95,14 @@ inline bool CUnit::valid() const
&& (unit_vis != unitVis_invalid); && (unit_vis != unitVis_invalid);
} }
// 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
std::string GetStringFromUnit(const CUnit& unit );
CUnit GetUnitFromString(const std::string& unit );
#endif //_UNIT_H_ #endif //_UNIT_H_

View file

@ -7,6 +7,7 @@ struct uvector2;
struct vector2 struct vector2
{ {
vector2() : x (0), y (0) {}
vector2( coord_t _x, coord_t _y ) vector2( coord_t _x, coord_t _y )
: x(_x) : x(_x)
, y(_y) , y(_y)
@ -32,6 +33,7 @@ struct vector2
struct uvector2 struct uvector2
{ {
uvector2() : x (0), y (0) {}
uvector2( ucoord_t _x, ucoord_t _y ) uvector2( ucoord_t _x, ucoord_t _y )
: x(_x) : x(_x)
, y(_y) , y(_y)

View file

@ -22,9 +22,35 @@ const char* tests()
return "Unit IDs the same"; return "Unit IDs the same";
} }
// Test basic invalid unit conversion
{
CUnit unit1;
std::string unit1Desc = GetStringFromUnit(unit1);
CUnit unit2 = GetUnitFromString(unit1Desc);
if ( unit1 != unit2 )
return "Failed to convert an empty unit to string and back";
}
// Test custom unit conversion
{
CUnit unit1;
unit1.setFromVisual('v');
unit1.setPlayer(0);
unit1.setTeam(Team::Green);
unit1.setPos( uvector2(5,10) );
std::string unit1Desc = GetStringFromUnit(unit1);
CUnit unit2 = GetUnitFromString(unit1Desc);
if ( unit1 != unit2 )
return "Failed to convert custom unit to string and back";
}
// Test if we can successfully create a unit from a visual // Test if we can successfully create a unit from a visual
{ {
CUnit unit = CUnit::getUnitFromVis('v'); CUnit unit = GetUnitFromVis('v');
if( unit.getVisual() != 'v' ) if( unit.getVisual() != 'v' )
return "failed to properly create V unit with factory"; return "failed to properly create V unit with factory";
} }
@ -56,7 +82,7 @@ const char* tests()
CTTRTSGame game( 5, 5 ); CTTRTSGame game( 5, 5 );
{ {
CUnit unit = CUnit::getUnitFromVis('^'); CUnit unit = GetUnitFromVis('^');
unit.setPos( {2,2} ); unit.setPos( {2,2} );
unit.setPlayer(0); unit.setPlayer(0);
unit.setTeam(Team::Red); unit.setTeam(Team::Red);
@ -65,7 +91,7 @@ const char* tests()
} }
{ {
CUnit unit = CUnit::getUnitFromVis('^'); CUnit unit = GetUnitFromVis('^');
unit.setPos( {2,2} ); unit.setPos( {2,2} );
unit.setPlayer(0); unit.setPlayer(0);
unit.setTeam(Team::Red); unit.setTeam(Team::Red);
@ -82,7 +108,7 @@ const char* tests()
{ {
CTTRTSGame game( 5, 5 ); CTTRTSGame game( 5, 5 );
CUnit unit = CUnit::getUnitFromVis('>'); CUnit unit = GetUnitFromVis('>');
const unit_id_t id = unit.getID(); const unit_id_t id = unit.getID();
COrder order; COrder order;
@ -113,7 +139,7 @@ const char* tests()
unit_id_t id; unit_id_t id;
{ {
CUnit unit = CUnit::getUnitFromVis('>'); CUnit unit = GetUnitFromVis('>');
id = unit.getID(); id = unit.getID();
COrder order; COrder order;
@ -131,7 +157,7 @@ const char* tests()
return "Game failed to issue valid order"; return "Game failed to issue valid order";
} }
{ {
CUnit unit = CUnit::getUnitFromVis('<'); CUnit unit = GetUnitFromVis('<');
unit.setPos( {1,0} ); unit.setPos( {1,0} );
unit.setPlayer(2); unit.setPlayer(2);