// 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; } }
void ExpandCore(Queue <MazeMapPosition> q, MazeMapPosition currentMapPosition, (int x, int y) redboxPosition,