public void Simulate(bool threaded) { SerializeRoot(); Console.WriteLine(); NeedCalculation = false; List <Board> boards = new List <Board>(); boards.Add(root); int wide = 0; int depth = 0; int maxDepth = 15; int maxWide = 3000; int maxBoards = 2000; int maxWideT = 5000; int maxBoardsT = 3000; int skipped = 0; root.Update(); bool tryToSkipEqualBoards = true; Board bestBoard = root; Log("ROOTBOARD : "); Log(root.ToString()); Log(""); Console.WriteLine(root.ToString()); bool foundearly = false; List <Board> Roots = new List <Board>(); List <Board> Childs = new List <Board>(); if (threaded) { foreach (HREngine.Bots.Action a in root.CalculateAvailableActions()) { Board tmp = root.ExecuteAction(a); Roots.Add(tmp); Childs.Add(tmp); } Childs.Add(root); while (Roots.Count > 0) { wide = Roots.Count; if (Roots.Count > maxWideT) { wide = maxWideT; } float widePerTree = 0; float wideTree = 0; widePerTree = 2; ManualResetEvent[] doneEvents = new ManualResetEvent[wide]; for (int i = 0; i < wide; i++) { doneEvents[i] = new ManualResetEvent(false); SimulationThread thread = new SimulationThread(); ThreadPool.QueueUserWorkItem(thread.Calculate, (object)new SimulationThreadStart(Roots[i], ref Childs, doneEvents[i], widePerTree)); } foreach (var e in doneEvents) { e.WaitOne(); } bool foundLethal = false; foreach (Board baa in Childs) { if (baa == null) { continue; } if (baa.GetValue() > 10000) { foundLethal = true; bestBoard = baa; break; } Board endBoard = Board.Clone(baa); endBoard.EndTurn(); bestBoard.CalculateEnemyTurn(); if (bestBoard.EnemyTurnWorseBoard != null) { endBoard.CalculateEnemyTurn(); Board worstBoard = endBoard.EnemyTurnWorseBoard; if (worstBoard == null) { worstBoard = endBoard; } if (worstBoard.GetValue() > bestBoard.EnemyTurnWorseBoard.GetValue()) { bestBoard = endBoard; } else if (worstBoard.GetValue() == bestBoard.EnemyTurnWorseBoard.GetValue()) { if (endBoard.GetValue() > bestBoard.GetValue()) { bestBoard = endBoard; } } } else { if (endBoard.GetValue() > bestBoard.GetValue()) { bestBoard = endBoard; } } } if (foundLethal) { break; } Roots.Clear(); int boardsAdded = 0; //Childs.RemoveAll(item => item == null); //Childs.Sort((x, y) => y.GetValue().CompareTo(x.GetValue())); foreach (Board bbb in Childs) { if (bbb != null) { Roots.Add(bbb); boardsAdded++; if (boardsAdded > maxBoardsT) { break; } } } Childs.Clear(); } } else { float widePerTree = 0; float wideTree = 0; while (boards.Count != 0) { if (depth >= maxDepth) { break; } wide = 0; skipped = 0; List <Board> childs = new List <Board>(); widePerTree = maxWide / boards.Count; foreach (Board b in boards) { wideTree = 0; List <Action> actions = b.CalculateAvailableActions(); foreach (Action a in actions) { if (wide > maxWide) { break; } if (wideTree >= widePerTree) { break; } Board bb = b.ExecuteAction(a); /* * Console.WriteLine(a.ToString()); * Console.WriteLine("**************************************"); * Console.WriteLine(bb.ToString()); */ if (bb != null) { if (bb.GetValue() > 10000) { bestBoard = bb; foundearly = true; break; } if (tryToSkipEqualBoards) { bool found = false; foreach (Board lol in childs) { if (bb.Equals(lol)) { found = true; break; } } if (!found) { wideTree++; wide++; childs.Add(bb); } else { skipped++; } } else { wideTree++; wide++; childs.Add(bb); } } } if (foundearly) { break; } } if (!foundearly) { List <Board> bestBoards = new List <Board>(); int limit = maxBoards; if (childs.Count < maxBoards) { limit = childs.Count; } childs.Sort((x, y) => y.GetValue().CompareTo(x.GetValue())); childs = new List <Board>(childs.GetRange(0, limit)); foreach (Board baa in childs) { Board endBoard = Board.Clone(baa); endBoard.EndTurn(); bestBoard.CalculateEnemyTurn(); if (bestBoard.EnemyTurnWorseBoard != null) { endBoard.CalculateEnemyTurn(); Board worstBoard = endBoard.EnemyTurnWorseBoard; if (worstBoard == null) { worstBoard = endBoard; } if (worstBoard.GetValue() > bestBoard.EnemyTurnWorseBoard.GetValue()) { bestBoard = endBoard; } else if (worstBoard.GetValue() == bestBoard.EnemyTurnWorseBoard.GetValue()) { if (endBoard.GetValue() > bestBoard.GetValue()) { bestBoard = endBoard; } } } else { if (endBoard.GetValue() > bestBoard.GetValue()) { bestBoard = endBoard; } } } } else { Log("Found early at : " + depth.ToString() + " | " + wide.ToString()); Console.WriteLine("Found Early"); break; } Log("Simulation :" + depth.ToString() + " | " + wide.ToString() + " | " + skipped.ToString()); Console.WriteLine("Simulation :" + depth.ToString() + " | " + wide.ToString() + " | " + skipped.ToString()); boards.Clear(); boards = childs; depth++; } } Action actionPrior = null; foreach (Action acc in bestBoard.ActionsStack) { if (actionPrior == null && acc.Actor != null) { if (acc.Actor.Behavior.GetPriorityPlay(bestBoard) > 1 && acc.Type != Action.ActionType.MINION_ATTACK && acc.Type != Action.ActionType.HERO_ATTACK) { Console.WriteLine("Action priori found"); if (acc.Type == Action.ActionType.CAST_MINION && acc.Actor.Behavior.ShouldBePlayed(root)) { if (root.MinionFriend.Count < 7) { actionPrior = acc; } } else if (acc.Actor.Behavior.ShouldBePlayed(root)) { actionPrior = acc; } } } } List <Action> finalStack = new List <Action>(); if (actionPrior != null) { finalStack.Add(actionPrior); if (bestBoard.ActionsStack.IndexOf(actionPrior) + 2 <= bestBoard.ActionsStack.Count) { if (bestBoard.ActionsStack[bestBoard.ActionsStack.IndexOf(actionPrior) + 1] != null) { if (bestBoard.ActionsStack[bestBoard.ActionsStack.IndexOf(actionPrior) + 1].Type == Action.ActionType.RESIMULATE) { finalStack.Add(new Action(Action.ActionType.RESIMULATE, null)); } } } foreach (Action a in bestBoard.ActionsStack) { if (a != actionPrior || a.Type == Action.ActionType.RESIMULATE) { if (a.Type == Action.ActionType.RESIMULATE && finalStack[finalStack.Count - 1].Type == Action.ActionType.RESIMULATE) { continue; } finalStack.Add(a); } } } else { finalStack = bestBoard.ActionsStack; } ActionStack = finalStack; Log(""); Log(""); Log(""); Log(""); Log("BEST BOARD FOUND"); Log(bestBoard.ToString()); Console.WriteLine("---------------------------------"); Console.WriteLine(bestBoard.ToString()); Console.WriteLine("---------------------------------"); foreach (HREngine.Bots.Action a in ActionStack) { Log(a.ToString()); Console.WriteLine(a.ToString()); } }
public void Simulate(bool threaded) { SerializeRoot(); Console.WriteLine(); NeedCalculation = false; List<Board> boards = new List<Board>(); boards.Add(root); int wide = 0; int depth = 0; int maxDepth = 15; int maxWide = 3000; int maxBoards = 2000; int maxWideT = 5000; int maxBoardsT = 3000; int skipped = 0; root.Update(); bool tryToSkipEqualBoards = true; Board bestBoard = root; Log("ROOTBOARD : "); Log(root.ToString()); Log(""); Console.WriteLine(root.ToString()); bool foundearly = false; List<Board> Roots = new List<Board>(); List<Board> Childs = new List<Board>(); if (threaded) { foreach (HREngine.Bots.Action a in root.CalculateAvailableActions()) { Board tmp = root.ExecuteAction(a); Roots.Add(tmp); Childs.Add(tmp); } Childs.Add(root); while (Roots.Count > 0) { wide = Roots.Count; if (Roots.Count > maxWideT) wide = maxWideT; float widePerTree = 0; float wideTree = 0; widePerTree =2; ManualResetEvent[] doneEvents = new ManualResetEvent[wide]; for (int i = 0; i < wide; i++) { doneEvents[i] = new ManualResetEvent(false); SimulationThread thread = new SimulationThread(); ThreadPool.QueueUserWorkItem(thread.Calculate, (object)new SimulationThreadStart(Roots[i], ref Childs, doneEvents[i], widePerTree)); } foreach (var e in doneEvents) e.WaitOne(); bool foundLethal = false; foreach (Board baa in Childs) { if (baa == null) continue; if(baa.GetValue() > 10000) { foundLethal = true; bestBoard = baa; break; } Board endBoard = Board.Clone(baa); endBoard.EndTurn(); bestBoard.CalculateEnemyTurn(); if (bestBoard.EnemyTurnWorseBoard != null) { endBoard.CalculateEnemyTurn(); Board worstBoard = endBoard.EnemyTurnWorseBoard; if (worstBoard == null) worstBoard = endBoard; if (worstBoard.GetValue() > bestBoard.EnemyTurnWorseBoard.GetValue()) { bestBoard = endBoard; } else if (worstBoard.GetValue() == bestBoard.EnemyTurnWorseBoard.GetValue()) { if (endBoard.GetValue() > bestBoard.GetValue()) { bestBoard = endBoard; } } } else { if (endBoard.GetValue() > bestBoard.GetValue()) { bestBoard = endBoard; } } } if (foundLethal) break; Roots.Clear(); int boardsAdded = 0; //Childs.RemoveAll(item => item == null); //Childs.Sort((x, y) => y.GetValue().CompareTo(x.GetValue())); foreach (Board bbb in Childs) { if (bbb != null) { Roots.Add(bbb); boardsAdded++; if (boardsAdded > maxBoardsT) break; } } Childs.Clear(); } } else { float widePerTree = 0; float wideTree = 0; while (boards.Count != 0) { if (depth >= maxDepth) break; wide = 0; skipped = 0; List<Board> childs = new List<Board>(); widePerTree = maxWide / boards.Count; foreach (Board b in boards) { wideTree = 0; List<Action> actions = b.CalculateAvailableActions(); foreach (Action a in actions) { if (wide > maxWide) break; if (wideTree >= widePerTree) break; Board bb = b.ExecuteAction(a); /* Console.WriteLine(a.ToString()); Console.WriteLine("**************************************"); Console.WriteLine(bb.ToString()); */ if (bb != null) { if (bb.GetValue() > 10000) { bestBoard = bb; foundearly = true; break; } if (tryToSkipEqualBoards) { bool found = false; foreach (Board lol in childs) { if (bb.Equals(lol)) { found = true; break; } } if (!found) { wideTree++; wide++; childs.Add(bb); } else { skipped++; } } else { wideTree++; wide++; childs.Add(bb); } } } if (foundearly) break; } if (!foundearly) { List<Board> bestBoards = new List<Board>(); int limit = maxBoards; if (childs.Count < maxBoards) limit = childs.Count; childs.Sort((x, y) => y.GetValue().CompareTo(x.GetValue())); childs = new List<Board>(childs.GetRange(0, limit)); foreach (Board baa in childs) { Board endBoard = Board.Clone(baa); endBoard.EndTurn(); bestBoard.CalculateEnemyTurn(); if (bestBoard.EnemyTurnWorseBoard != null) { endBoard.CalculateEnemyTurn(); Board worstBoard = endBoard.EnemyTurnWorseBoard; if (worstBoard == null) worstBoard = endBoard; if (worstBoard.GetValue() > bestBoard.EnemyTurnWorseBoard.GetValue()) { bestBoard = endBoard; } else if (worstBoard.GetValue() == bestBoard.EnemyTurnWorseBoard.GetValue()) { if (endBoard.GetValue() > bestBoard.GetValue()) { bestBoard = endBoard; } } } else { if (endBoard.GetValue() > bestBoard.GetValue()) { bestBoard = endBoard; } } } } else { Log("Found early at : " + depth.ToString() + " | " + wide.ToString()); Console.WriteLine("Found Early"); break; } Log("Simulation :" + depth.ToString() + " | " + wide.ToString() + " | " + skipped.ToString()); Console.WriteLine("Simulation :" + depth.ToString() + " | " + wide.ToString() + " | " + skipped.ToString()); boards.Clear(); boards = childs; depth++; } } Action actionPrior = null; foreach (Action acc in bestBoard.ActionsStack) { if (actionPrior == null && acc.Actor != null) { if (acc.Actor.Behavior.GetPriorityPlay(bestBoard) > 1 && acc.Type != Action.ActionType.MINION_ATTACK && acc.Type != Action.ActionType.HERO_ATTACK) { Console.WriteLine("Action priori found"); if (acc.Type == Action.ActionType.CAST_MINION && acc.Actor.Behavior.ShouldBePlayed(root)) { if (root.MinionFriend.Count < 7) actionPrior = acc; } else if (acc.Actor.Behavior.ShouldBePlayed(root)) { actionPrior = acc; } } } } List<Action> finalStack = new List<Action>(); if (actionPrior != null) { finalStack.Add(actionPrior); if (bestBoard.ActionsStack.IndexOf(actionPrior) + 2 <= bestBoard.ActionsStack.Count) { if (bestBoard.ActionsStack[bestBoard.ActionsStack.IndexOf(actionPrior) + 1] != null) { if (bestBoard.ActionsStack[bestBoard.ActionsStack.IndexOf(actionPrior) + 1].Type == Action.ActionType.RESIMULATE) { finalStack.Add(new Action(Action.ActionType.RESIMULATE, null)); } } } foreach (Action a in bestBoard.ActionsStack) { if (a != actionPrior || a.Type == Action.ActionType.RESIMULATE) { if (a.Type == Action.ActionType.RESIMULATE && finalStack[finalStack.Count - 1].Type == Action.ActionType.RESIMULATE) continue; finalStack.Add(a); } } } else { finalStack = bestBoard.ActionsStack; } ActionStack = finalStack; Log(""); Log(""); Log(""); Log(""); Log("BEST BOARD FOUND"); Log(bestBoard.ToString()); Console.WriteLine("---------------------------------"); Console.WriteLine(bestBoard.ToString()); Console.WriteLine("---------------------------------"); foreach (HREngine.Bots.Action a in ActionStack) { Log(a.ToString()); Console.WriteLine(a.ToString()); } }