Finialise the full game step
Had to rework a ton of code from bad design. NOTE: FRIENDLY FIRE IS ON >:D
This commit is contained in:
		
							parent
							
								
									6fc41914f7
								
							
						
					
					
						commit
						aee703b107
					
				
					 7 changed files with 379 additions and 57 deletions
				
			
		
							
								
								
									
										171
									
								
								game/game.cpp
									
										
									
									
									
								
							
							
						
						
									
										171
									
								
								game/game.cpp
									
										
									
									
									
								
							| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
#include "game.h"
 | 
					#include "game.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <algorithm>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Interpret a string of orders
 | 
					// Interpret a string of orders
 | 
				
			||||||
int CTTRTSGame::IssueOrders( player_id_t player, const std::string& _orders )
 | 
					int CTTRTSGame::IssueOrders( player_id_t player, const std::string& _orders )
 | 
				
			||||||
| 
						 | 
					@ -40,34 +41,81 @@ int CTTRTSGame::IssueOrder( player_id_t player, const COrder& order )
 | 
				
			||||||
	if ( VerifyOrder(player,order) )
 | 
						if ( VerifyOrder(player,order) )
 | 
				
			||||||
			return 1;
 | 
								return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	m_orders.push_back(order);
 | 
					    for ( OrderUnitPair& pair : m_OrderUnitPairs )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ( pair.unit.getID() == order.unit )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            pair.order = order;
 | 
				
			||||||
 | 
					            return 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Verify a position
 | 
				
			||||||
 | 
					int CTTRTSGame::VerifyPos(uvector2 vec) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if ( ( vec.x >= dimentions.x )
 | 
				
			||||||
 | 
					        || ( vec.y >= dimentions.y ) )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Get a units new position
 | 
				
			||||||
 | 
					uvector2 CTTRTSGame::GetNewPosition( const OrderUnitPair& pair ) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    switch ( pair.order.order )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    case order_c::F:
 | 
				
			||||||
 | 
					        return pair.unit.getInFront();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return { ucoord_invalid,ucoord_invalid };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Simulate and progress to the next turn
 | 
					// Simulate and progress to the next turn
 | 
				
			||||||
// Returns non-zero if simulation failed
 | 
					// Returns non-zero if simulation failed
 | 
				
			||||||
