//public abstract TimedPlay TimedPlayOnRoll(GameState gamestate, List<PlayHint> hints);
 public abstract TimedPlay TimedPlayOnRoll(GameState gamestate, List<PlayHint> hints, VenueUndoMethod undo_method);
Beispiel #2
0
        public override TimedPlay TimedPlayOnRoll(GameState gamestate, List <PlayHint> hints, VenueUndoMethod undo_method)
        {
            List <Play> legal_plays  = gamestate.Board.LegalPlays(gamestate.PlayerOnRoll, gamestate.Dice);
            List <Move> forced_moves = Board.ForcedMoves(legal_plays);

            // Sort the moves.
            foreach (PlayHint hint in hints)
            {
                SortMoves(gamestate, hint.Play, legal_plays, forced_moves);
            }

            double optimal_move_equity = hints[0].Equity;

            double doubtful = 0.04;
            double bad      = 0.08;
            double very_bad = 0.16;

            /*List<PlayHint> good_hints = new List<PlayHint>();
             * List<PlayHint> doubtful_hints = new List<PlayHint>();
             * List<PlayHint> bad_hints = new List<PlayHint>();
             * List<PlayHint> very_bad_hints = new List<PlayHint>();
             *
             * // Skip the first one as it is the optimal one.
             * for (int i = 1; i < hints.Count; i++)
             * {
             *  double diff = optimal_move_equity - hints[i].Equity;
             *  if (diff >= very_bad)
             *      very_bad_hints.Add(hints[i]);
             *  else if (diff >= bad)
             *      very_bad_hints.Add(hints[i]);
             *  else if (diff >= doubtful)
             *      doubtful_hints.Add(hints[i]);
             *  else
             *      good_hints.Add(hints[i]);
             * }*/

            /*if (legal_plays.Count != hints.Count)
             * {
             *  Console.WriteLine("Legal plays and hint plays mis-match");
             *  Console.WriteLine("Legal plays: ");
             *  foreach (Play play in legal_plays)
             *      Console.WriteLine(play);
             *  Console.WriteLine("Hint plays: ");
             *  foreach (PlayHint hint in hints)
             *      Console.WriteLine(hint);
             *
             *  throw new Exception();
             * }*/

            // Is the play an obvious move? Check the equity difference to second best move.
            bool obvious_move = false;

            if (legal_plays.Count == 1 || (hints.Count > 1 && (hints[1].Equity - optimal_move_equity) > bad))
            {
                obvious_move = true;
            }

            List <Play> fake_plays = new List <Play>();

            if (!obvious_move && undo_method != VenueUndoMethod.None)
            {
                // Choose the amount of fake plays.
                int fake_plays_to_choose = 0;
                if (random.NextDouble() <= undo_probability)
                {
                    fake_plays_to_choose++;
                    while (random.NextDouble() < 0.1)
                    {
                        fake_plays_to_choose++;
                    }
                }

                // Choose the fake plays.
                for (int i = 0; i < fake_plays_to_choose; i++)
                {
                    int fake_play_index = 1;
                    while (random.Next(3) == 0)
                    {
                        fake_play_index++;
                        if (fake_play_index >= hints.Count)
                        {
                            fake_play_index = 0;
                        }
                    }

                    // Make it partial?
                    if (random.NextDouble() <= 0.3)
                    {
                        Play partial_play    = new Play();
                        int  moves_to_choose = 1;
                        while (random.Next(4) == 0)
                        {
                            moves_to_choose++;
                            if (moves_to_choose >= hints[fake_play_index].Play.Count)
                            {
                                moves_to_choose = 1;
                            }
                        }

                        for (int m = 0; m < moves_to_choose; m++)
                        {
                            partial_play.Add(hints[fake_play_index].Play[m]);
                        }

                        fake_plays.Add(partial_play);
                    }
                    else
                    {
                        fake_plays.Add(hints[fake_play_index].Play);
                    }
                }
            }

            TimedPlay timed_play = new TimedPlay();

            // Add undo sequences using fake plays.
            if (!obvious_move && hints.Count > 1 && fake_plays.Count > 0)
            {
                List <Move> made_moves = new List <Move>();
                //Queue<Move> made_moves = new Queue<Move>();
                //Stack<Move> made_moves = new Stack<Move>();

                foreach (Play fake_play in fake_plays)
                {
                    for (int i = 0; i < fake_play.Count; i++)
                    {
                        /*if (made_moves.Count > 0)
                         * {
                         *  int shared = 0;
                         *  while (shared < made_moves.Count && shared < fake_play.Count && made_moves[shared] == fake_play[shared])
                         *      shared++;
                         * }
                         * else*/
                        timed_play.Add(new TimedMove(fake_play[i], 0, 0));
                        //made_moves.Push(fake_play[i]);
                    }

                    // Undo all
                    if (undo_method == VenueUndoMethod.UndoLast)
                    {
                        for (int i = 0; i < fake_play.Count; i++)
                        {
                            timed_play.Add(TimedMove.CreateUndoMove(0, 0));
                        }
                    }
                    else
                    {
                        timed_play.Add(TimedMove.CreateUndoMove(0, 0));
                    }
                }

                int m = 0;
                // TODO: Some how check if current move and previous share some similar so not necessary undo all.

                foreach (Move move in hints[0].Play)
                {
                    timed_play.Add(new TimedMove(move, 0, 0));
                }
            }
            else
            {
                // No fake plays, add the optimal move.
                foreach (Move move in hints[0].Play)
                {
                    timed_play.Add(new TimedMove(move, 0, 0));
                }
            }


            int  last_from     = -2;
            bool was_last_undo = false;

            foreach (TimedMove timed_move in timed_play)
            {
                if (timed_move.IsUndo)
                {
                    if (was_last_undo)
                    {
                        timed_move.WaitBefore = Gaussian.Next(500, 200, 10000, 600, 1.5);
                        timed_move.WaitAfter  = random.Next(200);
                    }
                    else
                    {
                        timed_move.WaitBefore = Gaussian.Next(1000, 500, 10000, 2000, 1.5);
                        timed_move.WaitAfter  = Gaussian.Next(1000, 50, 10000, 2000, 1.5);
                    }

                    last_from = -2;

                    was_last_undo = true;

                    continue;
                }

                was_last_undo = false;

                if (timed_move.From != last_from)
                {
                    //timed_move.WaitBefore = Gaussian.Next(500, 250, 2000, 500, 3.0);
                    //timed_move.WaitAfter = random.Next(300);
                    timed_move.WaitBefore = Gaussian.Next(1000, 250, 2000, 1000, 3.0);
                    timed_move.WaitAfter  = random.Next(300);
                }
                else
                {
                    //timed_move.WaitBefore = Gaussian.Next(250, 100, 2000, 200, 3.0);
                    //timed_move.WaitAfter = random.Next(100);
                    timed_move.WaitBefore = Gaussian.Next(500, 250, 2000, 200, 3.0);
                    timed_move.WaitAfter  = random.Next(250);
                }

                // Speedup for pure race or when we have a blockade.
                if (random.NextDouble() <= 0.9 && (gamestate.Board.IsPureRace() || HasBlockaded(gamestate) || obvious_move))
                {
                    timed_move.WaitBefore = (int)(timed_move.WaitBefore * (0.4 + 0.3 * random.NextDouble()));
                    timed_move.WaitAfter  = (int)(timed_move.WaitAfter * (0.4 + 0.3 * random.NextDouble()));
                }

                last_from = timed_move.From;
            }

            // Normalize with coefficient.
            foreach (TimedMove timed_move in timed_play)
            {
                timed_move.WaitBefore = (int)(timed_move.WaitBefore * coefficient);
                timed_move.WaitAfter  = (int)(timed_move.WaitAfter * coefficient);
            }

            return(timed_play);
        }
 public override TimedPlay TimedPlayOnRoll(GameState gamestate, List <PlayHint> hints, VenueUndoMethod undo_method)
 {
     return(TimedPlayOnRoll(gamestate, hints[0].Play));
 }
 //public abstract TimedPlay TimedPlayOnRoll(GameState gamestate, List<PlayHint> hints);
 public abstract TimedPlay TimedPlayOnRoll(GameState gamestate, List <PlayHint> hints, VenueUndoMethod undo_method);
 public override TimedPlay TimedPlayOnRoll(GameState gamestate, List<PlayHint> hints, VenueUndoMethod undo_method)
 {
     return TimedPlayOnRoll(gamestate, hints[0].Play);
 }
        public override TimedPlay TimedPlayOnRoll(GameState gamestate, List<PlayHint> hints, VenueUndoMethod undo_method)
        {
            List<Play> legal_plays = gamestate.Board.LegalPlays(gamestate.PlayerOnRoll, gamestate.Dice);
            List<Move> forced_moves = Board.ForcedMoves(legal_plays);

            // Sort the moves.
            foreach (PlayHint hint in hints)
            {
                SortMoves(gamestate, hint.Play, legal_plays, forced_moves);
            }

            double optimal_move_equity = hints[0].Equity;

            double doubtful = 0.04;
            double bad = 0.08;
            double very_bad = 0.16;

            /*List<PlayHint> good_hints = new List<PlayHint>();
            List<PlayHint> doubtful_hints = new List<PlayHint>();
            List<PlayHint> bad_hints = new List<PlayHint>();
            List<PlayHint> very_bad_hints = new List<PlayHint>();

            // Skip the first one as it is the optimal one.
            for (int i = 1; i < hints.Count; i++)
            {
                double diff = optimal_move_equity - hints[i].Equity;
                if (diff >= very_bad)
                    very_bad_hints.Add(hints[i]);
                else if (diff >= bad)
                    very_bad_hints.Add(hints[i]);
                else if (diff >= doubtful)
                    doubtful_hints.Add(hints[i]);
                else
                    good_hints.Add(hints[i]);
            }*/

            /*if (legal_plays.Count != hints.Count)
            {
                Console.WriteLine("Legal plays and hint plays mis-match");
                Console.WriteLine("Legal plays: ");
                foreach (Play play in legal_plays)
                    Console.WriteLine(play);
                Console.WriteLine("Hint plays: ");
                foreach (PlayHint hint in hints)
                    Console.WriteLine(hint);

                throw new Exception();
            }*/

            // Is the play an obvious move? Check the equity difference to second best move.
            bool obvious_move = false;
            if (legal_plays.Count == 1 || (hints.Count > 1 && (hints[1].Equity - optimal_move_equity) > bad))
                obvious_move = true;

            List<Play> fake_plays = new List<Play>();

            if (!obvious_move && undo_method != VenueUndoMethod.None)
            {
                // Choose the amount of fake plays.
                int fake_plays_to_choose = 0;
                if (random.NextDouble() <= undo_probability)
                {
                    fake_plays_to_choose++;
                    while (random.NextDouble() < 0.1)
                        fake_plays_to_choose++;
                }

                // Choose the fake plays.
                for (int i = 0; i < fake_plays_to_choose; i++)
                {
                    int fake_play_index = 1;
                    while (random.Next(3) == 0)
                    {
                        fake_play_index++;
                        if (fake_play_index >= hints.Count)
                            fake_play_index = 0;
                    }

                    // Make it partial?
                    if (random.NextDouble() <= 0.3)
                    {
                        Play partial_play = new Play();
                        int moves_to_choose = 1;
                        while (random.Next(4) == 0)
                        {
                            moves_to_choose++;
                            if (moves_to_choose >= hints[fake_play_index].Play.Count)
                                moves_to_choose = 1;
                        }

                        for (int m = 0; m < moves_to_choose; m++)
                        {
                            partial_play.Add(hints[fake_play_index].Play[m]);
                        }

                        fake_plays.Add(partial_play);
                    }
                    else
                        fake_plays.Add(hints[fake_play_index].Play);
                }
            }

            TimedPlay timed_play = new TimedPlay();

            // Add undo sequences using fake plays.
            if (!obvious_move && hints.Count > 1 && fake_plays.Count > 0)
            {
                List<Move> made_moves = new List<Move>();
                //Queue<Move> made_moves = new Queue<Move>();
                //Stack<Move> made_moves = new Stack<Move>();

                foreach (Play fake_play in fake_plays)
                {
                    for (int i = 0; i < fake_play.Count; i++)
                    {
                        /*if (made_moves.Count > 0)
                        {
                            int shared = 0;
                            while (shared < made_moves.Count && shared < fake_play.Count && made_moves[shared] == fake_play[shared])
                                shared++;
                        }
                        else*/
                        timed_play.Add(new TimedMove(fake_play[i], 0, 0));
                        //made_moves.Push(fake_play[i]);
                    }

                    // Undo all
                    if (undo_method == VenueUndoMethod.UndoLast)
                        for (int i = 0; i < fake_play.Count; i++)
                            timed_play.Add(TimedMove.CreateUndoMove(0, 0));
                    else
                        timed_play.Add(TimedMove.CreateUndoMove(0, 0));
                }

                int m = 0;
                // TODO: Some how check if current move and previous share some similar so not necessary undo all.

                foreach (Move move in hints[0].Play)
                    timed_play.Add(new TimedMove(move, 0, 0));
            }
            else
            {
                // No fake plays, add the optimal move.
                foreach (Move move in hints[0].Play)
                    timed_play.Add(new TimedMove(move, 0, 0));
            }

            int last_from = -2;
            bool was_last_undo = false;
            foreach (TimedMove timed_move in timed_play)
            {
                if (timed_move.IsUndo)
                {
                    if (was_last_undo)
                    {
                        timed_move.WaitBefore = Gaussian.Next(500, 200, 10000, 600, 1.5);
                        timed_move.WaitAfter = random.Next(200);
                    }
                    else
                    {
                        timed_move.WaitBefore = Gaussian.Next(1000, 500, 10000, 2000, 1.5);
                        timed_move.WaitAfter = Gaussian.Next(1000, 50, 10000, 2000, 1.5);
                    }

                    last_from = -2;

                    was_last_undo = true;

                    continue;
                }

                was_last_undo = false;

                if (timed_move.From != last_from)
                {
                    //timed_move.WaitBefore = Gaussian.Next(500, 250, 2000, 500, 3.0);
                    //timed_move.WaitAfter = random.Next(300);
                    timed_move.WaitBefore = Gaussian.Next(1000, 250, 2000, 1000, 3.0);
                    timed_move.WaitAfter = random.Next(300);
                }
                else
                {
                    //timed_move.WaitBefore = Gaussian.Next(250, 100, 2000, 200, 3.0);
                    //timed_move.WaitAfter = random.Next(100);
                    timed_move.WaitBefore = Gaussian.Next(500, 250, 2000, 200, 3.0);
                    timed_move.WaitAfter = random.Next(250);
                }

                // Speedup for pure race or when we have a blockade.
                if (random.NextDouble() <= 0.9 && (gamestate.Board.IsPureRace() || HasBlockaded(gamestate) || obvious_move))
                {
                    timed_move.WaitBefore = (int)(timed_move.WaitBefore * (0.4 + 0.3 * random.NextDouble()));
                    timed_move.WaitAfter = (int)(timed_move.WaitAfter * (0.4 + 0.3 * random.NextDouble()));
                }

                last_from = timed_move.From;
            }

            // Normalize with coefficient.
            foreach (TimedMove timed_move in timed_play)
            {
                timed_move.WaitBefore = (int)(timed_move.WaitBefore * coefficient);
                timed_move.WaitAfter = (int)(timed_move.WaitAfter * coefficient);
            }

            return timed_play;
        }
        public override TimedPlay TimedPlayOnRoll(GameState gamestate, List<PlayHint> hints, VenueUndoMethod undo_method)
        {
            TimedPlay play = new TimedPlay();

            foreach (Move move in hints[0].Play)
            {
                play.Add(new TimedMove(move, (int)this.moves[random.Next(this.moves.Count)].Key.Time, 0));
            }

            return play;
        }
        public override TimedPlay TimedPlayOnRoll(GameState gamestate, List <PlayHint> hints, VenueUndoMethod undo_method)
        {
            TimedPlay play = new TimedPlay();

            foreach (Move move in hints[0].Play)
            {
                play.Add(new TimedMove(move, (int)this.moves[random.Next(this.moves.Count)].Key.Time, 0));
            }


            return(play);
        }