Esempio n. 1
0
        public void TakeTurn(Player p)
        {
            if (p.OutOfMoves)
            {
                Log.important($"{p} is out, skipping turn!");
                return;
            }

            var AllMoves = AllPossibleMoves(p);

            if (AllMoves.Count == 0)
            {
                Log.important($"{p} is out of moves!");
                p.OutOfMoves = true;
                return;
            }

            if (!p.AI)
            {
                TakeHumanTurn(p);
                return;
            }

            var MoveTree = AllMoves.Select(o => new List <PossibleMove>()
            {
                o
            }).ToList();

            var LookSteps = p.LookAhead;

            if (p.Hand.Count(o => o.Type == CardType.PlaceMeeple) == 3)
            {
                LookSteps += 1;
            }

            var SW = new Stopwatch();

            SW.Start();
            bool MovesExhausted = false;

            for (int LookAhead = 1; LookAhead <= LookSteps; LookAhead++)
            {
                Log.info($"Performing lookahead step {LookAhead}");
                var NewMoveTree = new List <List <PossibleMove> >();
                var LogState    = Log.Enabled;
                Log.Enabled = false;

                foreach (var MoveCombo in MoveTree)
                {
                    if (MoveCombo.Count != LookAhead)
                    {
                        continue;
                    }

                    var Virtualboard  = Board.MakeCopy();
                    var VirtualPlayer = Virtualboard.Players[p.ID];

                    foreach (var m in MoveCombo)
                    {
                        Virtualboard.PlayMove(m, VirtualPlayer);
                    }

                    VirtualPlayer.Hand = VirtualPlayer.Hand.Where(o => o.Type != CardType.Shadow).ToList();

                    var FutureMoves = AllPossibleMoves(VirtualPlayer, Virtualboard);
                    if (FutureMoves.Count == 0)
                    {
                        continue;
                    }

                    foreach (var fm in FutureMoves)
                    {
                        var newcombo = MoveCombo.ToList();
                        newcombo.Add(fm);
                        NewMoveTree.Add(newcombo);
                    }
                }

                Log.Enabled = LogState;

                if (NewMoveTree.Count > 0)
                {
                    MoveTree.AddRange(NewMoveTree);
                }
                else
                {
                    Log.important($"All moves enhausted after {LookAhead} steps");
                    MovesExhausted = true;
                    break;
                }
            }

            var BestOneMoveScore = AllMoves.Max(j => j.ScoreValue);
            var BestMove         = AllMoves.First(o => o.ScoreValue == BestOneMoveScore);

            Log.info($"Best greedy move is {BestMove}, considered {MoveTree.Count} moves");

            List <PossibleMove> MyMove;

            if (p.ID == 1)
            {
                MyMove = DecideMove(p, MoveTree);
            }
            else
            {
                MyMove = DecideMoveOLD(p, MoveTree);
            }

            //foreach (var m in MyMove) {
            //    Vis.RenderMove(m);
            //    Vis.Refresh();
            //}

            if (MyMove.Sum(o => o.ScoreValue) < 0 && MovesExhausted && p.Hand.Count(o => o.Type == CardType.Shadow) == 0)
            {
                Log.important($"Not a good move! I pass");
                p.OutOfMoves = true;
            }
            else
            {
                if (MyMove.First().Destination.Type == CardType.Trap)
                {
                    Log.debug($"Its a trap!");
                }

                Board.PlayMove(MyMove.First(), p);
            }
        }