public double EstimateWinProbability(Game game, ID <Readable_GamePlayer> playerId)
        {
            Readable_GamePlayer player = game.Get_ReadableSnapshot(playerId);

            // first check for obvious things like whether one player has already lost
            if (game.GetWinner() != null)
            {
                if (game.GetWinner() == player)
                {
                    return(1);
                }
                else
                {
                    return(0);
                }
            }
            if (game.GetLosers().Count == game.NumPlayers)
            {
                return(0);
                //return 1.0 / game.NumPlayers;
            }
            // Now compute a heuristic based on how much stuff each player has
            double totalScore   = 0;
            double playerScore  = 0;
            double activePlayer = 1;

            foreach (Readable_GamePlayer candidate in game.Players)
            {
                // Exchange rates:
                // n power and n toughness is worth n mana
                // losing 25% of your life is worth 2 mana
                // 1 crystal per turn is worth 2 mana now.
                // n cards in hand is worth n mana (the cards often generate n mana worth of value (plus the mana spent to play them) even though they often cost 2*n to draw them)
                // Being the active player is worth 0.5 cards and 0.5 mana/turn, but the active player has received 1 additional card and 1 additional mana, so these must each be subtracted instead
                // This results in this score (equivalent amount of mana this turn):
                // mana+manaPerTurn*2++((power+toughness)/2)+(log(life)/log(4/3))+(activePlayer?)*-1.5+handSize

                /*
                 * double score = candidate.Get_CurrentResources().ToNumber() * activePlayer / 2 + candidate.Get_ResourcesPerTurn().ToNumber() - activePlayer * 2 +
                 *  (candidate.Get_Total_MonsterDamage(game) + candidate.Get_Total_MonsterHealth(game)) / 2 + Math.Log(candidate.GetHealth()) / Math.Log(4.0 / 3.0);
                 */
                double score = candidate.Get_CurrentResources().ToNumber() * activePlayer + candidate.Get_ResourcesPerTurn().ToNumber() * 2
                               + (candidate.Get_Total_MonsterDamage(game) + candidate.Get_Total_MonsterHealth(game)) / 2 + Math.Log(candidate.GetHealth()) / Math.Log(4.0 / 3.0) + activePlayer * -1.5
                               + candidate.Get_ReadableHand().Count;

                if (score < 1) // can't have 0 or less probability of winning unless you've actually lost already
                {
                    score = 1;
                }

                totalScore += score;
                if (candidate == player)
                {
                    playerScore = score;
                }
                activePlayer *= 0;
            }
            return(playerScore / totalScore);
        }
Exemplo n.º 2
0
        public void PlayGame(int player1Index, int player2Index)
        {
            List <TournamentPlayer> players = new List <TournamentPlayer>();
            TournamentPlayer        player1 = this.Players[player1Index];
            TournamentPlayer        player2 = this.Players[player2Index];

            players.Add(this.Players[player1Index]);
            players.Add(this.Players[player2Index]);
            Game game = this.referee.NewGame(players);

            if (player1Index == 0 || player2Index == 0)
            {
                game.ShouldPrint = true;
            }
            game.Play();
            if (game.GetWinner() != null)
            {
                TournamentPlayer winner = game.GetWinner().SourcePlayer;
                int winnerIndex, loserIndex;
                TournamentPlayer loser = null;
                if (winner == player1)
                {
                    winnerIndex = player1Index;
                    loserIndex  = player2Index;
                }
                else
                {
                    if (winner == player2)
                    {
                        winnerIndex = player2Index;
                        loserIndex  = player1Index;
                    }
                    else
                    {
                        return;
                    }
                }
                loser = this.Players[loserIndex];
                winner.NumWins++;
                loser.NumLosses++;

                if (winnerIndex > 0)
                {
                    // improve winner's rank by 1
                    this.Players.RemoveAt(winnerIndex);
                    winnerIndex--;
                    this.Players.Insert(winnerIndex, winner);
                    if (winnerIndex == loserIndex)
                    {
                        return;
                    }
                }
                // worsen losers's rank by 1
                if (loserIndex < players.Count - 1)
                {
                    this.Players.RemoveAt(loserIndex);
                    loserIndex++;
                    this.Players.Insert(loserIndex, loser);
                }
            }
        }