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); } }