コード例 #1
0
ファイル: AlphaBeta.cpp プロジェクト: welwa/ualbertabot
const bool AlphaBeta::pruneMove(GameState & state, const IDType & playerToMove, const MoveArray & moves, const MoveTuple & tuple) const
{

	IDType enemy(getEnemy(playerToMove));

	// damage assigned to each enemy unit so far
	int hpRemaining[Search::Constants::Max_Units];
	for (IDType u(0); u<state.numUnits(enemy); ++u)
	{
		hpRemaining[u] = state.getUnit(enemy,u).currentHP();
	}

	// for each unit in the tuple
	for (size_t u(0); u<moves.numUnits(); u++)
	{
		// get its move
		const Move & m(moves.getTupleMove(tuple, u));

		if (m.type() == MoveTypes::ATTACK)
		{
			// if the target unit has already been killed then return prune
			if (hpRemaining[m.index()] <= 0)
			{
				return true;
			}

			hpRemaining[m.index()] -= state.getUnit(playerToMove, u).damage();
		}
	}

	return false;
}
コード例 #2
0
void Player_Random::getMoves(GameState & state, const MoveArray & moves, std::vector<Move> & moveVec)
{
	for (size_t u(0); u<moves.numUnits(); u++)
	{
		moveVec.push_back(moves.getMove(u, rand() % moves.numMoves(u)));
	}
}
コード例 #3
0
ファイル: AlphaBeta.cpp プロジェクト: welwa/ualbertabot
void AlphaBeta::doTupleMoves(GameState & state, MoveArray & moves, const MoveTuple & tuple)
{
	// for each simultaneous move in this tuple
	for (size_t u(0); u<moves.numUnitsInTuple(); ++u)
	{
		Move m = moves.getTupleMove(tuple, u);
		state.makeMove(m, state);
	}
}
コード例 #4
0
// causes playerToMove() to make the moves in the tuple
void LargeGame::makeMoves(const MoveTuple & tuple, MoveArray & arr)
{
	// for each simultaneous move in this tuple
	for (size_t u(0); u<arr.numUnitsInTuple(); ++u)
	{
		Move m = arr.getTupleMove(tuple, u);
		//printf("  Move (%d, %d) (%s, %s)\n", (int)tuple, (int)u, state.getUnit(m.player(), m.unit()).name().c_str(), m.moveString().c_str());
		state.makeMove(m, state);
	}
}
コード例 #5
0
bool AlphaBetaSearch::getNextMoveVec(IDType playerToMove, MoveArray & moves, const size_t & moveNumber, const TTLookupValue & TTval, const size_t & depth, std::vector<Action> & moveVec) const
{
    if (_params.maxChildren() && (moveNumber >= _params.maxChildren()))
    {
        return false;
    }

    // if this move is beyond the first, check to see if we are only using a single move
    if (moveNumber == 1)
    {
        // if we are player modeling, we should have only generated the first move
        if (_params.playerModel(playerToMove) != PlayerModels::None)
	    {
            // so return false
		    return false;
	    }

	    // if there is a transposition table entry for this state
	    if (TTval.found())
	    {
		    // if there was a valid move found with higher depth, just do that one
		    const AlphaBetaMove & abMove = getAlphaBetaMove(TTval, playerToMove);
		    if ((TTval.entry()->getDepth() >= depth) && abMove.isValid())
		    {
                // so return false
			    return false;
		    }
	    }
    }

	const Array<std::vector<Action>, Constants::Max_Ordered_Moves> & orderedMoves(_orderedMoves[depth]);
    moveVec.clear();
   
	// if this move should be from the ordered list, return it from the list
	if (moveNumber < orderedMoves.size())
	{
        moveVec.assign(orderedMoves[moveNumber].begin(), orderedMoves[moveNumber].end());
        return true;
	}
	// otherwise return the next move vector starting from the beginning
	else
	{
        if (moves.hasMoreMoves())
        {
            moves.getNextMoveVec(moveVec);
            return true;
        }
        else
        {
            return false;
        }
	}
}
コード例 #6
0
void UnitScriptData::calculateMoves(const IDType & player, MoveArray & moves, GameState & state, std::vector<Action> & moveVec)
{
    // generate all script moves for this player at this state and store them in allScriptMoves
    for (size_t scriptIndex(0); scriptIndex<_scriptVec[player].size(); ++scriptIndex)
    {
        // get the associated player pointer
        const PlayerPtr & pp = getPlayerPtr(player, scriptIndex);

        // get the actual script we are working with
        const IDType actualScript = getScript(player, scriptIndex);

        // generate the moves inside the appropriate vector
        getMoves(player, actualScript).clear();
        pp->getMoves(state, moves, getMoves(player, actualScript));
    }

    // for each unit the player has to move, populate the move vector with the appropriate script move
    for (size_t unitIndex(0); unitIndex < moves.numUnits(); ++unitIndex)
    {
        // the unit from the state
        const Unit & unit = state.getUnit(player, unitIndex);

        // the move it would choose to do based on its associated script preference
        Action unitMove = getMove(player, unitIndex, getUnitScript(unit));

        // put the unit into the move vector
        moveVec.push_back(unitMove);
    }
}
コード例 #7
0
ファイル: GameState.cpp プロジェクト: levjj/ualbertabot
void GameState::printMoveTuple(const IDType & player, const MoveTuple & t) const
{
	printf("\n");
	MoveArray moves;
	generateMoves(moves, player);
	for (size_t u(0); u<moves.numUnitsInTuple(); ++u)
	{
		Move m = moves.getTupleMove(t, u);
		
		std::cout << "Player " << (int)m.player() << " " << getUnit(m.player(), m.unit()).name() << " (id=" << (int)m.unit() << ")" << " " << m.moveString() ;
		if (m.type() == MoveTypes::ATTACK)
		{
			std::cout << " target " << getUnit(getEnemy(m.player()), m.index()).name() << " (id=" << (int)m.index() << ")";
		}

		std::cout << "\n";
	}
	
}
コード例 #8
0
ファイル: UCTSearch.cpp プロジェクト: eras44/sparcraft
bool UCTSearch::getNextMove(IDType playerToMove, MoveArray & moves, const size_t & moveNumber, std::vector<UnitAction> & actionVec)
{
    if (moveNumber > _params.maxChildren())
    {
        return false;
    }

    // if this move is beyond the first, check to see if we are only using a single move
    if (moveNumber == 1)
    {
        // if we are player modeling, we should have only generated the first move
        if (_params.playerModel(playerToMove) != PlayerModels::None)
	    {
            // so return false
		    return false;
	    }
    }

    actionVec.clear();

	// if this move should be from the ordered list, return it from the list
	if (moveNumber < _orderedMoves.size())
	{
        actionVec.assign(_orderedMoves[moveNumber].begin(), _orderedMoves[moveNumber].end());
        return true;
	}
	// otherwise return the next move vector starting from the beginning
	else
	{
        if (moves.hasMoreMoves())
        {
            moves.getNextMoveVec(actionVec);
            return true;
        }
        else
        {
            return false;
        }
	}
}
コード例 #9
0
ファイル: AlphaBeta.cpp プロジェクト: welwa/ualbertabot
const MoveTuple AlphaBeta::getNumMoveTuples(MoveArray & moves, const TTLookupValue & TTval, const IDType & playerToMove, const size_t & depth) const
{
	// if we are doing opponent modeling, there is just one move to do
	if (_params.usePlayerModel(playerToMove))
	{
		return 1;
	}

	// if there is a transposition table entry for this state
	if (TTval.found())
	{
		// if there was a valid move found with higher depth, just do that one
		const AlphaBetaMove & abMove = getAlphaBetaMove(TTval, playerToMove);
		if ((TTval.entry()->getDepth() >= depth) && abMove.isValid() && (abMove.moveTuple() < moves.numMoveTuples()))
		{
			return 1;
		}
	}

	// otherwise, it's the number of possible moves + number of ordered moves
	return moves.numMoveTuples();
}
コード例 #10
0
ファイル: GameState.cpp プロジェクト: levjj/ualbertabot
void GameState::generateMoves(MoveArray & moves, const IDType & playerIndex) const
{
	moves.clear();

	// which is the enemy player
	IDType enemyPlayer  = getEnemy(playerIndex);

	// we are interested in all simultaneous moves
	// so return all units which can move at the same time as the first
	TimeType firstUnitMoveTime = getUnit(playerIndex, 0).firstTimeFree();
		
	for (IDType unitIndex(0); unitIndex < _numUnits[playerIndex]; ++unitIndex)
	{
		// unit reference
		const Unit & unit(getUnit(playerIndex,unitIndex));
			
		// if this unit can't move at the same time as the first
		if (unit.firstTimeFree() != firstUnitMoveTime)
		{
			// stop checking
			break;
		}

		if (unit.previousMoveTime() == _currentTime && _currentTime != 0)
		{
			// CHANGED
            // printf("ERROR: Previous Move: %s\n", unit.previousMove().moveString().c_str());
			int a = 6;
		}

		moves.addUnit();

		// generate attack moves
		if (unit.canAttackNow())
		{
			for (IDType u(0); u<_numUnits[enemyPlayer]; ++u)
			{
				const Unit & enemyUnit(getUnit(enemyPlayer, u));
				if (unit.canAttackTarget(enemyUnit, _currentTime) && enemyUnit.isAlive())
				{
					moves.add(Move(unitIndex, playerIndex, MoveTypes::ATTACK, u));
				}
			}
		}
		else if (unit.canHealNow())
		{
			for (IDType u(0); u<_numUnits[playerIndex]; ++u)
			{
				// units cannot heal themselves in broodwar
				if (u == unitIndex)
				{
					continue;
				}

				const Unit & ourUnit(getUnit(playerIndex, u));
				if (unit.canHealTarget(ourUnit, _currentTime) && ourUnit.isAlive())
				{
					moves.add(Move(unitIndex, playerIndex, MoveTypes::HEAL, u));
				}
			}
		}
		// generate the wait move if it can't attack yet
		else
		{
			if (!unit.canHeal())
			{
				moves.add(Move(unitIndex, playerIndex, MoveTypes::RELOAD, 0));
			}
		}
		
		// generate movement moves
		if (unit.isMobile())
		{
			for (IDType d(0); d<Search::Constants::Num_Directions; ++d)
			{
				Move move(unitIndex, playerIndex, MoveTypes::MOVE, d);
			
				Position dest;
				Position dir(Search::Constants::Move_Dir[move._moveIndex][0], 
							 Search::Constants::Move_Dir[move._moveIndex][1]);
			
				// if the unit can attack the destination will be set by default move distance
				if (unit.canAttackNow() || unit.canHeal())
				{
					dest = Position(Search::Constants::Move_Distance*dir.x(), Search::Constants::Move_Distance*dir.y()) + unit.pos();
				}
				// otherwise it will be a move until attack move
				else
				{
					dest = unit.getMoveUntilAttackDest(dir, _currentTime);
				}

				if (isWalkable(dest))
				{
					moves.add(Move(unitIndex, playerIndex, MoveTypes::MOVE, d));
				}
			}
		}

		// if no moves were generated for this unit, it must be issued a 'PASS' move
		if (moves.numMoves(unitIndex) == 0)
		{
			moves.add(Move(unitIndex, playerIndex, MoveTypes::PASS, 0));
		}
	}

	if (!moves.validateMoves())
	{
		fprintf(stderr, "Moves invalid, something is wrong\n");
	}
}
コード例 #11
0
void GameState::generateMoves(MoveArray & moves, const IDType & playerIndex) const
{
	moves.clear();

    // which is the enemy player
	IDType enemyPlayer  = getEnemy(playerIndex);

    // make sure this player can move right now
    const IDType canMove(whoCanMove());
    if (canMove == enemyPlayer)
    {
        System::FatalError("GameState Error - Called generateMoves() for a player that cannot currently move");
    }

	// we are interested in all simultaneous moves
	// so return all units which can move at the same time as the first
	TimeType firstUnitMoveTime = getUnit(playerIndex, 0).firstTimeFree();
		
	for (IDType unitIndex(0); unitIndex < _numUnits[playerIndex]; ++unitIndex)
	{
		// unit reference
		const Unit & unit(getUnit(playerIndex,unitIndex));
			
		// if this unit can't move at the same time as the first
		if (unit.firstTimeFree() != firstUnitMoveTime)
		{
			// stop checking
			break;
		}

		if (unit.previousActionTime() == _currentTime && _currentTime != 0)
		{
            System::FatalError("Previous Move Took 0 Time: " + unit.previousAction().moveString());
		}

		moves.addUnit();

		// generate attack moves
		if (unit.canAttackNow())
		{
			for (IDType u(0); u<_numUnits[enemyPlayer]; ++u)
			{
				const Unit & enemyUnit(getUnit(enemyPlayer, u));
				bool invisible = false;
				if (enemyUnit.type().hasPermanentCloak())
				{
					invisible = true;
					for (IDType detectorIndex(0); detectorIndex < _numUnits[playerIndex]; ++detectorIndex)
					{
						// unit reference
						const Unit & detector(getUnit(playerIndex, detectorIndex));
						if (detector.type().isDetector() && detector.canSeeTarget(enemyUnit, _currentTime))
						{
							invisible = false;
							break;
						}
					}
				}
				if (!invisible && unit.canAttackTarget(enemyUnit, _currentTime) && enemyUnit.isAlive())
				{
					moves.add(Action(unitIndex, playerIndex, ActionTypes::ATTACK, u));
                    //moves.add(Action(unitIndex, playerIndex, ActionTypes::ATTACK, unit.ID()));
				}
			}
		}
		else if (unit.canHealNow())
		{
			for (IDType u(0); u<_numUnits[playerIndex]; ++u)
			{
				// units cannot heal themselves in broodwar
				if (u == unitIndex)
				{
					continue;
				}

				const Unit & ourUnit(getUnit(playerIndex, u));
				if (unit.canHealTarget(ourUnit, _currentTime) && ourUnit.isAlive())
				{
					moves.add(Action(unitIndex, playerIndex, ActionTypes::HEAL, u));
                    //moves.add(Action(unitIndex, playerIndex, ActionTypes::HEAL, unit.ID()));
				}
			}
		}
		// generate the wait move if it can't attack yet
		else
		{
			if (!unit.canHeal())
			{
				moves.add(Action(unitIndex, playerIndex, ActionTypes::RELOAD, 0));
			}
		}
		
		// generate movement moves
		if (unit.isMobile())
		{
            // In order to not move when we could be shooting, we want to move for the minimum of:
            // 1) default move distance move time
            // 2) time until unit can attack, or if it can attack, the next cooldown
            double timeUntilAttack          = unit.nextAttackActionTime() - getTime();
            timeUntilAttack                 = timeUntilAttack == 0 ? unit.attackCooldown() : timeUntilAttack;

            // the default move duration
            double defaultMoveDuration      = (double)Constants::Move_Distance / unit.speed();

            // if we can currently attack
			double chosenTime = timeUntilAttack != 0 ? std::min(timeUntilAttack, defaultMoveDuration) : defaultMoveDuration;

            // the chosen movement distance
            PositionType moveDistance       = (PositionType)(chosenTime * unit.speed());

            // DEBUG: If chosen move distance is ever 0, something is wrong
            if (moveDistance == 0)
            {
                System::FatalError("Move Action with distance 0 generated. timeUntilAttack:"+
					std::to_string(timeUntilAttack)+", speed:"+std::to_string(unit.speed()));
            }

            // we are only generating moves in the cardinal direction specified in common.h
			for (IDType d(0); d<Constants::Num_Directions; ++d)
			{			
                // the direction of this movement
              	Position dir(Constants::Move_Dir[d][0], Constants::Move_Dir[d][1]);
            
                if (moveDistance == 0)
                {
                    printf("%lf %lf %lf\n", timeUntilAttack, defaultMoveDuration, chosenTime);
                }

                // the final destination position of the unit
                Position dest = unit.pos() + Position(moveDistance*dir.x(), moveDistance*dir.y());

                // if that poisition on the map is walkable
                if (isWalkable(dest) || (unit.type().isFlyer() && isFlyable(dest)))
				{
                    // add the move to the MoveArray
					moves.add(Action(unitIndex, playerIndex, ActionTypes::MOVE, d, dest));
				}
			}
		}

		// if no moves were generated for this unit, it must be issued a 'PASS' move
		if (moves.numMoves(unitIndex) == 0)
		{
			moves.add(Action(unitIndex, playerIndex, ActionTypes::PASS, 0));
		}
	}
}
コード例 #12
0
void Player_NOKDPS::getMoves(GameState & state, const MoveArray & moves, std::vector<UnitAction> & moveVec)
{
    moveVec.clear();
	IDType enemy(state.getEnemy(_playerID));

	Array<int, Constants::Max_Units> hpRemaining;

	for (IDType u(0); u<state.numUnits(enemy); ++u)
	{
		hpRemaining[u] = state.getUnit(enemy,u).currentHP();
	}

	for (IDType u(0); u<moves.numUnits(); ++u)
	{
		bool foundUnitAction						(false);
		size_t actionMoveIndex					(0);
		double actionHighestDPS					(0);
		size_t closestMoveIndex					(0);
		unsigned long long closestMoveDist		(std::numeric_limits<unsigned long long>::max());
		
		const Unit & ourUnit				(state.getUnit(_playerID, u));
		const Unit & closestUnit(ourUnit.canHeal() ? state.getClosestOurUnit(_playerID, u) : ourUnit.type().isDetector() ? state.getClosestEnemyUnit(_playerID, u, false):state.getClosestEnemyUnit(_playerID, u, true));
		
		for (size_t m(0); m<moves.numMoves(u); ++m)
		{
			const UnitAction move						(moves.getMove(u, m));
				
			if ((move.type() == UnitActionTypes::ATTACK) && (hpRemaining[move._moveIndex] > 0))
			{
				const Unit & target				(state.getUnit(state.getEnemy(move.player()), move._moveIndex));
				double dpsHPValue =				(target.dpf() / hpRemaining[move._moveIndex]);

				if (dpsHPValue > actionHighestDPS)
				{
					actionHighestDPS = dpsHPValue;
					actionMoveIndex = m;
					foundUnitAction = true;
				}

                if (move._moveIndex >= state.numUnits(enemy))
                {
                    int e = enemy;
                    int pl = _playerID;
                    printf("wtf\n");
                }
			}
			else if (move.type() == UnitActionTypes::HEAL)
			{
				const Unit & target				(state.getUnit(move.player(), move._moveIndex));
				double dpsHPValue =				(target.dpf() / hpRemaining[move._moveIndex]);

				if (dpsHPValue > actionHighestDPS)
				{
					actionHighestDPS = dpsHPValue;
					actionMoveIndex = m;
					foundUnitAction = true;
				}
			}
			else if (move.type() == UnitActionTypes::RELOAD)
			{
				if (ourUnit.canAttackTarget(closestUnit, state.getTime()))
				{
					closestMoveIndex = m;
					break;
				}
			}
			else if (move.type() == UnitActionTypes::MOVE)
			{
				Position ourDest				(ourUnit.x() + Constants::Move_Dir[move._moveIndex][0], 
												 ourUnit.y() + Constants::Move_Dir[move._moveIndex][1]);
				size_t dist						(closestUnit.getDistanceSqToPosition(ourDest, state.getTime()));

				if (dist < closestMoveDist)
				{
					closestMoveDist = dist;
					closestMoveIndex = m;
				}
			}
		}

		size_t bestMoveIndex(foundUnitAction ? actionMoveIndex : closestMoveIndex);

		UnitAction theMove(moves.getMove(u, actionMoveIndex));
		if (theMove.type() == UnitActionTypes::ATTACK)
		{
			hpRemaining[theMove.index()] -= state.getUnit(_playerID, theMove.unit()).damage();
		}
			
		moveVec.push_back(moves.getMove(u, bestMoveIndex));
	}
}
コード例 #13
0
const MoveTuple Player_AttackClosest::getMoveTuple(GameState & state, const MoveArray & moves)
{
	MoveTuple tuple(0);

	for (IDType u(0); u<moves.numUnits(); ++u)
	{
		bool foundAction					(false);
		size_t actionMoveIndex				(0);
		size_t closestMoveIndex				(0);
		unsigned long long actionDistance	(std::numeric_limits<unsigned long long>::max());
		unsigned long long closestMoveDist	(std::numeric_limits<unsigned long long>::max());

		const Unit & ourUnit				(state.getUnit(_playerID, u));
		const Unit & closestUnit			(ourUnit.canHeal() ? state.getClosestOurUnit(_playerID, u) : state.getClosestEnemyUnit(_playerID, u));

		for (size_t m(0); m<moves.numMoves(u); ++m)
		{
			const Move move					(moves.getMove(u, m));
				
			if (move.type() == MoveTypes::ATTACK)
			{
				const Unit & target			(state.getUnit(state.getEnemy(move.player()), move._moveIndex));
				size_t dist					(ourUnit.distSq(target, state.getTime()));

				if (dist < actionDistance)
				{
					actionDistance = dist;
					actionMoveIndex = m;
					foundAction = true;
				}
			}
			if (move.type() == MoveTypes::HEAL)
			{
				const Unit & target			(state.getUnit(move.player(), move._moveIndex));
				size_t dist					(ourUnit.distSq(target, state.getTime()));

				if (dist < actionDistance)
				{
					actionDistance = dist;
					actionMoveIndex = m;
					foundAction = true;
				}
			}
			else if (move.type() == MoveTypes::RELOAD)
			{
				if (ourUnit.canAttackTarget(closestUnit, state.getTime()))
				{
					closestMoveIndex = m;
					break;
				}
			}
			else if (move.type() == MoveTypes::MOVE)
			{
				Position ourDest			(ourUnit.x() + Search::Constants::Move_Dir[move._moveIndex][0], 
											 ourUnit.y() + Search::Constants::Move_Dir[move._moveIndex][1]);
				size_t dist					(closestUnit.distSq(ourDest, state.getTime()));

				if (dist < closestMoveDist)
				{
					closestMoveDist = dist;
					closestMoveIndex = m;
				}
			}
		}

		size_t bestMoveIndex(foundAction ? actionMoveIndex : closestMoveIndex);

		tuple += bestMoveIndex * moves.getProduct(u);
	}

	return tuple;
}
コード例 #14
0
void Player_KiterDPS::getMoves(GameState & state, const MoveArray & moves, std::vector<Move> & moveVec)
{
	for (IDType u(0); u<moves.numUnits(); ++u)
	{
		bool foundAction						(false);
		IDType actionMoveIndex					(0);
		IDType furthestMoveIndex				(0);
		size_t furthestMoveDist					(0);
		IDType closestMoveIndex					(0);
		double actionHighestDPS					(0);
		unsigned long long closestMoveDist		(std::numeric_limits<unsigned long long>::max());

		const Unit & ourUnit					(state.getUnit(_playerID, u));
		const Unit & closestUnit				(ourUnit.canHeal() ? state.getClosestOurUnit(_playerID, u) : state.getClosestEnemyUnit(_playerID, u));

		for (IDType m(0); m<moves.numMoves(u); ++m)
		{
			const Move move						(moves.getMove(u, m));
				
			if (move.type() == MoveTypes::ATTACK)
			{
				const Unit & target				(state.getUnit(state.getEnemy(move.player()), move._moveIndex));
				double dpsHPValue 				(target.dpf() / target.currentHP());

				if (dpsHPValue > actionHighestDPS)
				{
					actionHighestDPS = dpsHPValue;
					actionMoveIndex = m;
					foundAction = true;
				}
			}
			else if (move.type() == MoveTypes::HEAL)
			{
				const Unit & target				(state.getUnit(move.player(), move._moveIndex));
				double dpsHPValue 				(target.dpf() / target.currentHP());

				if (dpsHPValue > actionHighestDPS)
				{
					actionHighestDPS = dpsHPValue;
					actionMoveIndex = m;
					foundAction = true;
				}
			}
			else if (move.type() == MoveTypes::MOVE)
			{
				Position ourDest				(ourUnit.x() + Search::Constants::Move_Dir[move._moveIndex][0], 
												 ourUnit.y() + Search::Constants::Move_Dir[move._moveIndex][1]);
				size_t dist						(closestUnit.distSq(ourDest, state.getTime()));

				if (dist > furthestMoveDist)
				{
					furthestMoveDist = dist;
					furthestMoveIndex = m;
				}

				if (dist < closestMoveDist)
				{
					closestMoveDist = dist;
					closestMoveIndex = m;
				}
			}
		}

		// the move we will be returning
		size_t bestMoveIndex(0);

		// if we have an attack move we will use that one
		if (foundAction)
		{
			bestMoveIndex = actionMoveIndex;
		}
		// otherwise use the closest move to the opponent
		else
		{
			// if we are in attack range of the unit, back up
			if (ourUnit.canAttackTarget(closestUnit, state.getTime()))
			{
				bestMoveIndex = furthestMoveIndex;
			}
			// otherwise get back into the fight
			else
			{
				bestMoveIndex = closestMoveIndex;
			}
		}
		
		moveVec.push_back(moves.getMove(u, bestMoveIndex));
	}
}
コード例 #15
0
// TODO: UNTESTED
const MoveTuple Player_Kiter::getMoveTuple(GameState & state, const MoveArray & moves)
{
	// the tuple, we will generate this on the fly
	MoveTuple tuple(0);
	
	for (IDType u(0); u<moves.numUnits(); ++u)
	{
		bool foundAction						(false);
		IDType actionMoveIndex					(0);
		IDType furthestMoveIndex				(0);
		size_t furthestMoveDist					(0);
		IDType closestMoveIndex					(0);
		int actionDistance						(std::numeric_limits<int>::max());
		unsigned long long closestMoveDist		(std::numeric_limits<unsigned long long>::max());

		const Unit & ourUnit					(state.getUnit(_playerID, u));
		const Unit & closestUnit				(ourUnit.canHeal() ? state.getClosestOurUnit(_playerID, u) : state.getClosestEnemyUnit(_playerID, u));

		for (IDType m(0); m<moves.numMoves(u); ++m)
		{
			const Move move						(moves.getMove(u, m));
				
			if (move.type() == MoveTypes::ATTACK)
			{
				const Unit & target				(state.getUnit(state.getEnemy(move.player()), move._moveIndex));
				PositionType dist				(ourUnit.distSq(target, state.getTime()));

				if (dist < actionDistance)
				{
					actionDistance = dist;
					actionMoveIndex = m;
					foundAction = true;
				}
			}
			else if (move.type() == MoveTypes::HEAL)
			{
				const Unit & target				(state.getUnit(move.player(), move._moveIndex));
				PositionType dist				(ourUnit.distSq(target, state.getTime()));

				if (dist < actionDistance)
				{
					actionDistance = dist;
					actionMoveIndex = m;
					foundAction = true;
				}
			}
			else if (move.type() == MoveTypes::MOVE)
			{
				Position ourDest				(ourUnit.x() + Search::Constants::Move_Dir[move._moveIndex][0], 
												 ourUnit.y() + Search::Constants::Move_Dir[move._moveIndex][1]);
				size_t dist						(closestUnit.distSq(ourDest, state.getTime()));

				if (dist > furthestMoveDist)
				{
					furthestMoveDist = dist;
					furthestMoveIndex = m;
				}

				if (dist < closestMoveDist)
				{
					closestMoveDist = dist;
					closestMoveIndex = m;
				}
			}
		}

		// the move we will be returning
		size_t bestMoveIndex(0);

		// if we have an attack move we will use that one
		if (foundAction)
		{
			bestMoveIndex = actionMoveIndex;
		}
		// otherwise use the closest move to the opponent
		else
		{
			// if we are in attack range of the unit, back up
			if (ourUnit.canAttackTarget(closestUnit, state.getTime()))
			{
				bestMoveIndex = furthestMoveIndex;
			}
			// otherwise get back into the fight
			else
			{
				bestMoveIndex = closestMoveIndex;
			}
		}
			
		// update the tuple calculation
		tuple += bestMoveIndex * moves.getProduct(u);
	}

	return tuple;
}
コード例 #16
0
const MoveTuple Player_NOK_AttackDPS::getMoveTuple(GameState & state, const MoveArray & moves)
{
	MoveTuple tuple(0);

	IDType player(moves.getMove(0,0).player());
	IDType enemy(state.getEnemy(player));

	Array<int, Search::Constants::Max_Units> hpRemaining;
	if (state.numUnits(enemy) > Search::Constants::Max_Units) 
	{
		hpRemaining.resize(state.numUnits(enemy));
	}

	for (IDType u(0); u<state.numUnits(enemy); ++u)
	{
		hpRemaining[u] = state.getUnit(enemy,u).currentHP();
	}

	for (IDType u(0); u<moves.numUnits(); ++u)
	{
		bool foundAction						(false);
		size_t actionMoveIndex					(0);
		double actionHighestDPS					(0);
		size_t closestMoveIndex					(0);
		unsigned long long closestMoveDist		(std::numeric_limits<unsigned long long>::max());
		
		const Unit & ourUnit				(state.getUnit(_playerID, u));
		const Unit & closestUnit			(ourUnit.canHeal() ? state.getClosestOurUnit(_playerID, u) : state.getClosestEnemyUnit(_playerID, u));

		for (size_t m(0); m<moves.numMoves(u); ++m)
		{
			const Move move						(moves.getMove(u, m));
				
			if ((move.type() == MoveTypes::ATTACK) && (hpRemaining[move._moveIndex] > 0))
			{
				const Unit & target				(state.getUnit(state.getEnemy(move.player()), move._moveIndex));
				double dpsHPValue =				(target.dpf() / hpRemaining[move._moveIndex]);

				if (dpsHPValue > actionHighestDPS)
				{
					actionHighestDPS = dpsHPValue;
					actionMoveIndex = m;
					foundAction = true;
				}
			}
			else if (move.type() == MoveTypes::HEAL)
			{
				const Unit & target				(state.getUnit(move.player(), move._moveIndex));
				double dpsHPValue =				(target.dpf() / hpRemaining[move._moveIndex]);

				if (dpsHPValue > actionHighestDPS)
				{
					actionHighestDPS = dpsHPValue;
					actionMoveIndex = m;
					foundAction = true;
				}
			}
			else if (move.type() == MoveTypes::RELOAD)
			{
				if (ourUnit.canAttackTarget(closestUnit, state.getTime()))
				{
					closestMoveIndex = m;
					break;
				}
			}
			else if (move.type() == MoveTypes::MOVE)
			{
				Position ourDest				(ourUnit.x() + Search::Constants::Move_Dir[move._moveIndex][0], 
												 ourUnit.y() + Search::Constants::Move_Dir[move._moveIndex][1]);
				size_t dist						(closestUnit.distSq(ourDest, state.getTime()));

				if (dist < closestMoveDist)
				{
					closestMoveDist = dist;
					closestMoveIndex = m;
				}
			}
		}

		size_t bestMoveIndex(foundAction ? actionMoveIndex : closestMoveIndex);

		Move theMove(moves.getMove(u, actionMoveIndex));
		if (theMove.type() == MoveTypes::ATTACK)
		{
			hpRemaining[theMove.index()] -= state.getUnit(player, theMove.unit()).damage();
		}
			
		tuple += bestMoveIndex * moves.getProduct(u);
	}

	return tuple;
}
コード例 #17
0
void Player_AttackDPS::getMoves(GameState & state, const MoveArray & moves, std::vector<Move> & moveVec)
{
	for (IDType u(0); u<moves.numUnits(); ++u)
	{
		bool foundAction						(false);
		size_t actionMoveIndex					(0);
		size_t closestMoveIndex					(0);
		double actionHighestDPS					(0);
		unsigned long long closestMoveDist		(std::numeric_limits<unsigned long long>::max());
		
		const Unit & ourUnit					(state.getUnit(_playerID, u));
		const Unit & closestUnit				(ourUnit.canHeal() ? state.getClosestOurUnit(_playerID, u) : state.getClosestEnemyUnit(_playerID, u));

		for (size_t m(0); m<moves.numMoves(u); ++m)
		{
			const Move move						(moves.getMove(u, m));
				
			if (move.type() == MoveTypes::ATTACK)
			{
				const Unit & target				(state.getUnit(state.getEnemy(move.player()), move._moveIndex));
				double dpsHPValue =				(target.dpf() / target.currentHP());

				if (dpsHPValue > actionHighestDPS)
				{
					actionHighestDPS = dpsHPValue;
					actionMoveIndex = m;
					foundAction = true;
				}
			}
			if (move.type() == MoveTypes::HEAL)
			{
				const Unit & target				(state.getUnit(move.player(), move._moveIndex));
				double dpsHPValue =				(target.dpf() / target.currentHP());

				if (dpsHPValue > actionHighestDPS)
				{
					actionHighestDPS = dpsHPValue;
					actionMoveIndex = m;
					foundAction = true;
				}
			}
			else if (move.type() == MoveTypes::RELOAD)
			{
				if (ourUnit.canAttackTarget(closestUnit, state.getTime()))
				{
					closestMoveIndex = m;
					break;
				}
			}
			else if (move.type() == MoveTypes::MOVE)
			{
				Position ourDest				(ourUnit.x() + Search::Constants::Move_Dir[move._moveIndex][0], 
												 ourUnit.y() + Search::Constants::Move_Dir[move._moveIndex][1]);
				size_t dist						(closestUnit.distSq(ourDest, state.getTime()));

				if (dist < closestMoveDist)
				{
					closestMoveDist = dist;
					closestMoveIndex = m;
				}
			}
		}

		size_t bestMoveIndex(foundAction ? actionMoveIndex : closestMoveIndex);
			
		moveVec.push_back(moves.getMove(u, bestMoveIndex));
	}
}
コード例 #18
0
// get desired move tuple for this player's strategy
const MoveTuple Player_Random::getMoveTuple(GameState & state, const MoveArray & moves)
{
	//boost::random::uniform_int_distribution<> dist(0, moves.numMoveTuples() - 1);
		
	return rand() % moves.numMoveTuples();
}
コード例 #19
0
ファイル: AlphaBeta.cpp プロジェクト: welwa/ualbertabot
void AlphaBeta::generateOrderedMoves(GameState & state, MoveArray & moves, const TTLookupValue & TTval, const IDType & playerToMove, const size_t & depth)
{
	// get the array where we will store the moves and clear it
	Array<MoveTuple, Search::Constants::Max_Ordered_Moves> & orderedMoves(_orderedMoves[depth]);
	orderedMoves.clear();

	// if we are using opponent modeling, get the move and then return, we don't want to put any more moves in
	if (_params.usePlayerModel(playerToMove))
	{
		MoveTuple playerModelMove = _params.getPlayer(playerToMove)->getMoveTuple(state, moves);
		orderedMoves.add(playerModelMove);
		return;
	}

	// if there is a transposition table entry for this state
	if (TTval.found())
	{
		// get the abMove we stored for this player
		const AlphaBetaMove & abMove = getAlphaBetaMove(TTval, playerToMove);

		// here we get an incorrect move from the transposition table
		if (abMove.moveTuple() >= moves.numMoveTuples())
		{
			HashType h0 = state.calculateHash(0);
			HashType h1 = state.calculateHash(1);

			MoveArray moves2;
			state.generateMoves(moves2, playerToMove);
			// figure out why
			//fprintf(stderr, "Something very wrong, this tuple (%d) doesn't exist, only (%d) moves\n", (int)abMove.moveTuple(), (int)moves.numMoveTuples());
		}

		_results.ttFoundCheck++;

		// Two checks:
		// 1) Is the move 'valid' ie: was it actually set inside the TT
		// 2) Is it a valid tuple number for this move set? This guards against double
		//    hash collision errors. Even if it is a collision, this is just a move
		//    ordering, so no errors should occur.
		if (abMove.isValid() && (abMove.moveTuple() < moves.numMoveTuples()))
		{
			orderedMoves.add(abMove.moveTuple());
			_results.ttMoveOrders++;
			return;
		}
		else
		{
			_results.ttFoundButNoMove++;
		}
	}

	// if we are using script modeling, insert the script moves we want
	if (_params.useScriptMoveFirst())
	{
		for (size_t s(0); s<_allScripts.size(); s++)
		{
			MoveTuple scriptMove = _allScripts[s]->getMoveTuple(state, moves);

			orderedMoves.addUnique(scriptMove);
		}
	}
}
コード例 #20
0
ファイル: ecocoder.cpp プロジェクト: jdart1/arasan-chess
int CDECL main(int argc, char **argv)
{
   Bitboard::init();
   Attacks::init();
   Scoring::init();
   if (!initGlobals(argv[0], false)) {
      cleanupGlobals();
      exit(-1);
   }
   atexit(cleanupGlobals);

   Board board;
   ECO eco;
   int arg = 1;

   if (argc <=1)
   {
      show_usage();
      return -1;
   }
   else
   {
      ifstream pgn_file( argv[arg], ios::in | ios::binary);
      int c;
      ColorType side;
      string result, white, black;
      if (!pgn_file.good()) {
         cerr << "could not open file " << argv[arg] << endl;
         exit(-1);
      }
      else
      {
         vector<ChessIO::Header> hdrs;
         while (!pgn_file.eof())
         {
            long first;
            MoveArray moves;
            board.reset();
            side = White;
            while (pgn_file.good() && (c = pgn_file.get()) != EOF)
            {
               if (c=='[')
               {
                  int c1 = pgn_file.get();
                  if (c1 == 'E') {
                     int c2 = pgn_file.get();
                     if (c2 == 'v') {
                        pgn_file.putback(c2);
                        pgn_file.putback(c1);
                        pgn_file.putback(c);
                        break;
                     }
                  }
               }
            }
            hdrs.clear();
            ChessIO::collect_headers(pgn_file,hdrs,first);
            if (!hdrs.size()) continue;
            bool ok = true;
            bool done = false;
            bool exit = false;
            while (ok && !exit) {
               ChessIO::Token tok = ChessIO::get_next_token(pgn_file);
               string num;
               switch (tok.type) {
               case ChessIO::Eof: {
                  exit = true;
                  break;
               }
               case ChessIO::Number: {
                  num = tok.val;
                  break;
               }
               case ChessIO::GameMove: {
                  if (done) {
                     // we should not have moves after the result
                     // if it looks like a tag, push it back
                     if (tok.val.size() && tok.val[0] == '[') {
                        for (int i = (int)tok.val.size()-1; i >= 0; --i)
                           pgn_file.putback(tok.val[0]);
                     }
                     exit = true;
                     break;
                  }
                  // parse the move
                  Move m = Notation::value(board,side,Notation::InputFormat::SAN,tok.val);
                  if (IsNull(m) ||
                      !legalMove(board,StartSquare(m),
                                 DestSquare(m))) {
                     // echo to both stdout and stderr
                     cerr << "Illegal move: " << tok.val << endl;
                     cout << "Illegal move: " << tok.val << endl;
                     ok = false;
                  }
                  else {
                     BoardState bs = board.state;
                     string img;
                     // convert to SAN
                     Notation::image(board,m,Notation::OutputFormat::SAN,img);
                     moves.add_move(board,bs,m,img,false);
                     board.doMove(m);
                  }
                  side = OppositeColor(side);
                  break;
               }
               case ChessIO::Unknown: {
                  if (done) {
                     // ignore unknown text after result
                     // if it looks like a tag, push it back
                     if (tok.val.size() && tok.val[0] == '[') {
                        for (int i = (int)tok.val.size()-1; i >= 0; --i)
                           pgn_file.putback(tok.val[0]);
                     }
                     exit = true;
                     break;
                  }
                  cerr << "Unrecognized text: " << tok.val << endl;
                  break;
               }
               case ChessIO::Comment: {
                  // ignored for now
                  break;
               }
               case ChessIO::Result: {
                  result = tok.val;
                  done = true;
                  break;
               }
               case ChessIO::OpenVar:
                   cerr << "Warning: variations not supported" << endl;
                   done = true;
               default:
                   break;

               } // end switch
            }
            // output header
            string ecoC = "";
            int found = ChessIO::get_header(hdrs,"ECO",ecoC);
            if (!found) {
               string name;
               eco.classify(moves,ecoC,name);
               if (ecoC != "") {
                  ChessIO::Header ecoHeader("ECO",ecoC.c_str());
                  hdrs.push_back(ecoHeader);
               }
            }
            else if (ecoC == "") {
               string name;
               eco.classify(moves,ecoC,name);
               if (ecoC != "") {
                  ChessIO::Header ecoHeader("ECO",ecoC.c_str());
                  for (auto it = hdrs.begin(); it != hdrs.end(); it++) {
                     const ChessIO::Header &hdr = *it;
                     if (hdr.tag() == "ECO") { // replace old header
                        *it = ecoHeader;
                        break;
                     }
                  }
               }
            }
            if (moves.num_moves()>0) ChessIO::store_pgn(cout,moves,result,hdrs);
         }
         pgn_file.close();
      }
   }

   return 0;
}
コード例 #21
0
void Player_AttackClosest::getMoves(const GameState & state, const MoveArray & moves, std::vector<UnitAction> & moveVec)
{
    moveVec.clear();
	for (IDType u(0); u<moves.numUnits(); ++u)
	{
		bool foundUnitAction				(false);
		size_t actionMoveIndex				(0);
		size_t closestMoveIndex				(0);
		unsigned long long actionDistance	(std::numeric_limits<unsigned long long>::max());
		unsigned long long closestMoveDist	(std::numeric_limits<unsigned long long>::max());

		const Unit & ourUnit				(state.getUnit(_playerID, u));
		const Unit & closestUnit			(ourUnit.canHeal() ? state.getClosestOurUnit(_playerID, u) : state.getClosestEnemyUnit(_playerID, u));

		for (size_t m(0); m<moves.numMoves(u); ++m)
		{
			const UnitAction move					(moves.getMove(u, m));
				
			if (move.type() == UnitActionTypes::ATTACK)
			{
				const Unit & target			(state.getUnit(state.getEnemy(move.player()), move._moveIndex));
				size_t dist					(ourUnit.getDistanceSqToUnit(target, state.getTime()));

				if (dist < actionDistance)
				{
					actionDistance = dist;
					actionMoveIndex = m;
					foundUnitAction = true;
				}
			}
			if (move.type() == UnitActionTypes::HEAL)
			{
				const Unit & target			(state.getUnit(move.player(), move._moveIndex));
				size_t dist					(ourUnit.getDistanceSqToUnit(target, state.getTime()));

				if (dist < actionDistance)
				{
					actionDistance = dist;
					actionMoveIndex = m;
					foundUnitAction = true;
				}
			}
			else if (move.type() == UnitActionTypes::RELOAD)
			{
				if (ourUnit.canAttackTarget(closestUnit, state.getTime()))
				{
					closestMoveIndex = m;
					break;
				}
			}
			else if (move.type() == UnitActionTypes::MOVE)
			{
				Position ourDest			(ourUnit.x() + Constants::Move_Dir[move._moveIndex][0], 
											 ourUnit.y() + Constants::Move_Dir[move._moveIndex][1]);
				size_t dist					(closestUnit.getDistanceSqToPosition(ourDest, state.getTime()));

				if (dist < closestMoveDist)
				{
					closestMoveDist = dist;
					closestMoveIndex = m;
				}
			}
		}

		size_t bestMoveIndex(foundUnitAction ? actionMoveIndex : closestMoveIndex);

		moveVec.push_back(moves.getMove(u, bestMoveIndex));
	}
}
コード例 #22
0
void Player_Kiter_NOKDPS::getMoves(GameState & state, const MoveArray & moves, std::vector<Action> & moveVec)
{
    moveVec.clear();
	IDType enemy(state.getEnemy(_playerID));

	Array<int, Constants::Max_Units> hpRemaining;

	for (IDType u(0); u<state.numUnits(enemy); ++u)
	{
		hpRemaining[u] = state.getUnit(enemy,u).currentHP();
	}

	for (IDType u(0); u<moves.numUnits(); ++u)
	{
		bool foundAction					(false);
		size_t actionMoveIndex					(0);
        IDType furthestMoveIndex				(0);
		size_t furthestMoveDist					(0);
		double actionHighestDPS					(0);
		size_t closestMoveIndex					(0);
		unsigned long long closestMoveDist		(std::numeric_limits<unsigned long long>::max());
		
		const Unit & ourUnit				(state.getUnit(_playerID, u));
		const Unit & closestUnit			(ourUnit.canHeal() ? state.getClosestOurUnit(_playerID, u) : state.getClosestEnemyUnit(_playerID, u));

		for (size_t m(0); m<moves.numMoves(u); ++m)
		{
			const Action move						(moves.getMove(u, m));
				
			if ((move.type() == ActionTypes::ATTACK) && (hpRemaining[move.index()] > 0))
			{
				const Unit & target				(state.getUnit(state.getEnemy(move.player()), move.index()));
				double dpsHPValue =				(target.dpf() / hpRemaining[move.index()]);

				if (dpsHPValue > actionHighestDPS)
				{
					actionHighestDPS = dpsHPValue;
					actionMoveIndex = m;
					foundAction = true;
				}

                if (move.index() >= state.numUnits(enemy))
                {
                    int e = enemy;
                    int pl = _playerID;
                    printf("wtf\n");
                }
			}
			else if (move.type() == ActionTypes::HEAL)
			{
				const Unit & target				(state.getUnit(move.player(), move.index()));
				double dpsHPValue =				(target.dpf() / hpRemaining[move.index()]);

				if (dpsHPValue > actionHighestDPS)
				{
					actionHighestDPS = dpsHPValue;
					actionMoveIndex = m;
					foundAction = true;
				}
			}
			else if (move.type() == ActionTypes::RELOAD)
			{
				if (ourUnit.canAttackTarget(closestUnit, state.getTime()))
				{
					closestMoveIndex = m;
					break;
				}
			}
			else if (move.type() == ActionTypes::MOVE)
			{
				Position ourDest				(ourUnit.x() + Constants::Move_Dir[move.index()][0], 
												 ourUnit.y() + Constants::Move_Dir[move.index()][1]);
				size_t dist						(closestUnit.getDistanceSqToPosition(ourDest, state.getTime()));

                if (dist > furthestMoveDist)
				{
					furthestMoveDist = dist;
					furthestMoveIndex = m;
				}

				if (dist < closestMoveDist)
				{
					closestMoveDist = dist;
					closestMoveIndex = m;
				}
			}
		}

		size_t bestMoveIndex(0);
        // if we have an attack move we will use that one
		if (foundAction)
		{
			bestMoveIndex = actionMoveIndex;
		}
		// otherwise use the closest move to the opponent
		else
		{
			// if we are in attack range of the unit, back up
			if (ourUnit.canAttackTarget(closestUnit, state.getTime()))
			{
				bestMoveIndex = furthestMoveIndex;
			}
			// otherwise get back into the fight
			else
			{
				bestMoveIndex = closestMoveIndex;
			}
		}

		Action theMove(moves.getMove(u, actionMoveIndex));
		if (theMove.type() == ActionTypes::ATTACK)
		{
			hpRemaining[theMove.index()] -= state.getUnit(_playerID, theMove.unit()).damage();
		}
			
		moveVec.push_back(moves.getMove(u, bestMoveIndex));
	}
}