C# 有一个盒子的Sokoban游戏

C# 有一个盒子的Sokoban游戏,c#,C#,我正在进行一个学校项目,目标是创建一个sokoban解算器。sokoban游戏只有一个盒子。然而,对于大多数级别,它只是工作良好,但有两个级别,它生成了错误的答案,我不明白为什么。我将把下面的代码和两个级别,它不能正确解决 using System.Collections.Generic; using System.Linq; using System.Text; using System; using System.Diagnostics; namespace Koelkasttry {

我正在进行一个学校项目,目标是创建一个sokoban解算器。sokoban游戏只有一个盒子。然而,对于大多数级别,它只是工作良好,但有两个级别,它生成了错误的答案,我不明白为什么。我将把下面的代码和两个级别,它不能正确解决

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System;
using System.Diagnostics;

namespace Koelkasttry
{
    class Program
    {
        private int playerX, playerY, BoxX, BoxY, goalX, goalY, nCols;
        uint destBoard, currBoard;
        private string Playboard;

        Program(string[] board)
        {
            nCols = board[0].Length;
            StringBuilder playboard = new StringBuilder();

            for (int r = 0; r < board.Length; r++)
            {
                for (int c = 0; c < nCols; c++)
                {
                    char ch = board[r][c];

                    playboard.Append(ch != '?' && ch != '!' && ch != '+' ? ch : '.');

                    if (ch == '!')
                    {
                        this.BoxX = c;
                        this.BoxY = r;
                    }

                    if (ch == '?')
                    {
                        this.goalX = c;
                        this.goalY = r;
                    }

                    if (ch == '+')
                    {
                        this.playerX = c;
                        this.playerY = r;
                    }
                }
            }

            destBoard = (uint)goalY + ((uint)goalX << 8);
            currBoard = (uint)BoxY+((uint)BoxX << 8)+((uint)playerY << 16)+((uint)playerX << 24);

            Playboard = playboard.ToString();
        }

        private class Board
        {
            public uint Cur { get; internal set; }
            public string Sol { get; internal set; }
            public int X { get; internal set; }
            public int Y { get; internal set; }

            public Board(uint cur, string sol, int x, int y)
            {
                Cur = cur;
                Sol = sol;
                X = x;
                Y = y;
            }
        }

        //------------------------
        static void Main()
        {
            string readLine = Console.ReadLine();
            string[] splitLine = readLine.Split(" ".ToCharArray(),    StringSplitOptions.RemoveEmptyEntries);

            int x = 0;
            string temp = "";
            string[] level = new string[int.Parse(splitLine[1])];

            while (x < int.Parse(splitLine[1]))
            {
                temp += Console.ReadLine();
                x++;
            }

            int o = 0;

            for (int i = 0; i < int.Parse(splitLine[1]); i++)
            {
                string m = "";

                for (int c = 0; c < int.Parse(splitLine[0]); c++)
                {
                    m += temp[o];
                    o++;
                }

                level[i] = m;
            }

            string solved = new Program(level).Solve();

            if ("L".CompareTo(splitLine[2]) == 0 && solved != "No solution")
            {
                Console.WriteLine(solved.Length);
            }
            else if ("P".CompareTo(splitLine[2]) == 0 && solved != "No solution")
            {
                Console.WriteLine(solved.Length);
                Console.WriteLine(solved);
            }
            else
            {
                Console.WriteLine(solved);
            }
        }

