private Score SimulateLeaf(GameState state) { while (!state.IsGameFinished()) { GameSimulator.Simulate(state, true); if (state.Turn >= 100) { break; } } return(state.CalculateScore()); }
public Node(GameState state) { State = state; for (int i = 0; i < 20; i++) { GameState simState = new GameState(State); while (!simState.IsGameFinished()) { GameSimulator.Simulate(simState, true); } _result.Wins += simState.GetResult() ? 1 : 0; _result.Games++; } }
public void Expand() { _visitCount++; if (_expanded) { Node bestChild = null; double bestUtc = 0; foreach (Node child in Children.Values) { if (child.State.Self == null) { continue; } double uct = child.Result.WinRate + SQRT_TWO * Math.Sqrt(Math.Log(_visitCount) / child._visitCount); if (uct > bestUtc) { bestChild = child; bestUtc = uct; } } bestChild?.Expand(); return; } foreach (MoveType move in State.GetPossibleMoves()) { GameState nextGameState = new GameState(State); nextGameState.ApplyRequestedAction(MoveTypeToRequestedAction(move)); GameSimulator.Simulate(nextGameState, false); Children.Add(move, new Node(nextGameState)); } _expanded = true; }
private (RequestedActions, Score) SimulateBranch(int remainingDepth, GameState state) { if (state.IsGameFinished()) { return(null, state.CalculateScore()); } Score bestScore = Score.MinValue(); RequestedActions bestAction = null; if (state.IsPosWalkable(state.Self.Position + new Vector2Int(1, 0))) { GameState newState = new GameState(state); newState.Self.Position += new Vector2Int(1, 0); GameSimulator.Simulate(newState, false); Score score; if (remainingDepth > 0) { score = SimulateBranch(remainingDepth - 1, newState).Item2; } else { score = SimulateLeaf(newState); } if (score >= bestScore) { bestScore = score; bestAction = new RequestedActions { Move = new Vector2Int(1, 0) }; } } if (state.IsPosWalkable(state.Self.Position + new Vector2Int(-1, 0))) { GameState newState = new GameState(state); newState.Self.Position += new Vector2Int(-1, 0); GameSimulator.Simulate(newState, false); Score score; if (remainingDepth > 0) { score = SimulateBranch(remainingDepth - 1, newState).Item2; } else { score = SimulateLeaf(newState); } if (score >= bestScore) { bestScore = score; bestAction = new RequestedActions { Move = new Vector2Int(-1, 0) }; } } if (state.IsPosWalkable(state.Self.Position + new Vector2Int(0, 1))) { GameState newState = new GameState(state); newState.Self.Position += new Vector2Int(0, 1); GameSimulator.Simulate(newState, false); Score score; if (remainingDepth > 0) { score = SimulateBranch(remainingDepth - 1, newState).Item2; } else { score = SimulateLeaf(newState); } if (score >= bestScore) { bestScore = score; bestAction = new RequestedActions { Move = new Vector2Int(0, 1) }; } } if (state.IsPosWalkable(state.Self.Position + new Vector2Int(0, -1))) { GameState newState = new GameState(state); newState.Self.Position += new Vector2Int(0, -1); GameSimulator.Simulate(newState, false); Score score; if (remainingDepth > 0) { score = SimulateBranch(remainingDepth - 1, newState).Item2; } else { score = SimulateLeaf(newState); } if (score >= bestScore) { bestScore = score; bestAction = new RequestedActions { Move = new Vector2Int(0, -1) }; } } { GameState newState = new GameState(state); GameSimulator.Simulate(newState, false); Score score; if (remainingDepth > 0) { score = SimulateBranch(remainingDepth - 1, newState).Item2; } else { score = SimulateLeaf(newState); } if (score >= bestScore) { bestScore = score; bestAction = new RequestedActions(); } } if (state.Self.Bomb == null) { GameState newState = new GameState(state) { Self = { Bomb = new BombState(state.Self.BombFuze, state.Self.BombRadius, state.Self.Position) } }; GameSimulator.Simulate(newState, false); Score score; if (remainingDepth > 0) { score = SimulateBranch(remainingDepth - 1, newState).Item2; } else { score = SimulateLeaf(newState); } if (score >= bestScore) { bestScore = score; bestAction = new RequestedActions { DropBomb = true }; } } return(bestAction, bestScore); }