Exemplo n.º 1
0
        public static List <string> PlanB(State state, bool debug, Func <StateMetadata, bool> terminatingCondition)
        {
            string moves = "WASD";
            var    transpositionTable = new HashSet <Point>()
            {
                state.Position
            };
            var priorityQueue = new PriorityQueue <StateMetadata>((rhs, lhs) =>
                                                                  lhs.Depth == rhs.Depth ? CompareMetadata(lhs, rhs) : lhs.Depth < rhs.Depth);

            var initialState = new StateMetadata()
            {
                State = state
            };

            priorityQueue.Push(initialState);

            while (!priorityQueue.IsEmpty())
            {
                var currentMetadata = priorityQueue.Pop();
                var currentBoard    = currentMetadata.State.Board;
                var currentPosition = currentMetadata.State.Position;

                if (terminatingCondition(currentMetadata))
                {
                    return(currentMetadata.ToList().Select(i => i.Move).ToList());
                }

                foreach (var move in moves)
                {
                    var newState = currentMetadata.State.Move(move);

                    if (newState != null)
                    {
                        var newMetadata = new StateMetadata()
                        {
                            State         = newState.Item1,
                            Depth         = currentMetadata.Depth + 1,
                            Move          = move.ToString(),
                            PreviousState = currentMetadata
                        };

                        newMetadata.State.Board.Undo(newState.Item2);

                        if (!transpositionTable.Contains(newState.Item1.Position))
                        {
                            priorityQueue.Push(newMetadata);
                            transpositionTable.Add(newMetadata.State.Position);
                        }
                    }
                }
            }

            return(null);
        }
Exemplo n.º 2
0
        private static bool CompareMetadata(StateMetadata lhs, StateMetadata rhs)
        {
            foreach (var metric in GetMetrics(lhs).Zip(GetMetrics(rhs), (l, r) => l - r))
            {
                if (metric != 0)
                {
                    return(metric < 0);
                }
            }

            return(false);
        }
Exemplo n.º 3
0
        public static List <string> PlanA(State state, bool debug)
        {
            var           middle   = new Point(state.Board.MaxX / 2, state.Board.MaxY / 2);
            string        moves    = "FWASDQE";
            StateMetadata bestMove = null;

            var metadata = new StateMetadata()
            {
                State = state, Redo = new BoardUndo(), Debug = state.Board.Clone()
            };

            var transpositionTable = new Dictionary <object, StateMetadata>()
            {
                { state.GetHashTuple(), metadata }
            };
            var priorityQueue = new PriorityQueue <StateMetadata>((rhs, lhs) =>
                                                                  lhs.Depth == rhs.Depth ? CompareMetadata(lhs, rhs) : lhs.Depth < rhs.Depth);

            priorityQueue.Push(metadata);

            while (!priorityQueue.IsEmpty())
            {
                var currentMetadata = priorityQueue.Pop();

                if (bestMove != null && bestMove.State.UnpaintedCount == 0 ||
                    currentMetadata.Depth >= MaxDepth)
                {
                    if (bestMove.State.UnpaintedCount == state.UnpaintedCount)
                    {
                        return(null);
                    }

                    return(bestMove.ToList().Select(i => i.Move).ToList());
                }

                var undoBase = currentMetadata.State.Board.Redo(currentMetadata.Redo);
                //currentMetadata.State.Board.Compare(currentMetadata.Debug);

                foreach (var move in moves.Where(m => currentMetadata.Depth == 0 || m != 'F' && m != 'L'))
                {
                    var afterMove = currentMetadata.State.Move(move);

                    if (afterMove != null)
                    {
                        var newState = afterMove.Item1;
                        var undoMove = afterMove.Item2;

                        var newPoints = undoMove == null ? 0 : undoMove.Points.Sum(p => 1 + GetWallCount(state.Board, p.Item1));

                        var newMetadata = new StateMetadata()
                        {
                            Score         = currentMetadata.Score + newPoints,
                            State         = newState,
                            Depth         = currentMetadata.Depth + 1,
                            Move          = move.ToString(),
                            PreviousState = currentMetadata
                        };

                        var isBetterMove = bestMove == null || CompareMetadata(newMetadata, bestMove);
                        if (isBetterMove)
                        {
                            bestMove = newMetadata;
                        }

                        if (debug)
                        {
                            var betterMoveString = isBetterMove ? " *" : "";
                            if (isBetterMove)
                            {
                                Console.WriteLine($"{newMetadata}{betterMoveString}");
                            }
                        }

                        if (!transpositionTable.ContainsKey(newState.GetHashTuple()))
                        {
                            //newMetadata.Debug = state.Board.Clone();
                            newMetadata.Redo = new BoardUndo();
                            newMetadata.Redo.Points.AddRange(currentMetadata.Redo.Points);
                            newMetadata.Redo.Points.AddRange(state.Board.GetRedo(undoMove).Points);
                            priorityQueue.Push(newMetadata);
                            transpositionTable[newMetadata.State] = null;
                        }

                        currentMetadata.State.Board.Undo(undoMove);
                    }
                }

                currentMetadata.State.Board.Undo(undoBase);
            }

            throw new Exception("No moves found");
        }
Exemplo n.º 4
0
        // Heuristics:
        //    Maximize boosts collected.
        //    Maximize score unpainted squares.
        //
        private static IEnumerable <int> GetMetrics(StateMetadata metadata)
        {
            yield return(-metadata.State.BoostsCollected);

            yield return(-metadata.Score);
        }