Implement invalid unit positions
This commit is contained in:
		
							parent
							
								
									c98ac95759
								
							
						
					
					
						commit
						d172922698
					
				
					 4 changed files with 122 additions and 16 deletions
				
			
		|  | @ -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<uvector2> 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
 | ||||
| } | ||||
|  | @ -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<player_t>   GetPlayers() const; | ||||
| 
 | ||||
|     // Get the vector of current invalid positions
 | ||||
|     inline std::vector<uvector2>    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<uvector2>   m_InvalidPositions; // Vector of invalidated positions
 | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,6 +3,13 @@ | |||
| 
 | ||||
| #include <limits>       // 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 | ||||
| { | ||||
|  |  | |||
|  | @ -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(); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue