Пример #1
0
        // counts -> デバッグ用
        // true -> ゴールに到達, false -> それ以外
        void Expand(Queue <MazeMapPosition> q, out MazeMapPosition reachedGoalMapPosition, int counts)
        {
            var currentMapPosition = q.Dequeue();

            // 圧縮局面の解凍
            var expandedContent = expandMapLogic.Expand(currentMapPosition.Position);
            var expandedMap     = makeMazeMapLogic.MakeMazeMap(Frame, expandedContent);

            // 詰み判定 (黄箱が動かせる状態か?)
            //...

            // 赤箱の稼働範囲の計算
            var turningPreMovePositions = new List <((int x, int y), (int x, int y))>();
            var redboxPosition          = (x : expandedContent.RedboxPosition.Value.x * 2 + 1, y : expandedContent.RedboxPosition.Value.y * 2 + 1);

            searchMovableAreaLogic.MarkRedboxMovableArea(redboxPosition, expandedMap, turningPreMovePositions);

            // 終了条件の判定
            if (DetectReachedGoal(expandedContent, expandedMap))
            {
                reachedGoalMapPosition = currentMapPosition;
                return;
            }
            else
            {
                reachedGoalMapPosition = null;
            }

            // 局面の評価 (マニュアル)
            // 詰み (派生不可)
            if (!turningPreMovePositions.Any())
            {
                return;
            }

            // マーキングのクリア
            expandedMap = null; // GCに通知
            expandedMap = makeMazeMapLogic.MakeMazeMap(Frame, expandedContent);

            // 局面の展開
            for (var i = 0; i < turningPreMovePositions.Count; ++i)
            {
                var preMovePosition = turningPreMovePositions[i].Item1;
                var willMoveVector  = turningPreMovePositions[i].Item2;

                // 箱をマップ外に出すことを考えると少し効率化されるかも...
                var movedYellowOrGreenPosition = (x : preMovePosition.x + willMoveVector.x * 2, y : preMovePosition.y + willMoveVector.y * 2);
                if (movedYellowOrGreenPosition.x <= 0 || expandedMap.GetLength(0) <= movedYellowOrGreenPosition.x)
                {
                    continue;
                }
                if (movedYellowOrGreenPosition.y <= 0 || expandedMap.GetLength(0) <= movedYellowOrGreenPosition.y)
                {
                    continue;
                }

                // マップを元に戻すためにセーブ (赤箱の移動前/移動後・赤箱の移動に伴う黄or緑箱の移動)
                // 可読性よりも効率優先
                var mapContentMovedYellowOrGreen = expandedMap[preMovePosition.x + willMoveVector.x * 2, preMovePosition.y + willMoveVector.y * 2];
                var mapContentMovedRedbox        = expandedMap[preMovePosition.x + willMoveVector.x, preMovePosition.y + willMoveVector.y];
                var mapContentPreMoveRedbox      = expandedMap[redboxPosition.x, redboxPosition.y];

                ExpandCore(q, currentMapPosition, redboxPosition, expandedMap, preMovePosition, willMoveVector);

                // マップ (2次元配列) のコピーを行わずに,expandedMap を元に戻す
                expandedMap[redboxPosition.x, redboxPosition.y] = mapContentPreMoveRedbox;
                expandedMap[preMovePosition.x + willMoveVector.x, preMovePosition.y + willMoveVector.y]         = mapContentMovedRedbox;
                expandedMap[preMovePosition.x + willMoveVector.x * 2, preMovePosition.y + willMoveVector.y * 2] = mapContentMovedYellowOrGreen;
            }
        }
Пример #2
0
 void ExpandCore(Queue <MazeMapPosition> q, MazeMapPosition currentMapPosition, (int x, int y) redboxPosition,