Exemplo n.º 1
0
DWORD CTeleportPath::FindTeleportPath(POINT ptStart, POINT ptEnd, LPPOINT lpBuffer, DWORD dwMaxCount)
{
	if (lpBuffer == NULL || dwMaxCount == 0 || m_nCX <= 0 || m_nCY <= 0 || m_ppTable == NULL)
		return 0;
	
	memset(lpBuffer, 0, sizeof(POINT) * dwMaxCount);
	m_ptStart = ptStart;
	m_ptEnd = ptEnd;

	//GameInfof("start %d %d End %d %d", ptStart.x, ptStart.y, ptEnd.x, ptEnd.y);

	MakeDistanceTable();
	 
	lpBuffer[0] = ptStart; // start point
	DWORD dwFound = 0;

	POINT pos = ptStart;

	BOOL bOK = FALSE;
	int nRes = GetBestMove(pos);
	while (nRes != PATH_FAIL && dwFound < dwMaxCount)
	{
		// Reached?
		if (nRes == PATH_REACHED)
		{
			bOK = TRUE;
			lpBuffer[dwFound] = ptEnd;
			dwFound++;
			break; // Finished
		}

		// Perform a redundancy check
		int nRedundancy = GetRedundancy(lpBuffer, dwFound, pos);
		if (nRedundancy == -1)
		{
			// no redundancy
			lpBuffer[dwFound] = pos;
			dwFound++;
		}
		else
		{
			// redundancy found, discard all redundant steps
			dwFound = nRedundancy + 1;
			lpBuffer[dwFound] = pos;
		}	

		nRes = GetBestMove(pos);
	}	

	if (!bOK)
		dwFound = 0;

	return dwFound;
}
Exemplo n.º 2
0
void AI_DoMove(tMove *MyMove)
{
#if 1
	// Sanity checks
	for( int i = 0; i < N_PIECES; i ++ )
	{
		tPiece	*p = &gpCurrentGameState->MyActual.Pieces[i];
		if(p->bDead)	continue;

		if( p != GetPieceByPos(p->X, p->Y) ) {
			DEBUG("Piece %p(%i,%i R%i) not at stated position",
				p, p->X, p->Y, p->Rank);
		}
	}
#endif

	DEBUG("Deciding on move");
	GetBestMove(&gpCurrentGameState->MyActual, &gpCurrentGameState->Opponent, MyMove, 0);
}
ab::Acceleration ab::PredictiveStrategy::GetTurn(const ab::FieldState& state,
                                                 const ab::PlayerId player_id)
{
    size_t players_number = state.players.size();
    std::vector<BestMoveToCoin> best_moves;

    for (size_t player_index = 0; player_index < players_number; ++player_index)
        best_moves.push_back(GetBestMove(state, player_index));

    int aim_coin = best_moves[player_id].coin_id;
    if (-1 == aim_coin) {
        return MoveToClosestCoin(state, player_id);
    }

    double best_time_to_coin = best_moves[player_id].best_time;
    for (size_t player_index = 0; player_index < players_number; ++player_index) {
        if (best_moves[player_index].coin_id == aim_coin &&
            best_moves[player_index].best_time < best_time_to_coin)
        {
            return MoveToClosestCoin(state, player_id);
        }
    }
    return best_moves[player_id].best_acceleration;
}
Exemplo n.º 4
0
//******************************************************************************************
void CRoachQueen::GetBrainDirectedMovement(
// Special-cased for roach queens.
//
//Params:
	int &dxFirst,	//(out) Horizontal delta for where the monster would
					//		go if there weren't obstacles.
	int &dyFirst,	//(out) Vertical delta for same.
	int &dx,		//(out) Horizontal delta (-1, 0, or 1) for where monster
					//		can go, taking into account obstacles.
	int &dy)		//(out) Vertical delta (-1, 0, or 1) for same.