        //-------
        private string Solve()
        {
            char[,] dirLabels = { { 'N', 'N' }, { 'E', 'E' }, { 'S', 'S' }, { 'W', 'W' } };
            int[,] dirs = { { 0, -1 }, { 1, 0 }, { 0, 1 }, { -1, 0 } };

            ISet<uint> history = new HashSet<uint>();
            LinkedList<Board> open = new LinkedList<Board>();
            List<string> solution = new List<string>();

            open.AddLast(new Board(currBoard, string.Empty, playerX, playerY));

            history.Add(currBoard);


            while (!open.Count.Equals(0))
            {
                Board item = open.First();
                open.RemoveFirst();
                uint cur = item.Cur;
                string sol = item.Sol;
                int x = item.X;
                int y = item.Y;

                for (int i = 0; i < dirs.GetLength(0); i++)
                {
                    uint trial = cur;
                    int dx = dirs[i, 0];
                    int dy = dirs[i, 1];

                    // are we standing next to a box ?
                    if (comparing(trial & 65535, x + dx, y + dy))
                    {
                        // can we push it ?
                        if ((trial = Push(x, y, dx, dy)) != 0)
                        {
                            // or did we already try this one ?
                            if (!history.Contains(trial))
                            {

                                string newSol = sol + dirLabels[i, 1];

                                if (IsSolved(trial & 65535))
                                    return newSol;

                                open.AddLast(new Board(trial, newSol, x + dx, y + dy));
                                history.Add(trial);
                            }
                        }
                        // otherwise try changing position
                    }
                    else if ((trial = Move(x, y, dx, dy, trial)) != 0)
                    {
                        if (!history.Contains(trial))
                        {
                            string newSol = sol + dirLabels[i, 0];
                            open.AddLast(new Board(trial, newSol, x + dx, y + dy));
                            history.Add(trial);
                        }
                    }
                }
            }
            return "No solution";
        }

        private bool comparing(uint trail, int x, int y)
        {
            uint a = trail, b = 0, c = 0;

            b = (a >> 8);

            for (int i = 8; i < 16; i++)
            {
                trail &= (uint)~(1 << i);
            }

            c = trail;
            //   Console.Write(x + " " + y + " " + b + " " + c);
            //  Console.WriteLine();

            if (b == x && c == y)
            {



             //   Console.WriteLine(true);
                return (true);
            }


            return (false);
        }

        private uint Move(int x, int y, int dx, int dy, uint trialBoard)
        {
            int newPlayerPos = (y + dy) * nCols + x + dx;

            if (Playboard[newPlayerPos] != '.')
                return 0;

            for (int i = 16; i < 32; i++)
            {
                trialBoard &= (uint)~(1 << i);
            }

            trialBoard += ((uint)(x + dx) << 24) + ((uint)(y + dy) << 18);

            return trialBoard;
        }

        private uint Push(int x, int y, int dx, int dy)
        {
            int newBoxPos = (y + 2 * dy) * nCols + x + 2 * dx;

            if (Playboard[newBoxPos] != '.')
                return 0;

            uint a = ((uint)(x + dx) << 24) + ((uint)(y + dy) << 16) + ((uint)(x + 2 * dx) << 8) + ((uint)(y + 2 * dy));

            return a;
        }

        private bool IsSolved(uint trialBoard)
        {
            if (trialBoard == destBoard)
                return true;

            return false;
        }
    }
}

你的目标是什么:Winforms、WPF、ASP。。?您应该始终正确标记您的问题,以便人们可以在问题页面上看到它!你的目标是什么:Winforms、WPF、ASP。。?您应该始终正确标记您的问题,以便人们可以在问题页面上看到它!
12 12 P
MMMMMMMMMMMM
M...MMMM...M
M...MMMM...M
M..........M
MMM.MMMM.MMM
MMM.MMMM.MMM
MMM.MMMM.MMM
MMM.MMMM.MMM
M..!..M..+?M
M...M...MMMM
M...MMMMMMMM
MMMMMMMMMMMM

solution: 
 68
WWSWWNWWSWWNESENNNNNNWNNESWSEEEEEENEESWNWSSSSSNNNNWWWWWSSSSSEESEENEE



example 2:
18 9 P
MMMMMMMMMMMMMMMMMM
M?MMMMMMMMMMMMMMMM
M+MMMMMMMMMMMMMMMM
M!...............M
M.MMMMMMMMMMMMMM.M
M................M
M.M.MMMMMMMMMMMMMM
M...MMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMM

solution: 
 14
SSSEESSWWNNNNN