/// <summary> /// Processes game rules which apply after and between player turns. /// </summary> /// <param name="state">Game state immediately after a player turn has ended.</param> /// <returns>Game over state, if a win was detected, or game state ready for next player turn</returns> public static State PrepareNextTurn(State state) { state.Flags = state.Flags.HandleKingCaptureFlag(); CheckKingCreation(ref state); BlessAnyBridges(ref state); CheckBlessedKings(ref state); ApplyCurses(ref state); if (state.Flags.IsSecondTurn()) { UnlockAllLockedPieces(ref state); } state.Flags = state.Flags.NextTurn(); if (!state.Flags.GameEnded()) { var side = state.Flags.IsRedTurn() ? ActionSide.Red : ActionSide.Blue; if (!AvailableActionController.AllActions(state, side).Any()) { state.Flags = state.Flags.IsRedTurn() ? StateFlags.BlueWin : StateFlags.RedWin; } } return(state); }
private double AlphaBetaInternal(State state, int depth, double alpha, double beta, bool maximizingPlayer, bool secondTurn, HashSet <Guid> seenStates) { if (depth == 0 || state.Flags.GameEnded()) { return(GetScore(state)); } if (maximizingPlayer) { var v = double.NegativeInfinity; foreach (var proposed in AvailableActionController.GetAvailableActions(state, seenStates).OrderByDescending(kvp => kvp.Value.Heuristic)) { v = Math.Max(v, AlphaBetaInternal(proposed.Value.Result, depth - 1, alpha, beta, secondTurn ^ maximizingPlayer, !secondTurn, seenStates)); alpha = Math.Max(alpha, v); if (alpha >= beta) { break; } } return(v); } else { var v = double.PositiveInfinity; foreach (var proposed in AvailableActionController.GetAvailableActions(state, seenStates) .OrderByDescending(kvp => kvp.Value.Heuristic)) { v = Math.Min(v, AlphaBetaInternal(proposed.Value.Result, depth - 1, alpha, beta, secondTurn ^ maximizingPlayer, !secondTurn, seenStates)); beta = Math.Min(beta, v); if (alpha >= beta) { break; } } return(v); } }