Move source code into source subfolder

This commit is contained in:
Marc Di Luzio 2014-12-16 13:13:02 +00:00
parent 870f459f75
commit d0d3834449
23 changed files with 0 additions and 0 deletions

View file

@ -0,0 +1,17 @@
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} )

32
source/game/README.md Normal file
View file

@ -0,0 +1,32 @@
Game Design
=================
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, each turn receives data on the status of the board.
Each player must then issue a single command to each unit in their control.
The engine then takes all commands, evaluates all movement first simultaneously, then all other commands.
All attempted movement to the same square by two or more units will fail.
Friendly fire is enabled by default
--------------------------------------------------------
Units
-----
Currently only one unit, this will be expanded in the future.
Units have a set of properties, and commands than can be issued.
All units take one hit to kill.
##### properties
See [the unit header](unit.h) for full details on unit properties
##### orders
Commands take the form of a single char literal.
See [the order header](order.h) for details on the orders

435
source/game/game.cpp Normal file
View file

@ -0,0 +1,435 @@
#include "game.h"
#include <algorithm>
#include <string.h>
CTTRTSGame::CTTRTSGame( ucoord_t c, ucoord_t r )
: dimensions( c,r )
, turn (0), name ( "Custom_Game" )
{
}
// Move constructor
CTTRTSGame::CTTRTSGame(CTTRTSGame&& game)
: m_OrderUnitPairs(std::move(game.m_OrderUnitPairs))
, dimensions(std::move(game.dimensions))
, turn(std::move(game.turn))
, name(std::move(game.name))
{
}
CTTRTSGame& CTTRTSGame::operator=(CTTRTSGame&& game)
{
m_OrderUnitPairs = std::move(game.m_OrderUnitPairs);
dimensions = std::move(game.dimensions);
turn = std::move(game.turn);
name = std::move(game.name);
return *this;
}
// Interpret a string of orders
int CTTRTSGame::IssueOrders( player_id_t player, const std::string& _orders )
{
COrderVector orderVector;
// Copy the const orders into a buffer we can edit
std::string orders = _orders;
// Find a line end
size_t pos;
while ( (pos = orders.find('\n')) != std::string::npos )
{
// Grab the string up to the line end
const std::string sorder = orders.substr(0, pos);
// Erase all of string up to and including the line end
orders.erase(0,pos+1);
// Create an order from the string and push it back
COrder order = GetOrderFromString( sorder );
orderVector.push_back(order);
}
// Call our add order by vector method
return IssueOrders(player,orderVector);
}
// Issue orders by vector to the game
int CTTRTSGame::IssueOrders( player_id_t player, const COrderVector& orders )
{
// verify all the orders
for ( auto order : orders )
{
// If any order returns non-zero, back out
if ( IssueOrder(player,order) )
return 1;
}
return 0;
}
// Issue a single order
int CTTRTSGame::IssueOrder( player_id_t player, const COrder& order )
{
// Verify the order
if ( VerifyOrder(player,order) )
return 1;
// Get the right unit for the order
for ( OrderUnitPair& pair : m_OrderUnitPairs )
{
if ( pair.unit.getID() == order.unit )
{
pair.order = order;
return 0;
}
}
// Unit was not found, return 2
return 2;
}
// Verify a position
int CTTRTSGame::VerifyPos(uvector2 vec) const
{
// Simply check if within the bounds of our dimensions for now
if ( ( vec.x >= dimensions.x )
|| ( vec.y >= dimensions.y ) )
{
return 1;
}
return 0;
}
// Get a units new position
uvector2 CTTRTSGame::GetNewPosition( const OrderUnitPair& pair ) const
{
// Grab the order
switch ( pair.order.command)
{
// For forward orders, grab in front
case command_c::F:
return pair.unit.getInFront();
break;
// For all other orders, just grab the old position
default:
return pair.unit.getPos();
}
}
// Simulate and progress to the next turn
// Returns non-zero if simulation failed
int CTTRTSGame::SimulateToNextTurn()
{
int error = 0;
// Attempt all movement orders
for ( OrderUnitPair& pair : m_OrderUnitPairs )
{
switch ( pair.order.command)
{
case command_c::F:
{
// Verify new unit position will be on the board
uvector2 newpos = GetNewPosition(pair);
// Verify the position is even available
bool possible = ( VerifyPos(newpos) == 0 );
if ( possible )
{
// If any unit is in this spot, or moving unit moving to said spot, reject this
for ( const OrderUnitPair& pair2 : m_OrderUnitPairs )
{
if( GetNewPosition(pair2) != newpos )
{
possible = false;
break;
}
}
}
// If the movement is still possible
if ( possible )
{
pair.unit.setPos(newpos);
pair.order = COrder();
}
}
break;
default:
break;
}
}
// Vector of units to kill
std::vector< unit_id_t > toKill;
// Attempt all actions
for ( OrderUnitPair& pair : m_OrderUnitPairs )
{
switch ( pair.order.command)
{
case command_c::A:
{
// Verify that there's a unit in front to attack
uvector2 infront = pair.unit.getInFront();
// Check if there's any unit in front
// FRIENDLY FIRE IS ENABLED
for ( const OrderUnitPair& pair2 : m_OrderUnitPairs )
{
// if the unit is infront of our unit, then add it to the kill list
if( pair2.unit.getPos() == infront )
{
toKill.push_back(pair2.unit.getID());
pair.order = COrder();
break;
}
}
}
break;
case command_c::L:
{
// Simply turn left
pair.unit.turnLeft();
pair.order = COrder();
}
break;
case command_c::R:
{
// Simply turn right
pair.unit.turnRight();
pair.order = COrder();
}
break;
default:
break;
}
}
// Sort and erase all duplicates
std::sort( toKill.begin(), toKill.end() );
toKill.erase( std::unique( toKill.begin(), toKill.end() ), toKill.end() );
// Iterate through all kill orders
for ( auto id : toKill )
{
// Kill the units
for ( OrderUnitPairVector::iterator it = m_OrderUnitPairs.begin();
it != m_OrderUnitPairs.end();
it++ )
{
if( (*it).unit.getID() == id )
{
// Remove the unit from our alive unit pairs
m_OrderUnitPairs.erase(it);
break;
}
}
}
// Clear all orders
for ( OrderUnitPair& pair : m_OrderUnitPairs )
{
pair.order = COrder();
}
// Increment the current turn
turn++;
return error;
}
// Add a unit, nonzero return value indicates error
int CTTRTSGame::AddUnit( CUnit&& unit )
{
// Verify the unit
if( !unit.valid() )
return 1;
// Verify if the unit can be placed on the current board
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 OrderUnitPair& 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()) );
return 0;
}
// Add a units, nonzero return value indicates error
int CTTRTSGame::AddUnits( CUnitVector&& units )
{
CUnitVector::iterator it;
for ( it = units.begin(); it != units.end(); it++ )
{
// Attempt the unit add
if ( AddUnit( std::move(*it) ) )
return 1;
}
// All units added successfully
return 0;
}
// Verify any order
int CTTRTSGame::VerifyOrder( player_id_t player, const COrder& order ) const
{
int ret = 1;
// Grab the unit ID
const unit_id_t unitID = order.unit;
// Attempt to find the unit
for ( const OrderUnitPair& pair : m_OrderUnitPairs )
{
// Accept if we have the unit
if ( pair.unit.getID() == unitID )
{
ret = 0;
break;
}
}
// for now, as long as the unit exists we can attempt the order
return ret;
}
// Get unit by unit ID
const CUnit& CTTRTSGame::GetUnitByIDConst( unit_id_t id ) const
{
for ( const OrderUnitPair& pair : m_OrderUnitPairs )
{
// Attempt the unit add
if ( pair.unit.getID() )
return pair.unit;
}
// Return an invalid unit
static CUnit invalid_unit;
return invalid_unit;
}
// Get unit by unit ID
CUnit& CTTRTSGame::GetUnitByID( unit_id_t id )
{
for ( OrderUnitPair& pair : m_OrderUnitPairs )
{
// Attempt the unit add
if ( pair.unit.getID() )
return pair.unit;
}
// Return an invalid unit
static CUnit invalid_unit;
return invalid_unit;
}
// Check if we have a win state
Team CTTRTSGame::CheckForWin() const
{
// Array of units for each Team
unsigned int units[(int) Team::NUM_INVALID];
memset(units,0,sizeof(units));
// Count up all the units for each Team
for ( const OrderUnitPair& pair : m_OrderUnitPairs )
{
const int team = (int)pair.unit.getTeam();
units[team] += 1;
}
// Default winning Team to invalid (no win)
Team winningTeam = Team::NUM_INVALID;
// For each of the teams
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 )
{
winningTeam = (Team)i;
}
// Otherwise, if there are units in this Team and the winning Team HAS been set
else if ( units[i] > 0 )
{
// Set back to invalid and break out of the loop
winningTeam = Team::NUM_INVALID;
break;
}
}
return winningTeam;
}
// Get the game information as a string
std::string CTTRTSGame::GetStateAsString() const
{
// Print out the header
char header[64];
snprintf(header, 512, GAME_HEADER_FORMATTER , name.c_str(), dimensions.x, dimensions.y, turn );
// Gather unit information
std::string units;
for ( const OrderUnitPair& 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;
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 buf[64];
unsigned int turn;
unsigned int sizex;
unsigned int sizey;
sscanf(header.c_str(), GAME_HEADER_FORMATTER, buf, &sizex, &sizey, &turn );
CTTRTSGame game(sizex,sizey);
game.SetName(buf);
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));
}
return game;
}

119
source/game/game.h Normal file
View file

@ -0,0 +1,119 @@
#ifndef _GAME_H_
#define _GAME_H_
#include "unit.h"
#include "gametypes.h"
#include "order.h"
#define GAME_HEADER_FORMATTER "===== %s =====\nSIZE:[%u,%u]\nTURN:%u"
#define GAME_HEADER_DELIMITER "~~~~\n"
// Type for order and unit pairs
struct OrderUnitPair
{
// Straight up move constructor
OrderUnitPair( OrderUnitPair&& other )
: unit ( std::move(other.unit) )
, order ( other.order )
{}
// Multi parameter constructor
OrderUnitPair( CUnit&& u, COrder o )
: unit ( std::move(u) )
, order ( o )
{}
// Move assignment operator
inline OrderUnitPair& operator=( OrderUnitPair&& 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< OrderUnitPair > OrderUnitPairVector;
// Full TTRTS Game class
// Stores information about the game
// Can convert from a string or to a string
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);
// move asignment operator
CTTRTSGame& operator=(CTTRTSGame&& game);
// Simulate and progress to the next turn
// 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
Team 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_id_t player, const std::string& orders );
int IssueOrders( player_id_t player, const COrderVector& orders );
int IssueOrder( player_id_t player, const COrder& order );
// Add a units to the game, nonzero return value indicates error
int AddUnit( CUnit&& unit );
int AddUnits( CUnitVector&& units );
// Get the number of units
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; }
// Get a unit by it's ID
const CUnit& GetUnitByIDConst( unit_id_t id ) const;
// Get 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; }
// Set the turn of the game
inline int SetTurn( int in ) { return (turn = in); }
private:
// Verify any order or position - non-zero is error
int VerifyOrder( player_id_t player, const COrder& order ) const;
int VerifyPos( uvector2 vec ) const;
// Get a units new position after an order
uvector2 GetNewPosition( const OrderUnitPair& pair ) const;
// Get unit by unit 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
};
#endif //_GAME_H_

25
source/game/gametypes.h Normal file
View file

@ -0,0 +1,25 @@
#ifndef _GAME_TYPES_H_
#define _GAME_TYPES_H_
#include <limits> // std::numeric_limits
// Type for a team IDs
enum class Team : char
{
Red = 0,
Blue,
Green,
Yellow,
NUM_INVALID
};
typedef unsigned char player_id_t; // Type for player IDs
typedef unsigned short unit_id_t; // Type for unit IDs
typedef char unitVis_c; // Typedef for unit visual representations
static const player_id_t player_id_invalid = std::numeric_limits<player_id_t>::max();
static const unit_id_t unit_id_invalid = std::numeric_limits<unit_id_t>::max();
static const unitVis_c unitVis_invalid = std::numeric_limits<unitVis_c>::max();
#endif //_GAME_TYPES_H_

33
source/game/order.cpp Normal file
View file

@ -0,0 +1,33 @@
#include <string.h>
#include "order.h"
// Convert an order to a string
std::string GetStringFromOrder(const COrder& 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
COrder GetOrderFromString( const std::string& order )
{
COrder ret;
char corder;
unsigned int unit;
sscanf(order.c_str(), ORDER_FORMATTER,
&corder,
&unit);
ret.command = (command_c)corder;
ret.unit = unit;
return ret;
}

54
source/game/order.h Normal file
View file

@ -0,0 +1,54 @@
#ifndef _ORDERS_H_
#define _ORDERS_H_
#include <vector>
#include <string>
#include "gametypes.h"
#define ORDER_FORMATTER "ORDER:%c id:%u"
// Type for all orders ( as a char )
enum class command_c : char
{
F = 'F',
L = 'L',
R = 'R',
A = 'A',
NUM_INVALID
};
// Container for an order
struct COrder
{
// Base constructor makes invalid order
COrder()
: unit ( unit_id_invalid )
, command( command_c::NUM_INVALID )
{}
// Unit order is for
unit_id_t unit;
// Order command issued
command_c command;
// Basic operators
inline bool operator==( const COrder& rhs ) const;
inline bool operator!=( const COrder& rhs ) const { return !(*this==rhs); }
};
// Simple == operator
inline bool COrder::operator== ( const COrder& rhs ) const
{
return ( unit == rhs.unit ) && ( command == rhs.command);
}
// Typedef a vector of orders
typedef std::vector<COrder> COrderVector;
// string <--> order conversion functions
std::string GetStringFromOrder(const COrder& order );
COrder GetOrderFromString( const std::string& order );
#endif //_ORDERS_H_

261
source/game/unit.cpp Normal file
View file

@ -0,0 +1,261 @@
#include <string.h>
#include "unit.h"
#include <map> // for std::map
namespace
{
// Helper function for generating unique unit ids during static init
unit_id_t get_unique_unit_id()
{
static unit_id_t p = 0;
return p++;
}
// Map of visual representation of unit V
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()
{
static const dir_to_vis_map sk_visMap =
{
{dir_t::N,'^'},
{dir_t::E,'>'},
{dir_t::S,'v'},
{dir_t::W,'<'},
};
return sk_visMap;
}
}
// Get a unit from a visual
CUnit CUnit::GetUnitFromVis( unitVis_c vis )
{
CUnit unit;
unit.setFromVisual(vis);
return unit;
}
// 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];
memset(buff,0,sizeof(buff));
snprintf(buff,128, UNIT_FORMATTER,
unit.unit_id,
(int)unit.team_id,
unit.player_id,
unit.unit_vis,
unit.dir,
unit.pos.x,
unit.pos.y );
return buff;
}
// 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;
unsigned int player;
char vis;
char dir;
unsigned int posx;
unsigned int posy;
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_id_t)player;
ret.unit_vis = (unitVis_c)vis;
ret.dir = (dir_t)dir;
ret.pos = uvector2(posx,posy);
return ret;
}
// Plain constructor
CUnit::CUnit()
: unit_id ( get_unique_unit_id() )
, team_id ( Team::NUM_INVALID )
, unit_vis ( unitVis_invalid )
, player_id ( player_id_invalid )
, dir ( dir_t::S )
, pos ( { ucoord_invalid, ucoord_invalid } )
{
updateMyVisual();
}
// 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) )
{
updateMyVisual();
}
// Move asignment operator
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) ;
return *this;
}
// Equals operator
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);
}
// Update the visual representation of the unit
unitVis_c CUnit::updateMyVisual()
{
// Start at 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);
return getVisual();
}
// Set the unit from visual
bool CUnit::setFromVisual( const unitVis_c& vis )
{
dir_to_vis_map::const_iterator it;
for( it = get_vis_map_V().begin(); it != get_vis_map_V().end(); it++ )
{
if( it->second == vis )
{
dir = it->first;
updateMyVisual();
return true;
}
}
// No matching direction to visual
return false;
}
// Turn unit left
dir_t CUnit::turnLeft()
{
switch( dir )
{
case dir_t::N:
dir = dir_t::W;
break;
case dir_t::E:
dir = dir_t::N;
break;
case dir_t::S:
dir = dir_t::E;
break;
case dir_t::W:
dir = dir_t::S;
break;
}
updateMyVisual();
return getDir();
}
// Turn unit right
dir_t CUnit::turnRight()
{
switch( dir )
{
case dir_t::N:
dir = dir_t::E;
break;
case dir_t::E:
dir = dir_t::S;
break;
case dir_t::S:
dir = dir_t::W;
break;
case dir_t::W:
dir = dir_t::N;
break;
}
updateMyVisual();
return getDir();
}
// Turn unit around
dir_t CUnit::turnAround()
{
switch( dir )
{
case dir_t::N:
dir = dir_t::S;
break;
case dir_t::E:
dir = dir_t::W;
break;
case dir_t::S:
dir = dir_t::N;
break;
case dir_t::W:
dir = dir_t::E;
break;
}
updateMyVisual();
return getDir();
}
// Get the co-ordinate infront of the unit
uvector2 CUnit::getInFront() const
{
vector2 delta = vecFromDir(dir);
return pos + delta;
}

102
source/game/unit.h Normal file
View file

@ -0,0 +1,102 @@
#ifndef _UNIT_H_
#define _UNIT_H_
#include <string>
#include <vector>
#include "gametypes.h"
#include "vector2.h"
#define UNIT_FORMATTER "UNIT:%u tm:%u pl:%u vs:%c dr:%c ps:[%u,%u]"
// Base unit type
class CUnit
{
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();
// Move constructor and move assignment. CUnit cannot be copied
CUnit(CUnit&& unit);
CUnit& operator=(CUnit&& unit);
bool operator==(const CUnit& rhs);
bool operator!=(const CUnit& rhs) { return !(*this == rhs); }
// Default dtor
~CUnit() = default;
// 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 player_id_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 Team setTeam(const Team & v) { return (team_id = v); }
inline player_id_t setPlayer(const player_id_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; }
// Get the co-ordinate in front of the unit
uvector2 getInFront() const;
// Check unit is valid
inline bool valid() const;
// Set a unit based solely on it's visual
bool setFromVisual( const unitVis_c& vis);
// Orientation methods
dir_t turnLeft();
dir_t turnRight();
dir_t turnAround();
private:
// Update my visual must be called when setting direction
unitVis_c updateMyVisual();
// Unit ID
unit_id_t unit_id;
// Visual
unitVis_c unit_vis;
// Team ID
Team team_id;
// Owner ID
player_id_t player_id;
// Direction
dir_t dir;
// Position
uvector2 pos;
};
// Typedef for a vector of units
typedef std::vector< CUnit > CUnitVector;
// Simple validation
inline bool CUnit::valid() const
{
return (unit_id != unit_id_invalid )
&& (team_id != Team::NUM_INVALID )
&& (player_id != player_id_invalid)
&& (unit_vis != unitVis_invalid);
}
#endif //_UNIT_H_