const
{
	SQUARE square;
	this->pCurrentGame->pRoom->pPathMap[this->eMovement]->GetSquare(this->wX,
			this->wY, square);
	if (square.eState == ok && square.eDirection != none)
	{
		//Run away from swordsman, based on the direction of the pathmap.
		dx = -nGetOX(square.eDirection);
		dy = -nGetOY(square.eDirection);
		//Try to move diagonally toward middle of the room on non-primary axis.
		if (dx == 0)
			dx = (wX < (this->pCurrentGame->pRoom->wRoomCols / 2)) 
				 ? 1: -1;
		else if (dy == 0)
			dy = (wY < (this->pCurrentGame->pRoom->wRoomRows / 2))
				 ? 1: -1;
		dxFirst = dx;
		dyFirst = dy;
	} else {
		//With a brain, even invisible swordsman is sensed.
		dx = dxFirst = -sgn(this->pCurrentGame->swordsman.wX - this->wX);
		dy = dyFirst = -sgn(this->pCurrentGame->swordsman.wY - this->wY);
	}
	GetBestMove(dx, dy);
}
Exemplo n.º 5
0
//*****************************************************************************************
void CRoachQueen::Process(
//Process a roach queen for movement.
//
//Params:
	const int nLastCommand,	//(in) Last swordsman command.
	CCueEvents &CueEvents)	//(in/out) Accepts pointer to an IDList object that will be populated
							//with codes indicating events that happened that may correspond to
							//sound or graphical effects.
{
	//Get movement offsets.
	int dxFirst, dyFirst, dx, dy;
	if (this->pCurrentGame->pRoom->IsBrainPresent())
		GetBrainDirectedMovement(dxFirst, dyFirst, dx, dy);
	else
	{
		if (CanFindSwordsman())
		{
			// Run away!
			dx = dxFirst = -sgn(this->pCurrentGame->swordsman.wX - this->wX);
			dy = dyFirst = -sgn(this->pCurrentGame->swordsman.wY - this->wY);
			GetBestMove(dx, dy);
		}
		else return;	//no change -- and don't lay eggs
	}

	// Save previous location
	const UINT oX = this->wX;
	const UINT oY = this->wY;

	//Move roach queen to new destination square.
	MakeStandardMove(CueEvents,dx,dy);
	SetOrientation(dxFirst, dyFirst);
		
	//Shall we lay some eggs?
	//The criteria for laying an egg in a square should be:
	//1. Square does not contain a monster (including mimic).
	//2. Square does not contain a swordsman or sword.
	//3. Square does not contain a mimic sword.
	//4. T-square is T_EMPTY.
	//5. O-square is T_FLOOR.
	if ((this->pCurrentGame->wSpawnCycleCount % TURNS_PER_CYCLE == 0) &&
		CanFindSwordsman())
	{
		for (int y = -1; y <= 1; y++)
		{
			for (int x = -1; x <= 1; x++)
			{
				const UINT ex = this->wX + x;
				const UINT ey = this->wY + y;
				if (//Valid
					this->pCurrentGame->pRoom->IsValidColRow(ex, ey) &&
					// Not current queen position
					!(ex == this->wX && ey == this->wY) &&
					// Not old queen position (compat)
					!(ex == oX && ey == oY) &&
					// Not swordsman
					!(ex == this->pCurrentGame->swordsman.wX && 
					  ey == this->pCurrentGame->swordsman.wY) &&
					// Not monster or mimic or sword
					!DoesSquareContainObstacle(ex, ey) &&
					//And t-square is empty (compat).
					this->pCurrentGame->pRoom->GetTSquare(ex, ey) == T_EMPTY &&
					 //And o-square is floor (compat).                                   
					this->pCurrentGame->pRoom->GetOSquare(ex, ey) == T_FLOOR		
					)
				{
					// Place an egg
					CMonster *m = this->pCurrentGame->pRoom->AddNewMonster(M_REGG,
							ex,ey);
					m->SetCurrentGame(this->pCurrentGame);
					m->bIsFirstTurn = true;
				}
			}
		}
	}
}
Exemplo n.º 6
0
BYTE CPathFinder::CalculatePathTo(WORD x, WORD y, LPPATH lpBuffer, int nAdjust)
{
	if (lpBuffer == NULL || x == 0 || y == 0 || !VerifyMemory())
		return 0;

	memset(lpBuffer, 0, sizeof(PATH));
	lpBuffer->posStart = GetPosition();
	if (lpBuffer->posStart.x == 0 || lpBuffer->posStart.y == 0)
		return 0;
	
	if (!Search())
		return 0;

	//GameInfof("Mapsize %d, %d", m_rightBottom.x - m_lefttTop.x, m_rightBottom.y - m_lefttTop.y);

	m_ptAbsDest.x = x;
	m_ptAbsDest.y = y;

	m_ptRelDest = m_ptAbsDest;
	MapToGraph(m_ptRelDest);

	//GameInfof("des %d, %d", m_ptRelDest.x, m_ptRelDest.y);

	// verify destination, see if it's in our map
	if (!IsValidPos(m_ptRelDest))
		return 0;

	MakeMap2();	
	//DumpMap2();

	POINT pos;
	pos.x = (short)lpBuffer->posStart.x;
	pos.y = (short)lpBuffer->posStart.y;

	lpBuffer->iNodeCount = 0;

	BOOL bOK = FALSE;
	int nRes = GetBestMove(pos, nAdjust);
	while (nRes != PATH_FAIL && lpBuffer->iNodeCount < 255)
	{
		// Reached?
		if (nRes == PATH_REACHED)
		{
			bOK = TRUE;
			lpBuffer->aPathNodes[lpBuffer->iNodeCount].x = x;
			lpBuffer->aPathNodes[lpBuffer->iNodeCount].y = y;
			lpBuffer->iNodeCount++;
			break; // Finished
		}

		// Perform a redundancy check
		int nRedundancy = GetRedundancy(lpBuffer, pos);
		if (nRedundancy == -1)
		{
			// no redundancy
			lpBuffer->aPathNodes[lpBuffer->iNodeCount].x = (WORD)pos.x;
			lpBuffer->aPathNodes[lpBuffer->iNodeCount].y = (WORD)pos.y;
			lpBuffer->iNodeCount++;
		}
		else
		{
			// redundancy found, discard all redundant steps
			lpBuffer->iNodeCount = nRedundancy + 1;
			lpBuffer->aPathNodes[lpBuffer->iNodeCount].x = (WORD)pos.x;
			lpBuffer->aPathNodes[lpBuffer->iNodeCount].y = (WORD)pos.y;
		}	

		nRes = GetBestMove(pos, nAdjust);
	}	

	if (!bOK)
	{
		lpBuffer->iNodeCount = 0;
	}
	else
	{
		lpBuffer->posEnd.x = x;
		lpBuffer->posEnd.y = y;
	}
	
	//DumpMap1(lpBuffer);	// debug pictures
	return lpBuffer->iNodeCount;	
}
Exemplo n.º 7
0
//*****************************************************************************************
void CMimic::Process(
//Process a mimic for movement.
//
//Params:
	const int nLastCommand, //(in) Last swordsman command.
	CCueEvents &CueEvents)  //(in/out) Accepts pointer to an cues object that will be populated
							//with codes indicating events that happened that may correspond to
							//sound or graphical effects.
{
	int dx=0, dy=0;

	switch (nLastCommand)
	{
		case CMD_C:
		{
			this->wO = nNextCO(this->wO);
			break;
		}
		case CMD_CC:
		{
			this->wO = nNextCCO(this->wO);
			break;
		}
		case CMD_NW: dx = dy = -1; break;
		case CMD_N: dy = -1; break;
		case CMD_NE: dx = 1; dy = -1; break;
		case CMD_W: dx = -1; break;
		case CMD_E: dx = 1; break;
		case CMD_SW: dx = -1; dy = 1; break;
		case CMD_S: dx = 0; dy = 1; break;
		case CMD_SE: dx = dy = 1; break;
	}

	const UINT wMovementO = nGetO(dx, dy);

	if (this->bFrozen) //frozen by aumtlich gaze?
		dx = dy = 0;

	CDbRoom& room = *(this->pCurrentGame->pRoom);

	// Did the nLastCommand successfully move the swordsman.
	// If not, then set dx/dy to zero so mimics don't move
	if (this->pCurrentGame->IsPlayerAt(this->pCurrentGame->swordsman.wPrevX,
			this->pCurrentGame->swordsman.wPrevY))
	{
		dx=dy=0;
		this->wPrevX = this->wX;
		this->wPrevY = this->wY;

		//Player bumped into something, so mimics can "bump" into something in this
		//direction too, i.e. shatter a mirror in this direction if their sword is on it.
		this->wSwordMovement = CSwordsman::GetSwordMovement(nLastCommand, this->wO);
		if (nLastCommand != CMD_C && nLastCommand != CMD_CC && this->wSwordMovement != this->wO) //if not a turning or bumping movement
			this->wSwordMovement = NO_ORIENTATION;
		if (!HasSword() && wMovementO != NO_ORIENTATION) //they can face this direction when swordless
			this->wO = wMovementO;
	} else {
		GetBestMove(dx, dy);
		this->wSwordMovement = nGetO(dx, dy);

		//Check for obstacles in destination square.
		if (dx || dy)
		{
			ASSERT(nLastCommand != CMD_C && nLastCommand != CMD_CC && nLastCommand != CMD_WAIT
					&& nLastCommand != CMD_EXEC_COMMAND);

			//Before he moves, remember important square contents.
			const UINT wOTile = room.GetOSquare(this->wX, this->wY);
			const bool bWasOnTrapdoor = bIsTrapdoor(wOTile);
			const bool bWasOnPlatform = bIsPlatform(wOTile);

			//Move mimic to new destination square.
			Move(this->wX + dx, this->wY + dy, &CueEvents);

			if (!HasSword())
				this->wO = nGetO(dx,dy); //face the direction moved when w/o sword
			ASSERT(IsValidOrientation(this->wO));

			//Check for movement off of a trapdoor.
			ASSERT(dx || dy);
			if (bWasOnTrapdoor && HasSword())
				room.DestroyTrapdoor(this->wX - dx, this->wY - dy, CueEvents);

			//Check for platform movement.
			if (bWasOnPlatform)
			{
				const UINT wOTile = room.GetOSquare(this->wX, this->wY);
				if (bIsPit(wOTile) || bIsDeepWater(wOTile))
					room.MovePlatform(this->wX - dx, this->wY - dy, nGetO(dx,dy));
			}

			//Check for movement onto a checkpoint.
			this->pCurrentGame->QueryCheckpoint(CueEvents, this->wX, this->wY);

			//Process any and all of these item interactions.
			UINT tTile = room.GetTSquare(this->wX, this->wY);
			if (tTile==T_MIRROR)
			{
				room.PushObject(this->wX, this->wY, this->wX + dx, this->wY + dy, CueEvents);
				tTile = room.GetTSquare(this->wX, this->wY); //also check what was under the mirror
			}
			if (tTile==T_TOKEN)
				room.ActivateToken(CueEvents, this->wX, this->wY);
		} else {
			this->wPrevX = this->wX;
			this->wPrevY = this->wY;

			//Mimics can smash mirrors by bumping into them even when they don't move.
			this->wSwordMovement = CSwordsman::GetSwordMovement(nLastCommand, this->wO);
			if (nLastCommand != CMD_C && nLastCommand != CMD_CC && this->wSwordMovement != this->wO)
				this->wSwordMovement = NO_ORIENTATION;
			if (!HasSword() && wMovementO != NO_ORIENTATION) //they can face this direction when swordless
				this->wO = wMovementO;
		}
	}
	//Light any fuse stood on.
	room.LightFuse(CueEvents, this->wX, this->wY, true);
}