示例#1
0
//----------------------------------------------------------------------
bool ArenaMap::searchHalfCircleUsingManhattenDistForNutrient( const TileCoords& pos, const TileCoords& dir, int radius, TileCoords& nutrientLoc ) const
{
	TileCoords currentPos = pos;
	int currRadius = radius;
	bool found = false;
	for( int i = 0; i < radius && !found; ++i )
	{
		found = searchInDirectionForNutrient( currentPos, TileCoords( 1, 0 ), currRadius, nutrientLoc );
		if( !found )
			found = searchInDirectionForNutrient( currentPos, TileCoords( -1, 0 ), currRadius, nutrientLoc );
		currentPos += dir;
		--currRadius;
	}
	return found;
}
示例#2
0
//----------------------------------------------------------------------
bool AIController::getEntityIDForClosestEnemyQueen( const TileCoords& pos, const ObservedEntities& entities, int& closestQueenID ) const
{
	int visibleQueenIndices[8] = { -1, -1, -1, -1, -1, -1 };
	int queenIndex = 0;
	for( int i = 0; i < entities.m_numberOfObservedEntities; ++i )
	{
		if( entities.m_entities[i].m_agentType == ENTITY_TYPE_QUEEN && queenIndex < 8 )
			visibleQueenIndices[ queenIndex++ ] = i;
	}
	TileCoords closestQueenTC(  -1, -1 );
	float closestDeltaSqrd = (float)m_arenaInfo.width;
	int closestQueenIndex = -1;
	for( int q = 0; q < queenIndex; ++q )
	{
		if( visibleQueenIndices[q] != -1 )
		{
			TileCoords nextQueenLoc = TileCoords( entities.m_entities[ visibleQueenIndices[q] ].m_positionX, entities.m_entities[ visibleQueenIndices[q] ].m_positionY );
			float deltaSqrd = ( nextQueenLoc - pos ).lengthSqrd();
			if( deltaSqrd < closestDeltaSqrd )
			{
				closestQueenTC = nextQueenLoc;
				closestDeltaSqrd = deltaSqrd;
				closestQueenIndex = visibleQueenIndices[q];
			}
		}
	}
	if( closestQueenIndex != -1 )
		closestQueenID = entities.m_entities[ closestQueenIndex ].m_entityID;
	else
		closestQueenID = -1;
	return closestQueenIndex != -1;
}
示例#3
0
TheGame::TheGame()
: m_map(nullptr)
, m_isPaused(false)
, m_pauseTexture(Texture::CreateOrGetTexture("Data/Images/Pause.png"))
{
	srand(0xDEADBEEF);
	m_map = new Map( TileCoords( 40, 40 ) );
}
示例#4
0
//----------------------------------------------------------------------
TileCoords AIController::getLocationForQueenToGoTo( const ArenaMap& currentMap )
{
	static OrderCode orderCodeToStartWith = ORDER_MOVE_NORTH;
	TileCoords newQueenLoc = m_queen->pos;
	if( m_currentNumWorkers <= 0 )
	{
		OrderCode dirCode = orderCodeToStartWith;
		float lowestGCost = 100.0f;
		for( int i = 0; i < 4; ++i )
		{
			dirCode = (OrderCode)Monky::MathFuncs<int>::wrap( orderCodeToStartWith + i, ORDER_MOVE_EAST, ORDER_MOVE_SOUTH ); 
			TileCoords newDir = AStarPathGenerator::getTileCoordsDirFromOrderCode( dirCode );
			TileCoords tempNewQueenLoc;
			newDir = newDir * (float)m_arenaInfo.visibilityRangeQueen;
			tempNewQueenLoc = m_queen->pos + newDir;
			float gCostToEnterTile = currentMap.getGCostToEnterTile( ENTITY_TYPE_QUEEN, tempNewQueenLoc.x, tempNewQueenLoc.y );
			if( currentMap.isInMap( tempNewQueenLoc.x, tempNewQueenLoc.y ) && currentMap.canMoveOnTile( tempNewQueenLoc.x, tempNewQueenLoc.y ) && gCostToEnterTile < lowestGCost )
			{
				newQueenLoc = tempNewQueenLoc;
				lowestGCost = gCostToEnterTile;
			}
		}
	
		int x, y;
		if( currentMap.getClosestNutrient( m_arenaInfo.visibilityRangeQueen * QUEEN_RANGE_FACTOR, newQueenLoc, x, y ) )
			newQueenLoc = TileCoords( x, y );

	
		orderCodeToStartWith = dirCode;
	}
	else
	{
		int x, y;
		if( currentMap.getClosestNutrient( m_arenaInfo.visibilityRangeQueen * QUEEN_RANGE_FACTOR, m_queen->pos, x, y ) )
			newQueenLoc = TileCoords( x, y );
	}

	if( newQueenLoc == m_queen->pos )
		newQueenLoc = currentMap.getRandomLocationInArea( m_queen->pos, (int)( m_arenaInfo.width*0.1 ) );
	
	return newQueenLoc;
}
示例#5
0
//------------------------------------------------------------
void ArenaMap::updateEnemySightingsHeatMap( const ObservedEntities& entities )
{
	for( int i = 0; i < entities.m_numberOfObservedEntities; ++i )
	{
		TileCoords entityLoc = TileCoords( entities.m_entities[i].m_positionX, entities.m_entities[i].m_positionY );
		MapTile& tile = getMapTile( entityLoc.x, entityLoc.y );
		++tile.enemyAgentsSeenInThisTile;
		if( tile.enemyAgentsSeenInThisTile > m_maxEnemySeenCountInSingleTile )
			m_maxEnemySeenCountInSingleTile = tile.enemyAgentsSeenInThisTile;
	}
}
示例#6
0
//----------------------------------------------------------------------
TileCoords ArenaMap::getRandomLocationInArea( const TileCoords& pos, int radius ) const
{
	TileCoords minXY( pos.x - radius, pos.y - radius );
	TileCoords maxXY( pos.x + radius, pos.y + radius );
	minXY.x = Monky::MathFuncs<int>::clamp( minXY.x, 0, m_arenaInfo.width - 1 );
	minXY.y = Monky::MathFuncs<int>::clamp( minXY.y, 0, m_arenaInfo.height - 1 );
	maxXY.x = Monky::MathFuncs<int>::clamp( maxXY.x, 0, m_arenaInfo.width - 1 );
	maxXY.y = Monky::MathFuncs<int>::clamp( maxXY.y, 0, m_arenaInfo.height - 1 );

	return TileCoords( Monky::RandNumGen::randInRangeInt( minXY.x, maxXY.x ), Monky::RandNumGen::randInRangeInt( minXY.y, maxXY.y ) ); 
	
}
示例#7
0
//------------------------------------------------------------
bool ArenaMap::getClosestNutrient( int startingRadius, const TileCoords& current, int& nutrientX, int& nutrientY ) const
{
	bool found = false;
	TileCoords nutrientLoc( -1, -1 );
	found = searchInDirectionForNutrient( current, TileCoords( 1, 0 ), startingRadius, nutrientLoc );

	if( !found )	
		found = searchInDirectionForNutrient( current, TileCoords( -1, 0 ), startingRadius, nutrientLoc );

	TileCoords hCircleDir = TileCoords( 0, 1 );
	--startingRadius;
	if( !found )
		found = searchHalfCircleUsingManhattenDistForNutrient( current + hCircleDir, hCircleDir, startingRadius, nutrientLoc );
			
	if( !found )
		found = searchHalfCircleUsingManhattenDistForNutrient( current - hCircleDir, -hCircleDir, startingRadius, nutrientLoc );

	nutrientX = nutrientLoc.x;
	nutrientY = nutrientLoc.y;

	return found;
}
示例#8
0
//----------------------------------------------------------------------
TileCoords AIController::getTileCoordsForEnemyAgent( int agentID, const ObservedEntities& entities ) const
{
	TileCoords agentLoc( -1, -1 );
	for( int i = 0; i < entities.m_numberOfObservedEntities; ++i )
	{
		if( entities.m_entities[i].m_entityID == agentID )
		{
			agentLoc = TileCoords( entities.m_entities[i].m_positionX, entities.m_entities[i].m_positionY );
			break;
		}
	}
	return agentLoc;
}
示例#9
0
//------------------------------------------------------------
void ArenaMap::init()
{
	m_currentTurn = 0;
	for( int  y = 0; y < m_height; ++y )
	{
		for( int x = 0; x < m_width; ++x )
		{
			int index = x + ( y * m_width );
			if( index >= 0 && index < ( m_width * m_height ) )
			{
				m_mapTiles[ index ].tileMaterial = (char)ARENA_SQUARE_TYPE_UNKNOWN;
				m_tilesToScout.addItem( TileCoords( x, y ) );
			}
		}
	}
}
示例#10
0
//------------------------------------------------------------
void ArenaMap::updateMap( const ArenaSquares& currentViewOfArena, int currentTurn )
{
	m_width = currentViewOfArena.m_width;
	m_height = currentViewOfArena.m_height;
	
	m_hasNewMapInfo = false;
	m_hasNoMoreResources = true;
	m_currentTurn = currentTurn;
	m_tilesToScout.clearPool();
	for( int  y = 0; y < m_height; ++y )
	{
		for( int x = 0; x < m_width; ++x )
		{
			int index = x + ( y * m_width );
			if( index >= 0 && index < ( m_width * m_height ) )
			{
				if( currentViewOfArena.m_arenaSquareMaterials[ index ] != ARENA_SQUARE_TYPE_UNKNOWN )
				{
					if( m_mapTiles[ index ].tileMaterial != (char)ARENA_SQUARE_TYPE_STONE )
					{
						if( currentViewOfArena.m_arenaSquareMaterials[ index ] == ARENA_SQUARE_TYPE_STONE )
							m_hasNewMapInfo = true;	
						if( m_mapTiles[ index ].tileMaterial == ARENA_SQUARE_TYPE_FOOD || currentViewOfArena.m_arenaSquareMaterials[ index ]  == ARENA_SQUARE_TYPE_FOOD )
							m_hasNoMoreResources = false;
							
						m_mapTiles[ index ].isClaimed = false;

						m_mapTiles[ index ].tileMaterial = (char)currentViewOfArena.m_arenaSquareMaterials[ index ];
						m_mapTiles[ index ].gCostToEnterTileForQueen = getGCostToEnterTileForEntityType( (ArenaSquareType)m_mapTiles[ index ].tileMaterial, ENTITY_TYPE_QUEEN );
						m_mapTiles[ index ].gCostToEnterTileForScout = getGCostToEnterTileForEntityType( (ArenaSquareType)m_mapTiles[ index ].tileMaterial, ENTITY_TYPE_SCOUT );
						m_mapTiles[ index ].gCostToEnterTileForSoldier = getGCostToEnterTileForEntityType( (ArenaSquareType)m_mapTiles[ index ].tileMaterial, ENTITY_TYPE_SOLDIER );
						m_mapTiles[ index ].gCostToEnterTileForWorker = getGCostToEnterTileForEntityType( (ArenaSquareType)m_mapTiles[ index ].tileMaterial, ENTITY_TYPE_WORKER );
					}
					m_mapTiles[ index ].lastTurnUpdated = m_currentTurn;
				}
				else if( m_currentTurn - m_mapTiles[ index ].lastTurnUpdated > TOLERANCE_FOR_TILE_FRESHNESS )
					m_tilesToScout.addItem( TileCoords( x, y ) );
			}
		}
	}
}
示例#11
0
//----------------------------------------------------------------------
void AIController::handleWorkerOrders( Agent* worker, ArenaMap& currentMap, const ObservedEntities& entities, Orders& tentativeOrders )
{
	if( m_currentQueenState == ATTACK && currentMap.hasNoMoreResources() && worker->specialStatus != ENTITY_SPECIAL_STATUS_CARRYING_FOOD )
	{
		tentativeOrders.AddOrder( worker->entityID, ORDER_SUICIDE );
	}
	else
	{
		if( worker->currentPath.empty() && !worker->waitingForPath )
		{
			if( worker->pos == m_queen->pos && worker->specialStatus == ENTITY_SPECIAL_STATUS_CARRYING_FOOD )
			{
				tentativeOrders.AddOrder( worker->entityID, ORDER_DROP_FOOD, true );
				--m_numWorkersWithFood;
				worker->currentTargetAgentID = -1;
			}
			else if( worker->pos == worker->currentTargetLoc && currentMap.getMapTileType( worker->pos.x, worker->pos.y ) == ARENA_SQUARE_TYPE_FOOD )
			{
				tentativeOrders.AddOrder( worker->entityID, ORDER_TAKE_FOOD, true );
				m_agentsRequestingPaths.push( worker->entityID );
				worker->currentTargetLoc = m_queen->pos;
				worker->currentTargetAgentID = m_queen->entityID;
				worker->waitingForPath = true;
				currentMap.getMapTile( worker->pos.x, worker->pos.y ).isClaimed = false;
			}	
			else if( worker->specialStatus != ENTITY_SPECIAL_STATUS_CARRYING_FOOD )
			{
				int x, y;
				if( currentMap.getClosestNutrient( m_arenaInfo.visibilityRangeQueen*QUEEN_RANGE_FACTOR, m_queen->pos, x, y ) )
				{
					m_agentsRequestingPaths.push( worker->entityID );
					worker->currentTargetLoc = TileCoords( x, y );
					worker->currentTargetAgentID = -1;
					worker->waitingForPath = true;
					currentMap.getMapTile( x, y ).isClaimed = true;
				}
				else
				{
					++m_numWorkersThatCouldntFindFoodThisFrame;
					if( m_numWorkersThatCouldntFindFoodThisFrame >= NUM_WORKERS_IDLE_BEFORE_QUEEN_MOVES )
					{
						worker->currentTargetAgentID = m_queen->entityID;
					}
					else
					{
						worker->currentTargetAgentID = -1;
						worker->currentTargetLoc = currentMap.getRandomLocationInArea( worker->pos, m_arenaInfo.visibilityRangeQueen*QUEEN_RANGE_FACTOR );
					}
					m_agentsRequestingPaths.push( worker->entityID );
					worker->waitingForPath = true;
				}
			}
			else
			{
				worker->currentTargetAgentID =  m_queen->entityID;
				m_agentsRequestingPaths.push( worker->entityID );
				worker->waitingForPath = true;
			}
		}
		else if( currentMap.getMapTileType( worker->currentTargetLoc.x, worker->currentTargetLoc.y ) != ARENA_SQUARE_TYPE_FOOD && worker->specialStatus != ENTITY_SPECIAL_STATUS_CARRYING_FOOD )
		{
			int x, y;
			if( currentMap.getClosestNutrient( m_arenaInfo.visibilityRangeQueen*QUEEN_RANGE_FACTOR, m_queen->pos, x, y ) )
			{
				m_agentsRequestingPaths.push( worker->entityID );
				worker->currentTargetLoc = TileCoords( x, y );
				worker->currentTargetAgentID = -1;
				worker->waitingForPath = true;
				currentMap.getMapTile( x, y ).isClaimed = true;
			}
		}
		else if( currentMap.hasNewMapInfo() && !worker->waitingForPath && !validPath( currentMap, worker->pos, worker->currentPath ) )
		{
			m_agentsRequestingPaths.push( worker->entityID );
			worker->waitingForPath = true;
		}
	}
}