int CTTRTSGame::SimulateToNextTurn()
 | 
					int CTTRTSGame::SimulateToNextTurn()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int error;
 | 
					    int error = 0;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    OrderUnitPairVector orderPairs;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Grab all movement orders
 | 
					 | 
				
			||||||
    for ( auto order : m_orders )
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        const OrderUnitPair pair = { order, GetUnitByID(order.unit) };
 | 
					 | 
				
			||||||
        orderPairs.push_back(pair);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Attempt all movement orders
 | 
					    // Attempt all movement orders
 | 
				
			||||||
    for ( auto pair : orderPairs )
 | 
					    for ( OrderUnitPair& pair : m_OrderUnitPairs )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        switch (  pair.order.order )
 | 
					        switch (  pair.order.order )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
        case order_c::F:
 | 
					        case order_c::F:
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                // Verify new unit position will be on the board
 | 
					                // 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;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -77,29 +125,74 @@ int CTTRTSGame::SimulateToNextTurn()
 | 
				
			||||||
    std::vector< unit_id_t > toKill;
 | 
					    std::vector< unit_id_t > toKill;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Attempt all actions
 | 
					    // Attempt all actions
 | 
				
			||||||
    for ( auto pair : orderPairs )
 | 
					    for ( OrderUnitPair& pair : m_OrderUnitPairs )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        switch (  pair.order.order )
 | 
					        switch (  pair.order.order )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
        case order_c::A:
 | 
					        case order_c::A:
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                // Verify that there's a unit in front to attack
 | 
					                // 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(pair.unit.getID());
 | 
				
			||||||
 | 
					                        pair.order = COrder();
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case order_c::L:
 | 
					        case order_c::L:
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                pair.unit.turnLeft();
 | 
				
			||||||
 | 
					                pair.order = COrder();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
        case order_c::R:
 | 
					        case order_c::R:
 | 
				
			||||||
            // Nothing needed here, these orders can always be carried out
 | 
					            {
 | 
				
			||||||
 | 
					                pair.unit.turnRight();
 | 
				
			||||||
 | 
					                pair.order = COrder();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            break;
 | 
					            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 )
 | 
					    for ( auto id : toKill )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        // Kill the units
 | 
				
			||||||
 | 
					        for ( OrderUnitPairVector::iterator it = m_OrderUnitPairs.begin();
 | 
				
			||||||
 | 
					              it != m_OrderUnitPairs.end();
 | 
				
			||||||
 | 
					              it++ )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if( (*it).unit.getID() == id )
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                // Add the dead unit to our dead unit list
 | 
				
			||||||
 | 
					                m_deadUnits.push_back(std::move((*it).unit));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Remove the unit from our alive unit pairs
 | 
				
			||||||
 | 
					                m_OrderUnitPairs.erase(it);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Clear all orders
 | 
						// Clear all orders
 | 
				
			||||||
	m_orders.resize(0);
 | 
					    for ( OrderUnitPair& pair : m_OrderUnitPairs )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        pair.order = COrder();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return error;
 | 
						return error;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -114,10 +207,11 @@ int CTTRTSGame::AddUnit( CUnit&& unit )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Verify if the unit can be placed on the current board
 | 
						// Verify if the unit can be placed on the current board
 | 
				
			||||||
	const uvector2 pos = unit.getPos();
 | 
						const uvector2 pos = unit.getPos();
 | 
				
			||||||
	if( (pos.x < dimentions.x) && (pos.y < dimentions.y) )
 | 
					    if( (pos.x >= dimentions.x) || (pos.y >= dimentions.y) )
 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	m_allUnits.push_back(std::move(unit));
 | 
					    // Add the unit with a blank order
 | 
				
			||||||
 | 
					    m_OrderUnitPairs.push_back( OrderUnitPair(std::move(unit), COrder()) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -141,35 +235,52 @@ int CTTRTSGame::AddUnits( CUnitVector&& units )
 | 
				
			||||||
// Verify any order
 | 
					// Verify any order
 | 
				
			||||||
int CTTRTSGame::VerifyOrder( player_id_t player, const COrder& order ) const
 | 
					int CTTRTSGame::VerifyOrder( player_id_t player, const COrder& order ) const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    int ret = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Grab the unit ID
 | 
						// Grab the unit ID
 | 
				
			||||||
	const unit_id_t unitID = order.unit;
 | 
						const unit_id_t unitID = order.unit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Attempt to find the unit
 | 
					    // Attempt to find the unit
 | 
				
			||||||
	bool unitFound = false;
 | 
					    for ( const OrderUnitPair& pair : m_OrderUnitPairs )
 | 
				
			||||||
    for ( const CUnit& unit : m_allUnits )
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
        if ( unit.getID() == unitID )
 | 
					        if ( pair.unit.getID() == unitID )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			unitFound = true;
 | 
					            ret = 0;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// for now, as long as the unit exists we can attempt the order
 | 
						// for now, as long as the unit exists we can attempt the order
 | 
				
			||||||
	return unitFound;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
// Get unit by unit ID
 | 
					// Get unit by unit ID
 | 
				
			||||||
const CUnit& CTTRTSGame::GetUnitByID( unit_id_t id ) const
 | 
					const CUnit& CTTRTSGame::GetUnitByIDConst( unit_id_t id ) const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    CUnitVector::const_iterator it;
 | 
					    CUnitVector::iterator it;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for ( const CUnit& unit : m_allUnits )
 | 
					    for ( const OrderUnitPair& pair : m_OrderUnitPairs )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // Attempt the unit add
 | 
					        // Attempt the unit add
 | 
				
			||||||
        if ( unit.getID()  )
 | 
					        if ( pair.unit.getID()  )
 | 
				
			||||||
            return unit;
 | 
					            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 )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    CUnitVector::iterator it;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for ( OrderUnitPair& pair : m_OrderUnitPairs )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // Attempt the unit add
 | 
				
			||||||
 | 
					        if ( pair.unit.getID()  )
 | 
				
			||||||
 | 
					            return pair.unit;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Return an invalid unit
 | 
					    // Return an invalid unit
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										55
									
								
								game/game.h
									
										
									
									
									
								
							
							
						
						
									
										55
									
								
								game/game.h
									
										
									
									
									
								
							| 
						 | 
					@ -12,8 +12,27 @@ typedef std::vector< CUnit > CUnitVector;
 | 
				
			||||||
// Type for order and unit pairs
 | 
					// Type for order and unit pairs
 | 
				
			||||||
struct OrderUnitPair
 | 
					struct OrderUnitPair
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    const COrder& order;
 | 
					    // Straight up move constructor
 | 
				
			||||||
    const CUnit& unit;
 | 
					    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 asignment operator
 | 
				
			||||||
 | 
					    inline OrderUnitPair& operator=( OrderUnitPair&& rhs ) { *this = std::move(rhs); return *this; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CUnit unit;
 | 
				
			||||||
 | 
					    COrder order;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef std::vector< OrderUnitPair > OrderUnitPairVector;
 | 
					typedef std::vector< OrderUnitPair > OrderUnitPairVector;
 | 
				
			||||||
| 
						 | 
					@ -48,36 +67,42 @@ public:
 | 
				
			||||||
	int AddUnits( CUnitVector&& units );
 | 
						int AddUnits( CUnitVector&& units );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Get the number of units
 | 
						// Get the number of units
 | 
				
			||||||
	inline unsigned int GetNumUnits() const { return m_allUnits.size(); }
 | 
					    inline unsigned int GetNumUnits() const { return m_OrderUnitPairs.size(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Get unit by index as above (not unit ID)
 | 
						// Get unit by index as above (not unit ID)
 | 
				
			||||||
	inline const CUnit& GetUnitByIndex( unsigned int i ) const { return m_allUnits[i]; }
 | 
					    inline const CUnit& GetUnitByIndex( unsigned int i ) const { return m_OrderUnitPairs[i].unit; }
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
    // Get unit by unit ID
 | 
					    // Get unit by unit ID
 | 
				
			||||||
    const CUnit& GetUnitByID( unit_id_t id ) const;
 | 
					    const CUnit& GetUnitByIDConst( unit_id_t id ) const;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Get the number of order
 | 
					 | 
				
			||||||
	inline unsigned int GetNumOrders() const { return m_orders.size(); }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Get orders by index as above 
 | 
						// Get orders by index as above 
 | 
				
			||||||
	inline const COrder& GetOrdersByIndex( unsigned int i ) const { return m_orders[i]; }
 | 
					    inline const COrder& GetOrdersByIndex( unsigned int i ) const { return m_OrderUnitPairs[i].order; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Get dimentions
 | 
						// Get dimentions
 | 
				
			||||||
    inline const uvector2& GetDimentions() const { return dimentions; }
 | 
					    inline const uvector2& GetDimentions() const { return dimentions; }
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Verify any order
 | 
					    // Verify any order - non-zero is error
 | 
				
			||||||
    int VerifyOrder( player_id_t player, const COrder& order ) const;
 | 
					    int VerifyOrder( player_id_t player, const COrder& order ) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Verify any order
 | 
					    // Verify any order - non-zero is error
 | 
				
			||||||
    int VerifyUnit(  const CUnit& unit ) const;
 | 
					    int VerifyUnit(  const CUnit& unit ) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Vector to store points to all units
 | 
					    // Verify Position - non-zero is error
 | 
				
			||||||
	CUnitVector 		m_allUnits;
 | 
					    int VerifyPos( uvector2 vec ) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Orders to execute this turn
 | 
					    // Get a units new position after an order
 | 
				
			||||||
	COrderVector 		m_orders;
 | 
					    uvector2 GetNewPosition( const OrderUnitPair& pair ) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Get unit by unit ID
 | 
				
			||||||
 | 
					    CUnit& GetUnitByID( unit_id_t id );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Vector to store points to all units
 | 
				
			||||||
 | 
					    OrderUnitPairVector 		m_OrderUnitPairs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // List of dead units
 | 
				
			||||||
 | 
					    CUnitVector                 m_deadUnits;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Dimensions of the game
 | 
						// Dimensions of the game
 | 
				
			||||||
	uvector2 dimentions;
 | 
						uvector2 dimentions;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,7 +14,8 @@ enum class order_c : char
 | 
				
			||||||
    F = 'F',
 | 
					    F = 'F',
 | 
				
			||||||
    L = 'L',
 | 
					    L = 'L',
 | 
				
			||||||
    R = 'R',
 | 
					    R = 'R',
 | 
				
			||||||
    A = 'A'
 | 
					    A = 'A',
 | 
				
			||||||
 | 
					    INVALID
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Movement orders
 | 
					// Movement orders
 | 
				
			||||||
| 
						 | 
					@ -34,6 +35,13 @@ static const order_c sk_actionOrders[] =
 | 
				
			||||||
// Container for an order
 | 
					// Container for an order
 | 
				
			||||||
struct COrder
 | 
					struct COrder
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    COrder()
 | 
				
			||||||
 | 
					        : unit ( unit_id_invalid )
 | 
				
			||||||
 | 
					        , order ( order_c::INVALID )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Unit order is for
 | 
						// Unit order is for
 | 
				
			||||||
	unit_id_t unit;
 | 
						unit_id_t unit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,6 +36,7 @@ CUnit::CUnit()
 | 
				
			||||||
, player_id ( player_id_invalid )
 | 
					, player_id ( player_id_invalid )
 | 
				
			||||||
, unit_vis 	( unitVis_invalid )
 | 
					, unit_vis 	( unitVis_invalid )
 | 
				
			||||||
, dir 		( dir_t::S )
 | 
					, dir 		( dir_t::S )
 | 
				
			||||||
 | 
					, pos 		( { ucoord_invalid, ucoord_invalid } )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	updateMyVisual();
 | 
						updateMyVisual();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -47,6 +48,7 @@ CUnit::CUnit(CUnit&& unit)
 | 
				
			||||||
, player_id ( std::move(unit.player_id) )
 | 
					, player_id ( std::move(unit.player_id) )
 | 
				
			||||||
, unit_vis 	( std::move(unit.unit_vis) )
 | 
					, unit_vis 	( std::move(unit.unit_vis) )
 | 
				
			||||||
, dir 		( std::move(unit.dir) )
 | 
					, dir 		( std::move(unit.dir) )
 | 
				
			||||||
 | 
					, pos 		( std::move(unit.pos) )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	updateMyVisual();
 | 
						updateMyVisual();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -81,7 +83,7 @@ bool CUnit::setFromVisual( const unitVis_c& vis )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if( it->second == vis )
 | 
							if( it->second == vis )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			dir == it->first;
 | 
					            dir = it->first;
 | 
				
			||||||
			updateMyVisual();
 | 
								updateMyVisual();
 | 
				
			||||||
			return true;
 | 
								return true;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -90,3 +92,91 @@ bool CUnit::setFromVisual( const unitVis_c& vis )
 | 
				
			||||||
	// No matching direction to visual
 | 
						// No matching direction to visual
 | 
				
			||||||
	return false;
 | 
						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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										18
									
								
								game/unit.h
									
										
									
									
									
								
							
							
						
						
									
										18
									
								
								game/unit.h
									
										
									
									
									
								
							| 
						 | 
					@ -13,22 +13,28 @@ class CUnit
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	CUnit();
 | 
						CUnit();
 | 
				
			||||||
	CUnit(CUnit&& unit);
 | 
					    CUnit(CUnit&& unit);
 | 
				
			||||||
 | 
					    CUnit& operator=(CUnit&& unit) { *this = std::move(unit); return *this; }
 | 
				
			||||||
	~CUnit() = default;
 | 
						~CUnit() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline const unit_id_t& 	getID() const 		{ return unit_id; }
 | 
						inline const unit_id_t& 	getID() const 		{ return unit_id; }
 | 
				
			||||||
	inline const team_id_t& 	getTeam() const 	{ return team_id; }
 | 
						inline const team_id_t& 	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; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Return non-zero values on error
 | 
						// Return non-zero values on error
 | 
				
			||||||
	inline int 	setTeam(const team_id_t& v)  		{ return (v == team_id_invalid) ? 	-1 : (( team_id = v ), 0); }
 | 
					    inline int 	 setTeam(const team_id_t& v)  		{ return (v == team_id_invalid) ? 	-1 : (( team_id = v ), 0); }
 | 
				
			||||||
	inline int 	setPlayer(const player_id_t& v)  	{ return (v == player_id_invalid) ? -1 : (( player_id = v ), 0); }
 | 
					    inline int 	 setPlayer(const player_id_t& v)  	{ return (v == player_id_invalid) ? -1 : (( player_id = v ), 0); }
 | 
				
			||||||
	inline int	setVisual(const unitVis_c& v)  		{ return (v == unitVis_invalid) ? 	-1 : (( unit_vis = v ), 0); }
 | 
					    inline int	 setVisual(const unitVis_c& v)  	{ return (v == unitVis_invalid) ? 	-1 : (( unit_vis = v ), 0); }
 | 
				
			||||||
 | 
					    inline dir_t setDir(const dir_t& v)             { return (dir = v); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	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; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Get the co-ordinate infront of the unit
 | 
				
			||||||
 | 
					    uvector2 getInFront() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Check unit is valid
 | 
						// Check unit is valid
 | 
				
			||||||
	inline bool valid() const;
 | 
						inline bool valid() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,6 +44,10 @@ public:
 | 
				
			||||||
	// Factory function for creating units from a visual
 | 
						// Factory function for creating units from a visual
 | 
				
			||||||
    static CUnit getUnitFromVis( unitVis_c vis );
 | 
					    static CUnit getUnitFromVis( unitVis_c vis );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dir_t turnLeft();
 | 
				
			||||||
 | 
					    dir_t turnRight();
 | 
				
			||||||
 | 
					    dir_t turnAround();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,16 +3,73 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "mathtypes.h"
 | 
					#include "mathtypes.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct uvector2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct vector2
 | 
					struct vector2
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	coord_t x;
 | 
						coord_t x;
 | 
				
			||||||
	coord_t y;
 | 
						coord_t y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inline vector2 operator-() const { return { (coord_t)-x, (coord_t)-y }; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inline operator uvector2() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // vec
 | 
				
			||||||
 | 
					    inline vector2 operator+(const vector2& rhs) const { return { (coord_t)(rhs.x + x) , (coord_t)(rhs.y + y) }; }
 | 
				
			||||||
 | 
					    inline vector2 operator-(const vector2& rhs) const { return *this + (-rhs); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inline const vector2& operator+=(const vector2& rhs) { *this = *this+rhs; return *this; }
 | 
				
			||||||
 | 
					    inline const vector2& operator-=(const vector2& rhs) { return *this+=(-rhs); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inline bool operator==(const vector2& rhs) const { return ( rhs.x == x) && ( rhs.y == y); }
 | 
				
			||||||
 | 
					    inline bool operator!=(const vector2& rhs) const { return !(*this==rhs); }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct uvector2
 | 
					struct uvector2
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	ucoord_t x;
 | 
						ucoord_t x;
 | 
				
			||||||
	ucoord_t y;
 | 
						ucoord_t y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Implicit conversion to vector 2 if needed
 | 
				
			||||||
 | 
					    inline operator vector2() const { return { (coord_t)x, (coord_t)y }; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inline uvector2 operator-() const { return { (ucoord_t)-x, (ucoord_t)-y }; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // uvec
 | 
				
			||||||
 | 
					    inline uvector2 operator+(const uvector2& rhs) const { return { (ucoord_t)(rhs.x + x) , (ucoord_t)(rhs.y + y) }; }
 | 
				
			||||||
 | 
					    inline uvector2 operator-(const uvector2& rhs) const { return *this + (-rhs); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inline const uvector2& operator+=(const uvector2& rhs) { *this = *this+rhs; return *this; }
 | 
				
			||||||
 | 
					    inline const uvector2& operator-=(const uvector2& rhs) { return *this+=(-rhs); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inline bool operator==(const uvector2& rhs) const { return ( rhs.x == x) && ( rhs.y == y); }
 | 
				
			||||||
 | 
					    inline bool operator!=(const uvector2& rhs) const { return !(*this==rhs); }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif //_VECTOR2_H_
 | 
					inline vector2::operator uvector2() const { return { (ucoord_t)x, (ucoord_t)y }; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline vector2 vecFromDir( dir_t dir )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    switch( dir )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    case dir_t::N:
 | 
				
			||||||
 | 
					        return { 0,1 };
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case dir_t::E:
 | 
				
			||||||
 | 
					        return { 1,0 };
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case dir_t::S:
 | 
				
			||||||
 | 
					        return { 0,-1 };
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case dir_t::W:
 | 
				
			||||||
 | 
					        return { -1,0 };
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return { 0,0 };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif //_VECTOR2_H_
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -68,13 +68,34 @@ const char* tests()
 | 
				
			||||||
		if( game.SimulateToNextTurn() )
 | 
							if( game.SimulateToNextTurn() )
 | 
				
			||||||
			return "Failed to simulate a blank game";
 | 
								return "Failed to simulate a blank game";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if( game.GetNumOrders() )
 | 
					        if( game.GetNumUnits() )
 | 
				
			||||||
			return "Game started with non-zero order number";
 | 
					            return "Game started with non-zero unit number";
 | 
				
			||||||
 | 
					 | 
				
			||||||
		if( game.GetNumUnits() )
 | 
					 | 
				
			||||||
			return "Game started with non-zero unit number";
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        CTTRTSGame game( 5, 5 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        CUnit unit = CUnit::getUnitFromVis('>');
 | 
				
			||||||
 | 
					        const unit_id_t id = unit.getID();
 | 
				
			||||||
 | 
					        COrder order;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        unit.setPos( {2,2} );
 | 
				
			||||||
 | 
					        unit.setPlayer(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        game.AddUnit(std::move(unit));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        order.unit = id;
 | 
				
			||||||
 | 
					        order.order = order_c::F;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        game.IssueOrder(0,order);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        game.SimulateToNextTurn();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if( game.GetUnitByIDConst(id).getPos() != uvector2{3,2} )
 | 
				
			||||||
 | 
					            return "Simple movement order failed";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nullptr;
 | 
						return nullptr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue