Пример #1
0
        public BoardCalculator(
            ReadOnlyBlockadeState state)
        {
            this._state = state;

            this._connectedComponentLabels = new Lazy <Grid <NullableInt> >(() => ComputeConnectedComponents(state));
        }
Пример #2
0
 public double EvaluateState(ReadOnlyBlockadeState state, int player, IBlockadeHeuristic blockadeHeuristic)
 {
     return(state.IsGameOver()
                         ? (state.CurrentPlayer == player
                                 ? blockadeHeuristic.WinScore
                                 : blockadeHeuristic.LossScore)
                         : blockadeHeuristic.EvaluateState(state, player));
 }
Пример #3
0
 public double EvaluateState(ReadOnlyBlockadeState state, int player)
 {
     return(Enumerable.Range(0, state.PlayerCount)
            .Where(thisPlayer => !state.IsPlayerOut(thisPlayer))
            .Select(thisPlayer => (thisPlayer == player ? 1.0 : -1.0)
                    * (GetReachableCellScore(state, thisPlayer) * 100.0
                       + GetNeighborAversionScore(state, thisPlayer) * 1.0))
            .Sum());
 }
Пример #4
0
        public int PickMove(List <Move> moves, ReadOnlyBlockadeState state)
        {
            var tuple = this._singleLevelMoveEvaluator.PickBestMove(moves, state, new HelmutBlockadeHeuristic());

            return(tuple != null
                                ? tuple.Item1
                   // all moves kill me, so pick a random one
                                : this._random.Next(moves.Count));
        }
Пример #5
0
            public double EvaluateState(ReadOnlyBlockadeState state, int player)
            {
                var weights = new[] { 20, 15, 10 };

                return(weights.Select((weight, i) =>
                                      state.GetBoardCalculator()
                                      .GetD1Neighbors(state.GetCurrentLocationOfPlayer(player), distance: i + 1)
                                      .Sum(l => (state.GetCell(l).IsEmpty() ? 1 : -1) * weight))
                       .Sum());
            }
Пример #6
0
 public Tuple <int, double> PickBestMove(List <Move> moves, ReadOnlyBlockadeState state, IBlockadeHeuristic blockadeHeuristic)
 {
     return(moves.Select((move, i) => new { nextState = state.MakeMove(move), move, i })
            .Where(a => a.nextState.GetBoardCalculator().GetD1Neighbors(a.move.Location, distance: 1)
                   .Where(l => a.nextState.GetCell(l).IsEmpty())
                   .Any())
            .Select(a => Tuple.Create(this.EvaluateState(a.nextState, state.CurrentPlayer, blockadeHeuristic), a.i))
            .OrderByDescending(t => t)
            .Select(t => Tuple.Create(t.Item2, t.Item1))
            .FirstOrDefault());
 }
Пример #7
0
 public double GetReachableCellScore(ReadOnlyBlockadeState state, int player)
 {
     using (var step = this._myProfiler.Step("sophie evaluate state - reachable"))
     {
         // so we cant check the reachable count for the current position of the player because that space is
         // occupied, but we can check all the places they can go and get the max of that as an analog
         return(state.GetMoves(player)
                .Select(move => state.GetBoardCalculator().GetReachableCellCount(move.Location))
                .Max());
     }
 }
Пример #8
0
 public double GetNeighborAversionScore(ReadOnlyBlockadeState state, int player)
 {
     using (var step = this._myProfiler.Step("mira evaluate state - neighbor"))
     {
         var weights = new[] { 20, 15, 10 };
         return(weights.Select((weight, i) =>
                               state.GetBoardCalculator()
                               .GetD1Neighbors(state.GetCurrentLocationOfPlayer(player), distance: i + 1)
                               .Sum(l => (state.GetCell(l).IsEmpty() ? 1 : -1) * weight))
                .Sum());
     }
 }
Пример #9
0
        public Tuple <int, double> PickBestMove(List <Move> moves, ReadOnlyBlockadeState state, IBlockadeHeuristic heuristic, int levels)
        {
            if (levels == 0)
            {
                var singleLevelResult = this._singleLevelMoveEvaluator.PickBestMove(moves, state, heuristic);
                return(singleLevelResult != null
                                        ? singleLevelResult
                                        : Tuple.Create(0, heuristic.LossScore));
            }

            return(moves.Select((m, i) => Tuple.Create(i, this.TryAllOtherPlayerMoves(state.MakeMove(m), heuristic, levels, state.CurrentPlayer)))
                   .OrderByDescending(t => Tuple.Create(t.Item2, this._random.Next()))
                   .First());
        }
Пример #10
0
        // static so it can be used in a lazy
        private static Grid <NullableInt> ComputeConnectedComponents(ReadOnlyBlockadeState state)
        {
            var labels       = Grid.Create(state.Rows, state.Cols, (row, col) => new NullableInt(default(int?)));
            var currentLabel = 0;

            state.GetBoard().ForEach((location, cell) =>
            {
                if (cell.IsEmpty() && !labels[location].HasValue)
                {
                    ApplyLabel(state, labels, location, currentLabel);
                    currentLabel++;
                }
            });
            return(labels);
        }
Пример #11
0
        private static void ApplyLabel(ReadOnlyBlockadeState state, Grid <NullableInt> labels, Location location, int label)
        {
            Throw.If(labels[location].HasValue);

            labels[location] = new NullableInt(label);
            GetD1Neighbors(state, location, distance: 1)
            .ToList()
            .ForEach(newLocation =>
            {
                // not using Where() because we need to evaluate condition immediately before recursing
                if (!labels[newLocation].HasValue && state.GetCell(newLocation).IsEmpty())
                {
                    ApplyLabel(state, labels, newLocation, label);
                }
            });
        }
Пример #12
0
        // static so it can be shared with other statics
        private static IEnumerable <Location> GetD1Neighbors(ReadOnlyBlockadeState state, Location location, int distance)
        {
            if (distance == 1)
            {
                return(new[]
                {
                    Location.Create(location.Row - 1, location.Col),
                    Location.Create(location.Row + 1, location.Col),
                    Location.Create(location.Row, location.Col - 1),
                    Location.Create(location.Row, location.Col + 1)
                }.Where(l => IsLocationOnBoard(state, l)));
            }

            return(Enumerable.Range(0, distance + 1)
                   .Select(x => Tuple.Create(x, distance - x))
                   .SelectMany(t => new[] { t, Tuple.Create(-t.Item1, t.Item2), Tuple.Create(t.Item1, -t.Item2), Tuple.Create(-t.Item1, -t.Item2) })
                   .Select(delta => Location.Create(row: location.Row + delta.Item1, col: location.Col + delta.Item2))
                   .Where(l => IsLocationOnBoard(state, l))
                   .Distinct());
        }
Пример #13
0
        public int PickMove(List <Move> moves, ReadOnlyBlockadeState state)
        {
            var okayMoves = moves.Select((m, i) =>
            {
                var nextState = state.MakeMove(m);
                return(nextState.GetBoardCalculator()
                       .GetD1Neighbors(m.Location, distance: 1)
                       .Where(l => nextState.GetCell(l).IsEmpty())
                       .Any()
                                                ? i
                                                : default(int?));
            })
                            .Where(i => i.HasValue)
                            .Select(i => i.Value)
                            .ToList();

            return(okayMoves.Count > 0
                                ? okayMoves[this._random.Next(okayMoves.Count)]
                                : 0);
        }
Пример #14
0
        public double TryAllOtherPlayerMoves(ReadOnlyBlockadeState state, IBlockadeHeuristic heuristic, int levels, int myselfPlayer)
        {
            if (state.IsGameOver())
            {
                return(state.CurrentPlayer == myselfPlayer
                                        ? heuristic.WinScore
                                        : heuristic.LossScore);
            }

            if (state.CurrentPlayer == myselfPlayer)
            {
                return(this.PickBestMove(state.GetMoves().ToList(), state, heuristic, levels - 1).Item2);
            }

            return(state.GetMoves()
                   .Select(state.MakeMove)
                   .Select(newState => newState.GetCurrentLocationOfPlayer(myselfPlayer) == null
                                        ? heuristic.LossScore
                                        : newState.CurrentPlayer == myselfPlayer
                                                ? this.PickBestMove(newState.GetMoves().ToList(), newState, heuristic, levels - 1).Item2
                                                : this.TryAllOtherPlayerMoves(newState, heuristic, levels, myselfPlayer))
                   .Average());
        }
Пример #15
0
 public int PickMove(List <Move> moves, ReadOnlyBlockadeState state)
 {
     return(this._random.Next(moves.Count));
 }
Пример #16
0
        public int PickMove(List <Move> moves, ReadOnlyBlockadeState state)
        {
            var tuple = this._simpleMultiLevelEvaluator.PickBestMove(moves, state, new MiraBlockadeHeuristic(this._myProfiler), levels: 1);

            return(tuple.Item1);
        }
Пример #17
0
 public double EvaluateState(ReadOnlyBlockadeState state, int player)
 {
     return(GetReachableCellScore(state, player) * 100.0
            + GetNeighborAversionScore(state, player) * 1.0);
 }
Пример #18
0
 private static bool IsLocationOnBoard(ReadOnlyBlockadeState state, Location location)
 {
     return(location.Row >= 0 && location.Row < state.Rows &&
            location.Col >= 0 && location.Col < state.Cols);
 }