void StartShuffle() { state = PuzzleState.Shuffling; shuffleMovesRemaining = shuffleLength; emptyBlock.gameObject.SetActive(false); MakeNextShuffleMove(); }
private void HandleBlockFinishedMoving() { _blockIsMoving = false; if (CheckIfSolved()) { // Wait a few seconds and restart StartCoroutine(DisplayStartMessageAfterSeconds(3f)); } if (_state == PuzzleState.InPlay) { MakeNextPlayerMove(); } else if (_state == PuzzleState.Shuffling) { if (_shuffleMovesRemaining > 0) { MakeNextShuffleMove(); } else { _state = PuzzleState.InPlay; } } }
public BFSearch(PuzzleState baseState){ searchQueue_ = new Queue<Node>(); foundStates_ = new HashSet<PuzzleState>(); baseNode = new Node(baseState, this); }
private IEnumerator RandomShuffle() { _state = PuzzleState.Shuffling; _hiddenPiece.gameObject.SetActive(false); int x = _hiddenPiece.coordinates.x; int y = _hiddenPiece.coordinates.y; int prevX = -1; int prevY = -1; for (int i = 0; i < shuffleMoves; i++) { PuzzlePiece toSlide = GetRandomAdjecentPiece(x, y, prevX, prevY); prevX = x; prevY = y; x = toSlide.coordinates.x; y = toSlide.coordinates.y; SlidePuzzlePiece(toSlide); while (_pieceIsSliding) { yield return(null); } } _state = PuzzleState.InPlay; }
private void Awake() { state = PuzzleState.NotSolved; openPosition = new Vector3(transform.position.x, transform.position.y - transform.localScale.y, transform.position.z); }
void OnBlockFinishedMoving() { blockIsMoving = false; CheckIfSolved(); Debug.Log(shuffleMovesRemaining); switch (puzzleState) { case PuzzleState.InPlay: MakeNextBlockMove(); break; case PuzzleState.Shuffling: if (shuffleMovesRemaining > 0) { Shuffle(); } else { puzzleState = PuzzleState.InPlay; } break; case PuzzleState.Completed: break; } }
protected override string SolveIn(PuzzleState ps, int n) { var cs = (CubeState)ps; var solution = _twoSolver.SolveIn(cs.ToTwoByTwoState(), n); return(solution); }
public void TestCompactString() { var str = "abcd"; var ps = PuzzleState.FromCompactString(str); Assert.AreEqual(ps.Count, 4, "State has 4 pieces"); Assert.AreEqual(ps.numColors, 4, "State has 4 colors"); Assert.IsFalse(ps.sided, "state is sided"); var ps1 = ps.Flip(new Move(0, Side.Right)); Assert.AreEqual("dcba", ps1.ToCompactString(), "Flipped compact representation matches"); var sps = PuzzleState.FromCompactString("$abcd"); Assert.AreEqual(sps.Count, 4, "State has 4 pieces"); Assert.AreEqual(sps.numColors, 4, "State has 4 colors"); Assert.IsTrue(sps.sided, "state is sided"); var sps2 = sps.Flip(new Move(2, Side.Left)); // new expected state: CBAd Assert.AreEqual(sps2.ColorIndex(0), 2, "piece 0 has color index 2"); Assert.IsTrue(sps2.Rotated(0), "piece 0 is rotated"); Assert.AreEqual(sps2.ColorIndex(1), 1, "piece 1 has color index 1"); Assert.IsTrue(sps2.Rotated(1), "piece 1 is rotated"); Assert.AreEqual(sps2.ColorIndex(2), 0, "piece 2 has color index 0"); Assert.IsTrue(sps2.Rotated(2), "piece 2 is rotated"); Assert.AreEqual(sps2.ColorIndex(3), 3, "piece 3 has color index 3"); Assert.IsTrue(!sps2.Rotated(3), "piece 3 is NOT rotated"); Assert.AreEqual("$CBAd", sps2.ToCompactString(), "Compact string matches expected"); }
public void DoWin() { SolutionState = PuzzleState.Solved; selectable.GetRoot().GetComponent <LevelManager>().NotifyPuzzleSolved(this); TurnLightsOff(); graphicCtrl.Paint(SolutionState); }
public void Reset(int size){ foreach(GameObject c in cubes_) Destroy(c); state_ = new PuzzleState(size); cubes_ = new List<GameObject>(); short[,] nums2D = state_.NumbersMappedTo2D(); int idx = 1; for(int i = 0; i < PuzzleState.width_; i++){ for(int j = 0; j < PuzzleState.width_; j++){ if(idx++ == PuzzleState.puzzleSize_ + 1) break; Material m = (Material)Resources.Load(nums2D[i,j].ToString(), typeof(Material)); GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube); cube.renderer.material = m; cube.transform.position = new Vector3(j,-i,-1.38f); cube.transform.Rotate(new Vector3(0,0,180)); cube.AddComponent("CubeClick"); cubes_.Add(cube); } } nullPosition = new Vector3(PuzzleState.width_ - 1 , -(PuzzleState.width_ - 1), -1.38f); }
/// <summary>Runs this elimination technique over the supplied puzzle state and previously computed possible numbers.</summary> /// <param name="state">The puzzle state.</param> /// <param name="exitEarlyWhenSoleFound">Whether the method can exit early when a cell with only one possible number is found.</param> /// <param name="possibleNumbers">The previously computed possible numbers.</param> /// <param name="numberOfChanges">The number of changes made by this elimination technique.</param> /// <param name="exitedEarly">Whether the method exited early due to a cell with only one value being found.</param> /// <returns>Whether more changes may be possible based on changes made during this execution.</returns> internal override bool Execute( PuzzleState state, bool exitEarlyWhenSoleFound, FastBitArray[][] possibleNumbers, out int numberOfChanges, out bool exitedEarly) { numberOfChanges = 0; exitedEarly = false; FastBitArray [] arrays = new FastBitArray[state.GridSize]; for (int i = 0; i < state.GridSize; i++) { GetRowPossibleNumbers(possibleNumbers, i, arrays); numberOfChanges += EliminateHiddenSubsets(arrays, exitEarlyWhenSoleFound, out exitedEarly); if (exitedEarly) { return(false); } GetColumnPossibleNumbers(possibleNumbers, i, arrays); numberOfChanges += EliminateHiddenSubsets(arrays, exitEarlyWhenSoleFound, out exitedEarly); if (exitedEarly) { return(false); } GetBoxPossibleNumbers(state, possibleNumbers, i, arrays); numberOfChanges += EliminateHiddenSubsets(arrays, exitEarlyWhenSoleFound, out exitedEarly); if (exitedEarly) { return(false); } } return(numberOfChanges != 0); }
void StartShuffle() { this._state = PuzzleState.Shuffling_; this._shuffle_moves_remaining = this._shuffle_length; this._empty_block.gameObject.SetActive(false); this.MakeNextShuffleMove(); }
// 削除した部分の上のピースを落とす private void DropBlock() { currentState = PuzzleState.Wait; StartCoroutine(board.DropBlock(() => currentState = PuzzleState.MatchCheck)); board.HasMatch(); }
public void DoLoose() { SolutionState = PuzzleState.Broken; _selectable.GetRoot().GetComponent <LevelManager>().NotifyPuzzleBreakdown(this); _graphicCtrl.Paint(SolutionState); }
protected void UpdateInput(KeyboardState newKeyState) { if (newKeyState.IsKeyDown(Keys.Z) && !oldKeyState.IsKeyDown(Keys.Z)) { if (!_pieces[(int)selectorPos.X, (int)selectorPos.Y].isFilled) { _pieces[(int)selectorPos.X, (int)selectorPos.Y].Rotate(); } } if (newKeyState.IsKeyDown(Keys.Right) && !oldKeyState.IsKeyDown(Keys.Right)) { selectorPos.X++; } else if (newKeyState.IsKeyDown(Keys.Left) && !oldKeyState.IsKeyDown(Keys.Left)) { selectorPos.X--; } else if (newKeyState.IsKeyDown(Keys.Up) && !oldKeyState.IsKeyDown(Keys.Up)) { selectorPos.Y--; } else if (newKeyState.IsKeyDown(Keys.Down) && !oldKeyState.IsKeyDown(Keys.Down)) { selectorPos.Y++; } if (newKeyState.IsKeyDown(Keys.Escape)) { _state = PuzzleState.eFailed; _finished = true; } ClampSelector(); }
public void Clear() { var contentList = scrollViewContent.transform; foreach (Transform cl in contentList) { Destroy(cl.gameObject); } var dragParentList = DragParent.transform; foreach (Transform dP in dragParentList) { Destroy(dP.gameObject); } foreach (var bp in imageManager.backgroundPanels) { foreach (Transform bpImage in bp.transform) { Destroy(bpImage.gameObject); } } currentState = null; allTransparentPuzzlesList.Clear(); }
public int ComputeManhattanDistance(PuzzleState other) { if (other == null) { throw new NullReferenceException(); } int manhattanDist = 0; int[,] myLookup = new int[GridSize * GridSize, 2]; int[,] otherLookup = new int[GridSize * GridSize, 2]; for (int i = 0; i < Data.GetLength(0); i++) { for (int j = 0; j < Data.GetLength(1); j++) { myLookup[this.Data[i, j], 0] = i; myLookup[this.Data[i, j], 1] = j; otherLookup[other.Data[i, j], 0] = i; otherLookup[other.Data[i, j], 1] = j; } } // Use lookups to compare row and column differences. (ignore empty tile) for (int i = 1; i < myLookup.GetLength(0); i++) { int newDist = Math.Abs(myLookup[i, 0] - otherLookup[i, 0]) + Math.Abs(myLookup[i, 1] - otherLookup[i, 1]); manhattanDist += newDist; } return(manhattanDist); }
protected string SolveIn(PuzzleState ps, int n, string firstAxisRestriction, string lastAxisRestriction) { var cs = (CubeState)ps; if (Equals(GetSolvedState())) { return(""); } var solution = _twoPhaseSearcher.Solution(cs.ToFaceCube(), n, ThreeByThreeTimeout, 0, 0, firstAxisRestriction, lastAxisRestriction).Trim(); if ("Error 7".Equals(solution)) { return(null); } if (!solution.StartsWith("Error", StringComparison.Ordinal)) { return(solution); } // TODO - Not really sure what to do here. //l.severe(solution + " while searching for solution to " + cs.toFaceCube()); Assert(false); return(null); }
private void Update() { ChangePosition(); if (!switchers.Any()) { return; } if (switchers.Any(_ => _.IsClosed())) { if (state == PuzzleState.NotSolved) { return; } Close(); return; } if (state == PuzzleState.Solved) { return; } Open(); state = PuzzleState.Solved; }
override public List <core.Puzzle> GetPuzzlesWithState(Level level, params PuzzleSolvedState[] states) { return(QueryWithState(level.Ref, states) .Select( p => new core.Puzzle(level, PuzzleState.FromCompactString(p.InitialConfig))) .ToList()); }
/// <summary> /// ゲームの状態を更新する /// </summary> /// <param name="state">新しく更新する状態</param> private void SetState(PuzzleState state) { switch (state) { case PuzzleState.WAIT: this.GameTimer.Stop(); this.StateLabel.Text = "待機中"; break; case PuzzleState.PLAYING: this.GameTimer.Start(); this.StateLabel.Text = "ゲームプレイ中"; break; case PuzzleState.STOP: this.GameTimer.Stop(); this.StateLabel.Text = "一時停止中"; break; case PuzzleState.CLEAR: this.GameTimer.Stop(); this.StateLabel.Text = "ゲームクリア"; break; case PuzzleState.SHUFFLE: this.StateLabel.Text = "シャッフル中"; break; } this.StateLabel.ForeColor = this.StateColors[state][0]; this.StateLabel.BackColor = this.StateColors[state][1]; this.State = state; }
public void RestartOnGameScreen() { var gameSettings = ToolBox.Get <SettingsGame>(); var controller = GameObject.Find("Puzzle").GetComponent <PuzzleController>(); PuzzleState puzState = PuzzlesCreator.CreatePuzzle(gameSettings.lines, gameSettings.columns); //////// foreach (var dataItem in controller.DataPuzzleState.puzzleStates) { if (dataItem.puzzleID == controller.originalImage.sprite.name) { controller.DataPuzzleState.puzzleStates.Remove(dataItem); break; } } //// controller.Clear(); controller.DataPuzzleState.puzzleStates.Add(puzState); puzState.puzzleID = controller.originalImage.sprite.name; controller.currentState = puzState; controller.InitView(puzState.puzzleDatas); controller.UpdateProgress(); SetGamePanelsGamePositions(); }
public void ChangeState() { switch (state) { case PuzzleState.Setup: state = PuzzleState.Wait; break; case PuzzleState.Load: state = PuzzleState.Wait; break; case PuzzleState.Wait: state = PuzzleState.Touch; break; case PuzzleState.Touch: state = PuzzleState.End; break; case PuzzleState.End: state = PuzzleState.Load; break; } }
public void Init() { PuzzleClusterData.Sequence[] newSeqArr = new PuzzleClusterData.Sequence[data.Sequences.Count]; List <PuzzleClusterData.Sequence> newSeq = new List <PuzzleClusterData.Sequence>(); data.Sequences.CopyTo(newSeqArr); newSeq.AddRange(newSeqArr); while (chosenSeq.Count < data.SequencesAmount) { PuzzleClusterData.Sequence seq = newSeq[Random.Range(0, newSeq.Count)]; chosenSeq.Add(seq); newSeq.Remove(seq); } chosenColor = (ClusterColor)Random.Range(0, 4); SolutionState = PuzzleState.Unsolved; checkPressed = false; misstakes = 0; heatLvl = 0; Material[] newMaterials = Interactables.CheckLight.materials; newMaterials[1] = data.LightOffMat; Interactables.CheckLight.materials = newMaterials; SetScreens(false); graphicCtrl.Init(graphicCtrl.Data); graphicCtrl.Paint(SolutionState); }
public void NotifyShapeMovedHome() { if (_shapes.All(shape => !shape.IsInExplodedPosition)) { _state = PuzzleState.Solved; } }
void OnBlockFinishedMoving() { //add the block id to the history of pieces moved. blockIsMoving = false; CheckIfSolved(); if (state == PuzzleState.InPlay) { MakeNextPlayerMove(); } else if (state == PuzzleState.Shuffling) { if (shuffleMovesRemaining > 0) { MakeNextShuffleMove(); } else { solver.currentPos[block.id] = block.coord; state = PuzzleState.InPlay; solver.Shuffled(); CheckSurroundingBlock(); } } else if (state == PuzzleState.Solving) { CheckSurroundingBlock(); } }
public void Configure(Level.LevelType type, PuzzleState state, int index, Texture image = null) { this.type = type; if (type == Level.LevelType.sided || type == Level.LevelType.simple) { this.colorIndex = state.ColorIndex(index); mr.material = MatPool.GetMaterial(new MaterialKey { colorIndex = colorIndex, type = type }); } else { mr.material = plainMaterial; if (type == Level.LevelType.image) { mr.material.SetTexture("_MainTex", image); float vInc = (float)(1f / state.Count); float startV = vInc * state.ColorIndex(index); var mesh = GetComponent <MeshFilter>().mesh; mesh.uv = GeneratePiecesUVs(vInc, startV); mr.material.color = Color.white; } } }
public void Init() { SolutionState = PuzzleState.Unsolved; int _setupIndex = Random.Range(0, data.Setups.Count); chosenSetup = data.Setups[_setupIndex]; solutionIndex = 0; //Initializing lights foreach (PuzzleALARM_Light light in Lights) { light.Init(chosenSetup.LightPattern); } //Initializing buttons //Care: it works 'cause buttons are manually ordered for (int i = 0; i < allButtons.Count; i++) { allButtons[i].Init(this, new PuzzleALARM_inputData() { value = (InputValue)i }); } }
void CreatePuzzle() { blocks = new Block[blocksPerLine, blocksPerColumn]; // création de la liste des blocs Texture2D[,] imageSlices = ImageSlicer.GetSlices(brailleWord, blocksPerLine); //Vector3Int [,] MatriceLettre= transformationMatrice(mot_a_coder); //Texture2D [,] ImageLettre = transformationImage(mot_a_coder); for (int y = 0; y < blocksPerColumn; y++) { for (int x = 0; x < blocksPerLine; x++) { GameObject blockObject = GameObject.CreatePrimitive(PrimitiveType.Quad); // récupération d'un bloc = Quad blockObject.transform.position = new Vector2(-Vector2.one.x * (blocksPerLine - 1) * .5f + new Vector2(x, y).x, -Vector2.one.y * (blocksPerColumn - 1) * .5f + new Vector2(x, y).y); // on s'arrange pour que ça soit symétrique par rapport à la caméra blockObject.transform.parent = transform; Block block = blockObject.AddComponent <Block>(); block.OnBlockPressed += PlayerMoveBlockInput; block.OnFinishedMoving += OnBlockFinishedMoving; block.Init(new Vector2Int(x, y), imageSlices[x, y]); //block.Init(new Vector2Int(x, y), ImageLettre[x,y], MatriceLettre[x, y]); //on donne l'image (une partie découpée de l'image d'origine) au bloc blocks[x, y] = block; blockObject.tag = letterAndPos(x, y); if (y == blocksPerColumn - 1 && x == blocksPerLine - 1) { blockObject.SetActive(false); // on enlève l'image du bloc en bas à droite emptyBlock = block; } } } for (int i = 0; i < nombrePermutation; i++) // on réalise nombrePermutation permutations entre deux blocs pour mélanger le puzzle { int a = Random.Range(0, blocksPerLine); // int b = Random.Range(0, blocksPerColumn); // x int c = Random.Range(0, blocksPerLine); int d = Random.Range(0, blocksPerColumn); Vector2Int targetCoord = blocks[a, b].coord; blocks[a, b].coord = blocks[c, d].coord; blocks[c, d].coord = targetCoord; Vector2 targetPosition = blocks[a, b].transform.position; blocks[a, b].transform.position = blocks[c, d].transform.position; blocks[c, d].transform.position = targetPosition; //Vector3 targetMatriceLettre = blocks[a,b].lettre; //blocks[a, b].lettre = blocks[c, d].lettre; //blocks[c, d].lettre = targetMatriceLettre; } Camera.main.orthographicSize = Mathf.Max(blocksPerLine, blocksPerColumn) * .55f; //modification de l'image pour que ça correponde à l'écran inputs = new Queue <Block>(); state = PuzzleState.InPlay; }
// プレイヤーがピースを選択しているときの処理、入力終了を検知したらReleaseWaitに移行する private void BlockMove() { if (remainTime == 0) { ReleaseBlock(); } else { if (replay) { if (replayIdx < replayData[0].InputCount && replayData[0].InputFrame[replayIdx] == frame) { if (replayData[0].InputType[replayIdx] == (byte)InputType.Move) { // ボードの処理 Vector3 inputPos = board.GetBlockWorldPos(new Vector2(replayData[0].InputData1[replayIdx], replayData[0].InputData2[replayIdx])); Block block = board.board[replayData[0].InputData1[replayIdx], replayData[0].InputData2[replayIdx]]; board.SwitchBlock(selectedBlock, block); movingBlockObject.transform.position = inputPos + Vector3.up * 10; replayIdx++; } else if (replayData[0].InputType[replayIdx] == (byte)InputType.Release) { ReleaseBlock(); replayIdx++; } } } else { GodPhase phase = GodTouch.GetPhase(); if (phase == GodPhase.Moved) { Block block = board.GetNearestBlock(GodTouch.GetPosition()); if (block != selectedBlock) { // リプレイの処理 inputFrame.Add(frame); inputType.Add((int)InputType.Move); Vector2 pos = board.GetBlockBoardPos(block); inputData1.Add((byte)pos.x); inputData2.Add((byte)pos.y); // ボードの処理 board.SwitchBlock(selectedBlock, block); } movingBlockObject.transform.position = GodTouch.GetPosition() + Vector3.up * 10; } else if (phase == GodPhase.Ended) { ReleaseCount = 0; currentState = PuzzleState.ReleaseWait; } } } board.HasMatch(); }
/// <summary>Restores a puzzle based on the state from a serialized game.</summary> /// <param name="state">The current puzzle state.</param> /// <param name="originalState">The original puzzle state.</param> /// <param name="undoStates">The undo state stack.</param> public void RestorePuzzle( PuzzleState state, PuzzleState originalState, Stack <PuzzleState> undoStates) { OriginalState = originalState; UndoStates = undoStates; State = state; _selectedCell = FirstEmptyCell; }
/// <summary>Loads a new puzzle and sets it to be the current puzzle in the grid.</summary> /// <param name="state">The puzzle to load.</param> public void LoadNewPuzzle(PuzzleState state) { ClearUndoCheckpoints(); ClearOriginalPuzzleCheckpoint(); SetOriginalPuzzleCheckpoint(state.Clone()); State = state; _selectedCell = FirstEmptyCell; }
public float GoalDistanceEstimate(PuzzleState state) { SticksNode nodeGoal = state as SticksNode; float xd = (float)_coord.X - (float)nodeGoal._coord.X; float yd = (float)_coord.Y - (float)nodeGoal._coord.Y; return ((xd * xd) + (yd * yd)); }
// Here's the heuristic function that estimates the distance from a Node // to the Goal. public float GoalDistanceEstimate(PuzzleState state) { MapSearchNode nodeGoal = state as MapSearchNode; float xd = (float)x - (float)nodeGoal.x; float yd = (float)y - (float)nodeGoal.y; return ((xd * xd) + (yd * yd)); }
/// <summary>Runs this elimination technique over the supplied puzzle state and previously computed possible numbers.</summary> /// <param name="state">The puzzle state.</param> /// <param name="possibleNumbers">The previously computed possible numbers.</param> /// <param name="numberOfChanges">The number of changes made by this elimination technique.</param> /// <returns>Whether more changes may be possible based on changes made during this execution.</returns> internal override bool Execute( PuzzleState state, bool exitEarlyWhenSoleFound, FastBitArray[][] possibleNumbers, out int numberOfChanges, out bool exitedEarly) { numberOfChanges = 0; exitedEarly = false; // Eliminate impossible numbers based on numbers already set in the grid for (int i = 0; i < state.GridSize; i++) { for (int j = 0; j < state.GridSize; j++) { // If this cell has a value, we use it to eliminate numbers in other cells if (state[i, j].HasValue) { byte valueToEliminate = state[i, j].Value; // eliminate numbers in same row for (int y = 0; y < state.GridSize; y++) { if (possibleNumbers[i][y][valueToEliminate]) { numberOfChanges++; possibleNumbers[i][y][valueToEliminate] = false; } } // eliminate numbers in same column for (int x = 0; x < state.GridSize; x++) { if (possibleNumbers[x][j][valueToEliminate]) { numberOfChanges++; possibleNumbers[x][j][valueToEliminate] = false; } } // eliminate numbers in same box int boxStartX = (i / state.BoxSize) * state.BoxSize; for (int x = boxStartX; x < boxStartX + state.BoxSize; x++) { int boxStartY = (j / state.BoxSize) * state.BoxSize; for (int y = boxStartY; y < boxStartY + state.BoxSize; y++) { if (possibleNumbers[x][y][valueToEliminate]) { numberOfChanges++; possibleNumbers[x][y][valueToEliminate] = false; } } } } } } return false; }
public bool IsGoal(PuzzleState puzzleState) { MapSearchNode nodeGoal = puzzleState as MapSearchNode; if (nodeGoal == null) return false; if ((x == nodeGoal.x) && (y == nodeGoal.y)) { return true; } return false; }
public PuzzleState(int size){ puzzleSize_ = (short)size; width_ = (short)Mathf.Sqrt(puzzleSize_ + 1); numbers_ = new short[puzzleSize_ + 1]; //set up the puzzle grid for(int i = 0; i < puzzleSize_; i++){ numbers_[i] = (short)(i + 1); } numbers_[puzzleSize_] = -1; terminalState_ = new PuzzleState(this); }
public bool GetSuccessors(AStarSearch astarsearch, PuzzleState parentState) { SticksNode parent_node = parentState as SticksNode; Coordinate pcoord = parent_node == null ? new Coordinate(-1,-1) : parent_node._coord; Coordinate ncoord; // push each possible move except allowing the search to go backwards int[] xx = { 0, 1, 1, 0, -1, -1 }; int[] yy = { 1, 0, -1, -1, 0, 1 }; for (int i = 0; i < xx.Length; i++) { ncoord = _coord.Xform(xx[i], yy[i]); if (pcoord != ncoord && _map.ContainsKey(ncoord) && GetCost(ncoord) < 9) { astarsearch.AddSuccessor(new SticksNode(_map, ncoord, _unit)); } } return true; }
/// <summary>Restores a puzzle based on the state from a serialized game.</summary> /// <param name="state">The current puzzle state.</param> /// <param name="originalState">The original puzzle state.</param> /// <param name="undoStates">The undo state stack.</param> public void RestorePuzzle( PuzzleState state, PuzzleState originalState, Stack<PuzzleState> undoStates) { OriginalState = originalState; UndoStates = undoStates; State = state; _selectedCell = FirstEmptyCell; }
/// <summary>Creates a checkpoint used to determine where cells are invalid in the puzzle.</summary> public void SetOriginalPuzzleCheckpoint(PuzzleState original) { _originalState = original; if (original != null) { SolverOptions options = new SolverOptions(); options.MaximumSolutionsToFind = 2; SolverResults results = Solver.Solve(original, options); if (results.Status == PuzzleStatus.Solved && results.Puzzles.Count == 1) { _solvedOriginalState = results.Puzzle; } else _solvedOriginalState = null; } }
public bool Equals(PuzzleState rhs) { SticksNode n = rhs as SticksNode; if (n == null) return false; return n._coord == _coord; }
public float GetCost(PuzzleState successor) { SticksNode node = successor as SticksNode; if (node == null) return 9; return GetCost(node._coord); }
public bool IsGoal(PuzzleState puzzleState) { SticksNode nodeGoal = puzzleState as SticksNode; if (nodeGoal == null) return false; return _coord == nodeGoal._coord; }
/// <summary>Runs this elimination technique over the supplied puzzle state and previously computed possible numbers.</summary> /// <param name="state">The puzzle state.</param> /// <param name="exitEarlyWhenSoleFound">Whether the method can exit early when a cell with only one possible number is found.</param> /// <param name="possibleNumbers">The previously computed possible numbers.</param> /// <param name="numberOfChanges">The number of changes made by this elimination technique.</param> /// <param name="exitedEarly">Whether the method exited early due to a cell with only one value being found.</param> /// <returns>Whether more changes may be possible based on changes made during this execution.</returns> internal override bool Execute( PuzzleState state, bool exitEarlyWhenSoleFound, FastBitArray[][] possibleNumbers, out int numberOfChanges, out bool exitedEarly) { numberOfChanges = 0; exitedEarly = false; byte gridSize = state.GridSize; byte boxSize = state.BoxSize; // For each number that can exist in the puzzle (0-8, etc.) for (byte n = 0; n < gridSize; n++) { // For each row, if number only exists as a possibility in one cell, set it. for (byte x = 0; x < gridSize; x++) { int? seenIndex = null; for (byte y = 0; y < gridSize; y++) { if (possibleNumbers[x][y][n]) { // If this is the first time we're seeing the number, remember // where we're seeing it if (!seenIndex.HasValue) seenIndex = y; // We've seen this number before, so move on else { seenIndex = null; break; } } } if (seenIndex.HasValue && possibleNumbers[x][seenIndex.Value].CountSet > 1) { possibleNumbers[x][seenIndex.Value].SetAll(false); possibleNumbers[x][seenIndex.Value][n] = true; numberOfChanges++; if (exitEarlyWhenSoleFound) { exitedEarly = true; return false; } } } // For each column, if number only exists as a possibility in one cell, set it. // Same basic logic as above. for (byte y = 0; y < gridSize; y++) { int? seenIndex = null; for (byte x = 0; x < gridSize; x++) { if (possibleNumbers[x][y][n]) { if (!seenIndex.HasValue) seenIndex = x; else { seenIndex = null; break; } } } if (seenIndex.HasValue && possibleNumbers[seenIndex.Value][y].CountSet > 1) { possibleNumbers[seenIndex.Value][y].SetAll(false); possibleNumbers[seenIndex.Value][y][n] = true; numberOfChanges++; if (exitEarlyWhenSoleFound) { exitedEarly = true; return false; } } } // For each grid, if number only exists as a possibility in one cell, set it. // Same basic logic as above. for (byte gridNum = 0; gridNum < gridSize; gridNum++) { byte gridX = (byte)(gridNum % boxSize); byte gridY = (byte)(gridNum / boxSize); byte startX = (byte)(gridX * boxSize); byte startY = (byte)(gridY * boxSize); bool canEliminate = true; Point? seenIndex = null; for (byte x = startX; x < startX + boxSize && canEliminate; x++) { for (byte y = startY; y < startY + boxSize; y++) { if (possibleNumbers[x][y][n]) { if (!seenIndex.HasValue) seenIndex = new Point(x, y); else { canEliminate = false; seenIndex = null; break; } } } } if (seenIndex.HasValue && canEliminate && possibleNumbers[seenIndex.Value.X][seenIndex.Value.Y].CountSet > 1) { possibleNumbers[seenIndex.Value.X][seenIndex.Value.Y].SetAll(false); possibleNumbers[seenIndex.Value.X][seenIndex.Value.Y][n] = true; numberOfChanges++; if (exitEarlyWhenSoleFound) { exitedEarly = true; return false; } } } } return numberOfChanges != 0; }
// Class constructor public Puzzle() { currentPuzzle = this; state = PuzzleState.Doing; }
public bool Equals(PuzzleState prhs) { MapSearchNode rhs = prhs as MapSearchNode; // same state in a maze search is simply when (x,y) are the same if ((x == rhs.x) && (y == rhs.y)) { return true; } else { return false; } }
// given this node, what does it cost to move to successor. In the case // of our map the answer is the map terrain value at this node since that is // conceptually where we're moving public float GetCost(PuzzleState successor) { return (float)GetMap(x, y); }
public void SwapPiece(Move piece){ if(!state_.GetMoveablePieces().Contains(piece)){ Debug.Log ("this shouldnt happen...!"); return; } Vector3 p = cubes_[(int)piece.value_ - 1].transform.position; cubes_[(int)piece.value_ - 1].transform.position = nullPosition; nullPosition = p; state_ = state_.Move(piece); Debug.Log (AStarHeuristic.GetNumberOutOfPlaceHeuristic(state_)); }
// Update is called once per frame void Update() { MouseUpdate(); mNowState = mPuzCon.SelfUpdate(mNowState, mMouseData); }
/*! パズル部分の更新 @param nowState 現在の遷移 @param mouseData マウスの入力データ @param PuzzleState 遷移を返す */ public PuzzleState SelfUpdate(PuzzleState nowState, MouseData mouseData) { switch (nowState) { case PuzzleState.NONE: break; // ピース選択 case PuzzleState.SELECT: if (mTouchCon.SelectUpdate(mouseData)) nowState++; break; // ピース移動 case PuzzleState.MOVE: if (mTouchCon.MoveUpdate(mouseData)) nowState = PuzzleState.JUDGE; break; // 消すかどうか判定 case PuzzleState.JUDGE: // 何もそろってなければセレクトへ if(mJudgeCon.AllJudge() != null) nowState = PuzzleState.DEATH; else nowState = PuzzleState.SELECT; break; // 揃っているピースを消す case PuzzleState.DEATH: if (DeathUpdate()) { DownProcess(); nowState = PuzzleState.DOWN; } break; // 隙間を埋めるためにピースを落とす case PuzzleState.DOWN: if(mActivList.Count == 0 && mDeathList.Count == 0) nowState = PuzzleState.JUDGE; break; } // 各ピースの更新 PieceUpdate(); return nowState; }
/// <summary>Loads a new puzzle and sets it to be the current puzzle in the grid.</summary> /// <param name="state">The puzzle to load.</param> public void LoadNewPuzzle(PuzzleState state) { ClearUndoCheckpoints(); ClearOriginalPuzzleCheckpoint(); SetOriginalPuzzleCheckpoint(state.Clone()); State = state; _selectedCell = FirstEmptyCell; }
/// <summary>Clears the original puzzle checkpoint.</summary> public void ClearOriginalPuzzleCheckpoint() { _originalState = null; _solvedOriginalState = null; }
public PuzzleState(PuzzleState copy){ numbers_ = (short[])copy.numbers_.Clone(); }
/// <summary>Runs this elimination technique over the supplied puzzle state and previously computed possible numbers.</summary> /// <param name="state">The puzzle state.</param> /// <param name="possibleNumbers">The previously computed possible numbers.</param> /// <param name="numberOfChanges">The number of changes made by this elimination technique.</param> /// <returns>Whether more changes may be possible based on changes made during this execution.</returns> internal override bool Execute( PuzzleState state, bool exitEarlyWhenSoleFound, FastBitArray[][] possibleNumbers, out int numberOfChanges, out bool exitedEarly) { numberOfChanges = 0; exitedEarly = false; // Check each row to see if it contains the start of an xwing for(int row=0; row<state.GridSize; row++) { int count = 0; // used to find the two first-row members of the x-wing int [] foundColumns = new int[2]; // used to store the two first-row members of the x-wing // We'll be checking all numbers to see whether they're in an x-wing for(int n=0; n<state.GridSize; n++) { // Now look at every column in the row, and find the occurrences of the number. // For it to be a valid x-wing, it must have two and only two of the given number as a possibility. for(int column=0; column<state.GridSize; column++) { if (possibleNumbers[row][column][n] || (state[row,column].HasValue && state[row,column].Value == n)) { count++; if (count <= foundColumns.Length) foundColumns[count-1] = column; else break; } } // Assuming we found a row that has two and only two cells with the number as a possibility if (count == 2) { // Look for another row that has the same property for(int subRow=row+1; subRow<state.GridSize; subRow++) { bool validXwingFound = true; for(int subColumn=0; subColumn<state.GridSize && validXwingFound; subColumn++) { bool isMatchingColumn = (subColumn == foundColumns[0] || subColumn == foundColumns[1]); bool hasPossibleNumber = possibleNumbers[subRow][subColumn][n] || (state[subRow,subColumn].HasValue && state[subRow,subColumn].Value == n); if ((hasPossibleNumber && !isMatchingColumn) || (!hasPossibleNumber && isMatchingColumn)) validXwingFound = false; } // If another row is found that has two and only two cells with the number // as a possibility, and if those two cells are in the same two columns // as the original row, woo hoo, we've got an x-wing, and we can eliminate // that number from every other cell in the columns containing the numbers. if (validXwingFound) { for(int elimRow=0; elimRow<state.GridSize; elimRow++) { if (elimRow != row && elimRow != subRow) { for(int locationNum=0; locationNum<2; locationNum++) { if (possibleNumbers[elimRow][foundColumns[locationNum]][n]) { possibleNumbers[elimRow][foundColumns[locationNum]][n] = false; numberOfChanges++; if (exitEarlyWhenSoleFound && possibleNumbers[elimRow][foundColumns[locationNum]].CountSet == 1) { exitedEarly = true; return false; } } } } } break; } } } } } return numberOfChanges != 0; }
static bool Fit(PuzzleState startPuzzle ,Dictionary<ulong,List<RootState>> allRoots ,Dictionary<ulong,PuzzleState> nextPuzzles ,int number ,int number2 ,int i1 ,int i2 ,int i3 ,int i4 ,int i5 ,int i6 , ulong keepOutMask ) { bool[] keepOutMap = InitKeepOutMap(keepOutMask); int n1, n2, n3, n4 ; List<int> root = new List<int>(); PuzzleState tempPuzzle = startPuzzle; //Console.WriteLine("Call Fit! {0:D},{1:D}", number, number2); //startPuzzle.Print(); //Console.WriteLine("{0:X}", keepOutMask); do { //Console.WriteLine("} head of fit"); //tempPuzzle.Print(); n1 = tempPuzzle.NumberOf(i1); n2 = tempPuzzle.NumberOf(i2); n3 = tempPuzzle.NumberOf(i3); n4 = tempPuzzle.NumberOf(i4); if (n1 == number) { if (n2 == number2) { //Fin // 1 2 // ? ? if (allRoots.ContainsKey(tempPuzzle.data) == false) { allRoots[tempPuzzle.data] = new List<RootState>(); } allRoots[tempPuzzle.data].Add(new RootState(tempPuzzle.data, startPuzzle.data, root)); nextPuzzles[tempPuzzle.data] = tempPuzzle; return true; }else if (n3 == number2) { //NG // 1 ? // 2 ? //number2 to n5 tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, i5, root); }else if (n4 == number2) { if (n2 == 0) { //OK // 1 0 // ? 2 //number2 to n2 tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, i2, root); }else{ //NG // 1 ? // ? 2 //number2 to n6 tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, i6, root); } }else{ // 1 ? // ? ? //number to n2 tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i2, root); } }else if (n2 == number) { if (n1 == number2) { //NG // 2 1 // ? ? //number2 to n5 tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, i5, root); }else if (n3 == number2) { if (n1 == 0) { //NG // 0 1 // 2 ? //number2 to n6 tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, i6, root); }else{ //OK // ? 1 // 2 ? //number2 to n4 tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, i4, root); } }else if (n4 == number2) { //OK // ? 1 // ? 2 //lock number2 on n4 //number to n1 keepOutMap[i4] = true; tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i1, root); keepOutMap[i4] = false; }else{ // ? 1 x // ? ? y int ix = i2 + (i2 - i1); int iy = ix + (i3 - i1); //Console.WriteLine("ix={0:D} iy={1:D}", ix, iy); bool innerFlag = true; if (ix < 16 && (ix & 3) > (i2 & 3)) { if (tempPuzzle.NumberOf(ix) == 0 && iy < 16) { if (tempPuzzle.NumberOf(iy) == number2) { // ? 1 0 // ? ? 2 tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, ix, root); innerFlag = false; } }else if (tempPuzzle.NumberOf(ix) == number2) { // ? 1 2 // ? ? tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i1, root); if ( tempPuzzle != null ){ tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, i2, root); } innerFlag = false; } } if (innerFlag) { // lock number on n2 //number2 to n4 keepOutMap[i2] = true; tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, i4, root); keepOutMap[i2] = false; } } }else if (n3 == number) { if (n1 == number2) { //OK // 2 ? // 1 ? //lock number on n3 //number2 to n2 keepOutMap[i3] = true; tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, i2, root); keepOutMap[i3] = false; }else if( n2 == number2) { if (n1 == 0) { //OK // 0 2 // 1 ? //number to n1 tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i1, root); }else{ //NG // ? 2 // 1 ? //number to n5 tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i5, root); } }else if( n4 == number2) { if (n1 == 0) { //NG // 0 ? // 1 2 // number2 to n6 tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, i6, root); }else if (n2 == 0) { //NG // ? 0 // 1 2 // number to n5 tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i5, root); }else{ //OK // ? ? // 1 2 // number to n5 tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i5, root); } }else{ // ? ? // 1 ? //number to n2 tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i2, root); } }else if (n4 == number) { if (n1 == number2) { if (n2 == 0 ){ //NG // 2 0 // ? 1 //number to n5 tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i5, root); }else{ //OK // 2 ? // ? 1 //number to n3 tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i3, root); } }else if (n2 == number2) { //NG // ? 2 // ? 1 //number to n6 tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i6, root); }else if (n3 == number2) { if( n1 == 0 ){ //OK // 0 ? // 2 1 //number2 to n1 tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, i1, root); }else if (n2 == 0) { //OK // ? 0 // 2 1 //number to n2 tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i2, root); }else{ //NG // ? ? // 2 1 //number2 to n1 tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, i1, root); } }else{ // ? ? // ? 1 //number to n2 tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i2, root); } }else{ if( n1 == number2) { // 2 ? // ? ? //lock number2 on n1 //number to n3 keepOutMap[i1] = true; tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i3, root); keepOutMap[i1] = false; }else if( n2 == number2 || n3 == number2 || n4 == number2) { // ? 2 // ? ? //number2 to n1 // ? ? // 2 ? //number2 to n1 // ? ? // ? 2 //number2 to n1 tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number2, i1, root); }else{ //near number to each pos tempPuzzle = MoveNumber(tempPuzzle, keepOutMap, number, i2, root); } } } while ( tempPuzzle != null); #if DEBUG Console.WriteLine("unknown error?"); Filter f1 = new Filter(keepOutMask); f1.Print(); startPuzzle.Print(); #endif return false; }
public PuzzleState Move(Move m){ //copy the current state of the grid PuzzleState ret = new PuzzleState(this); //update the state ret.numbers_[GetNullCoord()] = m.value_; ret.numbers_[(int)m.idx_] = -1; return ret; }
// Use this for initialization void Start() { mNowState = PuzzleState.SELECT; mPuzCon = GameObject.Find("PuzzleController").GetComponent<PuzzleController>(); }
public static int Main() { PuzzleState problem; #if DEBUG #if MAKE_BY_RANDOM problem = new PuzzleState().Shuffle(1000); #else problem = new PuzzleState(new int[,]{{1, 6, 2, 4}, {9, 10, 3, 7}, {12, 15, 14, 11}, {0, 13, 5, 8}}); #endif problem.Print(); #else problem = InputPuzzle(); #endif Dictionary<ulong, List<RootState>> allRoots = new Dictionary<ulong, List<RootState>>(); Dictionary<ulong, PuzzleState> currentPuzzles = new Dictionary<ulong, PuzzleState>(); Dictionary<ulong, PuzzleState> nextPuzzles = new Dictionary<ulong, PuzzleState>(); Dictionary<ulong, PuzzleState> tempSwapPuzzles; allRoots[problem.data] = new List<RootState>(); allRoots[problem.data].Add(new RootState(problem.data, 0UL, null)); currentPuzzles[problem.data] = problem; while (currentPuzzles.Count > 0) { nextPuzzles.Clear(); #if DEBUG Console.WriteLine("puzzles: {0:D}", currentPuzzles.Count); #endif foreach (PuzzleState puzzle in currentPuzzles.Values) { if (filter0x0.Match(puzzle)) { continue; } MakeAllMovables(puzzle); if (CheckAllMovableRoot(puzzle, filter0x0, allRoots, nextPuzzles)) { continue; } if (CheckAllMovableRoot(puzzle, filter2x2, allRoots, nextPuzzles)) { continue; } if (filter2x2.Match(puzzle)) { //2x2 // 1 2 3 4 // 5 6 7 8 // 9 10 ? ? //13 14 ? ? Console.WriteLine("maybe not come here"); continue; } if (filter2x4.Match(puzzle)) { // 1 2 ? ? // 5 6 ? ? // 9 10 ? ? //13 14 ? ? if (filter2x3.Match(puzzle)) { // 1 2 3 4 // 5 6 ? ? // 9 10 ? ? //13 14 ? ? SearchAll(puzzle, filter2x2, allRoots, nextPuzzles, filter2x3.mask, 16); continue; } if (SearchAll(puzzle, filter2x3, allRoots, nextPuzzles, filter2x4.mask, 14) == false) { // + manual search FitHz(puzzle, allRoots, nextPuzzles, 3, filter2x4.mask); } } else if (filter4x2.Match(puzzle)) { // 1 2 3 4 // 5 6 7 8 // ? ? ? ? // ? ? ? ? if (filter3x2.Match(puzzle)) { // 1 2 3 4 // 5 6 7 8 // 9 ? ? ? //13 ? ? ? SearchAll(puzzle, filter2x2, allRoots, nextPuzzles, filter3x2.mask, 16); continue; } if (SearchAll(puzzle, filter2x3, allRoots, nextPuzzles, filter4x2.mask, 14) == false) { // + manual search FitVt(puzzle, allRoots, nextPuzzles, 9, filter4x2.mask); } } else if (filter3x3.Match(puzzle)) { // 1 2 3 4 // 5 ? ? ? // 9 ? ? ? //13 ? ? ? CheckAllMovableRoot(puzzle, filter2x3, allRoots, nextPuzzles); CheckAllMovableRoot(puzzle, filter3x2, allRoots, nextPuzzles); if (filter3x3m1LT.Match(puzzle)) { // 1 2 3 4 // 5 6 ? ? // 9 ? ? ? //13 ? ? ? // + manual search FitHz(puzzle, allRoots, nextPuzzles, 7, filter3x3m1LT.mask); FitVt(puzzle, allRoots, nextPuzzles, 10, filter3x3m1LT.mask); continue; } if (filter3x3m1RT.Match(puzzle)) { // 1 2 3 4 // 5 ? ? 8 // 9 ? ? ? //13 ? ? ? // + manual search FitHz(puzzle, allRoots, nextPuzzles, 6, filter3x3m1RT.mask); continue; } if (filter3x3m1LB.Match(puzzle)) { // 1 2 3 4 // 5 ? ? ? // 9 ? ? ? //13 14 ? ? // + manual search FitVt(puzzle, allRoots, nextPuzzles, 6, filter3x3m1LB.mask); continue; } // + manual search FitHz(puzzle, allRoots, nextPuzzles, 7, filter3x3.mask); FitVt(puzzle, allRoots, nextPuzzles, 10, filter3x3.mask); FitHz(puzzle, allRoots, nextPuzzles, 6, filter3x3.mask); FitVt(puzzle, allRoots, nextPuzzles, 6, filter3x3.mask); }else if (filter3x4.Match(puzzle)) { // 1 ? ? ? // 5 ? ? ? // 9 ? ? ? //13 ? ? ? if (filter3x4m2LT.Match(puzzle)) { // 1 2 ? ? // 5 6 ? ? // 9 ? ? ? //13 ? ? ? if (CheckAllMovableRoot(puzzle, filter3x3m1LT, allRoots, nextPuzzles) == false) { FitHz(puzzle, allRoots, nextPuzzles, 3, filter3x4m2LT.mask); } if (CheckAllMovableRoot(puzzle, filter2x4, allRoots, nextPuzzles) == false) { FitVt(puzzle, allRoots, nextPuzzles, 10, filter3x4m2LT.mask); } continue; } if (filter3x4m2LB.Match(puzzle)) { // 1 ? ? ? // 5 ? ? ? // 9 10 ? ? //13 14 ? ? if (CheckAllMovableRoot(puzzle, filter2x4, allRoots, nextPuzzles) == false) { FitVt(puzzle, allRoots, nextPuzzles, 2, filter3x4m2LB.mask); } continue; } if (filter3x4m2RT.Match(puzzle)) { // 1 ? ? 4 // 5 ? ? 8 // 9 ? ? ? //13 ? ? ? CheckAllMovableRoot(puzzle, filter3x3, allRoots, nextPuzzles); if (CheckAllMovableRoot(puzzle, filter3x3m1RT, allRoots, nextPuzzles) == false) { FitHz(puzzle, allRoots, nextPuzzles, 2, filter3x4m2RT.mask); } continue; } if (filter3x4m1LT.Match(puzzle)) { // 1 2 ? ? // 5 ? ? ? // 9 ? ? ? //13 ? ? ? if (CheckAllMovableRoot(puzzle, filter3x3, allRoots, nextPuzzles) == false) { FitHz(puzzle, allRoots, nextPuzzles, 3, filter3x4m1LT.mask); } if (CheckAllMovableRoot(puzzle, filter2x4, allRoots, nextPuzzles) == false) { CheckAllMovableRoot(puzzle, filter3x4m2LT, allRoots, nextPuzzles); CheckAllMovableRoot(puzzle, filter3x4m2LB, allRoots, nextPuzzles); } FitVt(puzzle, allRoots, nextPuzzles, 2, filter3x4.mask); FitVt(puzzle, allRoots, nextPuzzles, 10, filter3x4.mask); continue; } if (filter3x4m1RT.Match(puzzle)) { // 1 ? ? 4 // 5 ? ? ? // 9 ? ? ? //13 ? ? ? if (CheckAllMovableRoot(puzzle, filter3x3, allRoots, nextPuzzles) == false) { FitHz(puzzle, allRoots, nextPuzzles, 2, filter3x4m1RT.mask); } if (CheckAllMovableRoot(puzzle, filter3x4m2LT, allRoots, nextPuzzles) == false) { FitVt(puzzle, allRoots, nextPuzzles, 2, filter3x4.mask); } if (CheckAllMovableRoot(puzzle, filter3x4m2RT, allRoots, nextPuzzles) == false) { FitVt(puzzle, allRoots, nextPuzzles, 10, filter3x4.mask); } FitHz(puzzle, allRoots, nextPuzzles, 2, filter3x4.mask); continue; } if (filter3x4m1LB.Match(puzzle)) { // 1 ? ? ? // 5 ? ? ? // 9 ? ? ? //13 14 ? ? if (CheckAllMovableRoot(puzzle, filter2x4, allRoots, nextPuzzles) == false) { if (CheckAllMovableRoot(puzzle, filter3x4m2LB, allRoots, nextPuzzles) == false) { FitVt(puzzle, allRoots, nextPuzzles, 2, filter3x4.mask); } if ( CheckAllMovableRoot(puzzle, filter3x4m2LT, allRoots, nextPuzzles) == false) { FitVt(puzzle, allRoots, nextPuzzles, 10, filter3x4.mask); } } continue; } CheckAllMovableRoot(puzzle, filter3x3, allRoots, nextPuzzles); if (CheckAllMovableRoot(puzzle, filter3x4m2RT, allRoots, nextPuzzles) == false) { FitVtRv(puzzle, allRoots, nextPuzzles, 4, filter3x4.mask); } if (CheckAllMovableRoot(puzzle, filter2x4, allRoots, nextPuzzles) == false) { if (CheckAllMovableRoot(puzzle, filter3x4m2LT, allRoots, nextPuzzles) == false) { FitVt(puzzle, allRoots, nextPuzzles, 2, filter3x4.mask); } if (CheckAllMovableRoot(puzzle, filter3x4m2LB, allRoots, nextPuzzles) == false) { FitVt(puzzle, allRoots, nextPuzzles, 10, filter3x4.mask); } } }else if (filter4x3.Match(puzzle) ){ // 1 2 3 4 // ? ? ? ? // ? ? ? ? // ? ? ? ? if( filter4x3m2LT.Match(puzzle) ){ // 1 2 3 4 // 5 6 ? ? // ? ? ? ? // ? ? ? ? if (CheckAllMovableRoot(puzzle, filter4x2, allRoots, nextPuzzles) == false) { FitHz(puzzle, allRoots, nextPuzzles, 7, filter4x3m2LT.mask); } if (CheckAllMovableRoot(puzzle, filter3x3m1LT, allRoots, nextPuzzles) == false) { if( CheckAllMovableRoot(puzzle, filter3x3, allRoots, nextPuzzles) == false) { FitVt(puzzle, allRoots, nextPuzzles, 9, filter4x3m2LT.mask); } } continue; } if (filter4x3m2RT.Match(puzzle)) { // 1 2 3 4 // ? ? 7 8 // ? ? ? ? // ? ? ? ? if( CheckAllMovableRoot(puzzle, filter4x2, allRoots, nextPuzzles) == false) { FitHz(puzzle, allRoots, nextPuzzles, 5, filter4x3m2RT.mask); } continue; } if (filter4x3m2LB.Match(puzzle)) { // 1 2 3 4 // ? ? ? ? // ? ? ? ? //13 14 ? ? if( CheckAllMovableRoot(puzzle, filter2x3, allRoots, nextPuzzles) == false) { if( CheckAllMovableRoot(puzzle, filter3x3m1LB, allRoots, nextPuzzles) == false) { if( CheckAllMovableRoot(puzzle, filter3x3, allRoots, nextPuzzles) == false){ FitVt(puzzle, allRoots, nextPuzzles, 5, filter4x3m2LB.mask); } } } continue; } if( filter4x3m1LT.Match(puzzle) ){ // 1 2 3 4 // 5 ? ? ? // ? ? ? ? // ? ? ? ? if( CheckAllMovableRoot(puzzle, filter4x2, allRoots, nextPuzzles) == false){ CheckAllMovableRoot(puzzle, filter4x3m2LT, allRoots, nextPuzzles); } CheckAllMovableRoot(puzzle, filter3x3, allRoots, nextPuzzles); FitVt(puzzle, allRoots, nextPuzzles, 9, filter4x3m1LT.mask); continue; } if( filter4x3m1RT.Match(puzzle) ){ // 1 2 3 4 // ? ? ? 8 // ? ? ? ? // ? ? ? ? if( CheckAllMovableRoot(puzzle, filter4x2, allRoots, nextPuzzles) == false){ CheckAllMovableRoot(puzzle, filter4x3m2LT, allRoots, nextPuzzles); CheckAllMovableRoot(puzzle, filter4x3m2RT, allRoots, nextPuzzles); } FitHz(puzzle, allRoots, nextPuzzles, 5, filter4x3.mask); FitHz(puzzle, allRoots, nextPuzzles, 7, filter4x3.mask); continue; } if( filter4x3m1LB.Match(puzzle) ){ // 1 2 3 4 // ? ? ? ? // ? ? ? ? //13 ? ? ? CheckAllMovableRoot(puzzle, filter3x3, allRoots, nextPuzzles); FitVt(puzzle, allRoots, nextPuzzles, 5, filter4x3m1LB.mask); continue; } if( CheckAllMovableRoot(puzzle, filter4x2, allRoots, nextPuzzles) == false){ CheckAllMovableRoot(puzzle, filter4x3m2LT, allRoots, nextPuzzles); CheckAllMovableRoot(puzzle, filter4x3m2RT, allRoots, nextPuzzles); } CheckAllMovableRoot(puzzle, filter3x3, allRoots, nextPuzzles); //+ manual search FitHz(puzzle, allRoots, nextPuzzles, 5, filter4x3.mask); FitHz(puzzle, allRoots, nextPuzzles, 7, filter4x3.mask); FitHzRv(puzzle, allRoots, nextPuzzles, 13, filter4x3.mask); }else if (filterBxLT.Match(puzzle)) { // 1 2 ? ? // 5 6 ? ? // ? ? ? ? // ? ? ? ? if (CheckAllMovableRoot(puzzle, filter3x3m1LT, allRoots, nextPuzzles) == false) { CheckAllMovableRoot(puzzle, filter3x3, allRoots, nextPuzzles); } if( CheckAllMovableRoot(puzzle, filter2x4, allRoots, nextPuzzles) == false) { if( CheckAllMovableRoot(puzzle, filter3x4m2LT, allRoots, nextPuzzles) == false) { if( CheckAllMovableRoot(puzzle, filter3x4m1LT, allRoots, nextPuzzles) == false) { CheckAllMovableRoot(puzzle, filter3x4, allRoots, nextPuzzles); } } } if( CheckAllMovableRoot(puzzle, filter4x2, allRoots, nextPuzzles) == false) { if( CheckAllMovableRoot(puzzle, filter4x3m2LT, allRoots, nextPuzzles) ){ if (CheckAllMovableRoot(puzzle, filter4x3m1LT, allRoots, nextPuzzles) == false) { CheckAllMovableRoot(puzzle, filter4x3, allRoots, nextPuzzles); } } } FitHz(puzzle, allRoots, nextPuzzles, 3, filterBxLT.mask); FitVt(puzzle, allRoots, nextPuzzles, 9, filterBxLT.mask); }else if( filterBxRT.Match(puzzle) ){ // ? ? 3 4 // ? ? 7 8 // ? ? ? ? // ? ? ? ? if( CheckAllMovableRoot(puzzle, filter4x2, allRoots, nextPuzzles) == false) { if( CheckAllMovableRoot(puzzle, filter4x3m2RT, allRoots, nextPuzzles) == false) { if( CheckAllMovableRoot(puzzle, filter4x3m1RT, allRoots, nextPuzzles) == false) { CheckAllMovableRoot(puzzle, filter4x3, allRoots, nextPuzzles); } } } FitHz(puzzle, allRoots, nextPuzzles, 1, filterBxRT.mask); }else if( filterBxLB.Match(puzzle) ){ // ? ? ? ? // ? ? ? ? // 9 10 ? ? //13 14 ? ? if (CheckAllMovableRoot(puzzle, filter2x4, allRoots, nextPuzzles) == false) { if( CheckAllMovableRoot(puzzle, filter3x4m2LB, allRoots, nextPuzzles) == false) { if( CheckAllMovableRoot(puzzle, filter3x4m1LB, allRoots, nextPuzzles) == false) { CheckAllMovableRoot(puzzle, filter3x4, allRoots, nextPuzzles); } } } FitVt(puzzle, allRoots, nextPuzzles, 1, filterBxLB.mask); }else if( filter2VtTT.Match(puzzle) ){ // 1 ? ? 4 // 5 ? ? 8 // ? ? ? ? // ? ? ? ? if (CheckAllMovableRoot(puzzle, filter4x2, allRoots, nextPuzzles) == false) { if( CheckAllMovableRoot(puzzle, filter4x3m2LT, allRoots, nextPuzzles) == false) { CheckAllMovableRoot(puzzle, filter4x3m1LT, allRoots, nextPuzzles); } if (CheckAllMovableRoot(puzzle, filter4x3m2RT, allRoots, nextPuzzles) == false) { CheckAllMovableRoot(puzzle, filter4x3m1RT, allRoots, nextPuzzles); } FitHz(puzzle, allRoots, nextPuzzles, 2, filter2VtTT.mask); } if ( CheckAllMovableRoot(puzzle, filter3x4, allRoots, nextPuzzles) == false) { FitVt(puzzle, allRoots, nextPuzzles, 9, filterVtLT.mask); } }else if( filter2VtBT.Match(puzzle)) { // ? ? ? 4 // ? ? ? 8 // 9 ? ? ? //13 ? ? ? if( CheckAllMovableRoot(puzzle, filter3x4, allRoots, nextPuzzles) == false) { FitVt(puzzle, allRoots, nextPuzzles, 1, filterVtLB.mask); } if (CheckAllMovableRoot(puzzle, filterBxLB, allRoots, nextPuzzles) == false) { FitVt(puzzle, allRoots, nextPuzzles, 10, filterVtLB.mask); } if (CheckAllMovableRoot(puzzle, filterBxRT, allRoots, nextPuzzles) == false) { FitVtRv(puzzle, allRoots, nextPuzzles, 3, filterVtRT.mask); } }else if( filter2HzRL.Match(puzzle) ){ // ? ? 3 4 // ? ? ? ? // ? ? ? ? //13 14 ? ? if (CheckAllMovableRoot(puzzle, filter4x3, allRoots, nextPuzzles) == false) { FitHz(puzzle, allRoots, nextPuzzles, 1, filterHzRT.mask); } if (CheckAllMovableRoot(puzzle, filterBxLB, allRoots, nextPuzzles) == false) { FitHzRv(puzzle, allRoots, nextPuzzles, 9, filterHzLB.mask); } if (CheckAllMovableRoot(puzzle, filterBxRT, allRoots, nextPuzzles) == false) { FitHz(puzzle, allRoots, nextPuzzles, 7, filterHzRT.mask); } }else if (filter2HzLL.Match(puzzle) ){ // 1 2 ? ? // ? ? ? ? // ? ? ? ? //13 14 ? ? if( CheckAllMovableRoot(puzzle, filter2x4, allRoots, nextPuzzles) == false) { CheckAllMovableRoot(puzzle, filter3x4m1LT, allRoots, nextPuzzles); CheckAllMovableRoot(puzzle, filter3x4m1LB, allRoots, nextPuzzles); if (CheckAllMovableRoot(puzzle, filter3x4, allRoots, nextPuzzles) == false) { FitVt(puzzle, allRoots, nextPuzzles, 5, filter2HzLL.mask); FitHz(puzzle, allRoots, nextPuzzles, 3, filter2HzLL.mask); } } CheckAllMovableRoot(puzzle, filterBxLT, allRoots, nextPuzzles); CheckAllMovableRoot(puzzle, filterBxLB, allRoots, nextPuzzles); }else{ if (filter1.Match(puzzle)) { if (filterVtLT.Match(puzzle)) { // 1 ? ? ? // 5 ? ? ? // ? ? ? ? // ? ? ? ? if( CheckAllMovableRoot(puzzle, filterBxLT, allRoots, nextPuzzles) == false) { FitVt(puzzle, allRoots, nextPuzzles, 2, filterVtLT.mask); } if (CheckAllMovableRoot(puzzle, filter3x4, allRoots, nextPuzzles) == false) { FitVt(puzzle, allRoots, nextPuzzles, 9, filterVtLT.mask); } if (CheckAllMovableRoot(puzzle, filter2VtTT, allRoots, nextPuzzles) == false) { FitVtRv(puzzle, allRoots, nextPuzzles, 4, filterVtLT.mask); } continue; } if (filterHzLT.Match(puzzle)) { // 1 2 ? ? // ? ? ? ? // ? ? ? ? // ? ? ? ? if( CheckAllMovableRoot(puzzle, filterBxLT, allRoots, nextPuzzles) == false) { FitHz(puzzle, allRoots, nextPuzzles, 5, filterHzLT.mask); } if( CheckAllMovableRoot(puzzle, filter4x3, allRoots, nextPuzzles) == false) { FitHz(puzzle, allRoots, nextPuzzles, 3, filterHzLT.mask); } if( CheckAllMovableRoot(puzzle, filter2HzLL, allRoots, nextPuzzles) == false) { FitHzRv(puzzle, allRoots, nextPuzzles, 13, filterHzLT.mask); } continue; } } if (filter4.Match(puzzle) ){ if (filterVtRT.Match(puzzle) ){ // ? ? ? 4 // ? ? ? 8 // ? ? ? ? // ? ? ? ? if( CheckAllMovableRoot(puzzle, filterBxRT, allRoots, nextPuzzles) == false) { FitVtRv(puzzle, allRoots, nextPuzzles, 3, filterVtRT.mask); } if (CheckAllMovableRoot(puzzle, filter2VtBT, allRoots, nextPuzzles) == false) { FitVt(puzzle, allRoots, nextPuzzles, 9, filterVtRT.mask); } if (CheckAllMovableRoot(puzzle, filter2VtTT, allRoots, nextPuzzles) == false) { FitVt(puzzle, allRoots, nextPuzzles, 1, filterVtRT.mask); } continue; } if( filterHzRT.Match(puzzle) ){ // ? ? 3 4 // ? ? ? ? // ? ? ? ? // ? ? ? ? if( CheckAllMovableRoot(puzzle, filterBxRT, allRoots, nextPuzzles) == false) { FitHz(puzzle, allRoots, nextPuzzles, 7, filterHzRT.mask); } if( CheckAllMovableRoot(puzzle, filter4x3, allRoots, nextPuzzles) == false) { FitHz(puzzle, allRoots, nextPuzzles, 1, filterHzRT.mask); } if (CheckAllMovableRoot(puzzle, filter2HzRL, allRoots, nextPuzzles) == false) { FitHzRv(puzzle, allRoots, nextPuzzles, 13, filterHzRT.mask); } continue; } } if( filter13.Match(puzzle) ){ if( filterHzLB.Match(puzzle) ){ // ? ? ? ? // ? ? ? ? // ? ? ? ? //13 14 ? ? if( CheckAllMovableRoot(puzzle, filterBxLB, allRoots, nextPuzzles) == false) { FitHzRv(puzzle, allRoots, nextPuzzles, 9, filterHzLB.mask); } if (CheckAllMovableRoot(puzzle, filter2HzLL, allRoots, nextPuzzles) == false) { FitHz(puzzle, allRoots, nextPuzzles, 1, filterHzLB.mask); } if (CheckAllMovableRoot(puzzle, filter2HzRL, allRoots, nextPuzzles) == false) { FitHz(puzzle, allRoots, nextPuzzles, 3, filterHzLB.mask); } continue; } if( filterVtLB.Match(puzzle) ){ // ? ? ? ? // ? ? ? ? // 9 ? ? ? //13 ? ? ? if( CheckAllMovableRoot(puzzle, filterBxLB, allRoots, nextPuzzles) == false) { FitVt(puzzle, allRoots, nextPuzzles, 10, filterVtLB.mask); } if (CheckAllMovableRoot(puzzle, filter3x4, allRoots, nextPuzzles) == false) { FitVt(puzzle, allRoots, nextPuzzles, 1, filterVtLB.mask); } if (CheckAllMovableRoot(puzzle, filter2VtBT, allRoots, nextPuzzles) == false) { FitVtRv(puzzle, allRoots, nextPuzzles, 4, filterVtLB.mask); } continue; } } if( CheckAllMovableRoot(puzzle, filterHzLT, allRoots, nextPuzzles) == false) { FitHz(puzzle, allRoots, nextPuzzles, 1); } if (CheckAllMovableRoot(puzzle, filterVtLT, allRoots, nextPuzzles) == false) { FitVt(puzzle, allRoots, nextPuzzles, 1); } if (CheckAllMovableRoot(puzzle, filterHzRT, allRoots, nextPuzzles) == false) { FitHz(puzzle, allRoots, nextPuzzles, 3); } if (CheckAllMovableRoot(puzzle, filterHzLB, allRoots, nextPuzzles) == false) { FitHzRv(puzzle, allRoots, nextPuzzles, 13); } if (CheckAllMovableRoot(puzzle, filterVtRT, allRoots, nextPuzzles) == false) { FitVtRv(puzzle, allRoots, nextPuzzles, 4); } if (CheckAllMovableRoot(puzzle, filterVtLB, allRoots, nextPuzzles) == false) { FitVt(puzzle, allRoots, nextPuzzles, 9); } } } tempSwapPuzzles = currentPuzzles; currentPuzzles = nextPuzzles; nextPuzzles = tempSwapPuzzles; } Dictionary<ulong, List<int>> currentRoots = new Dictionary<ulong, List<int>>(); Dictionary<ulong, List<int>> nextRoots = new Dictionary<ulong, List<int>>(); Dictionary<ulong, List<int>> tempSwapRoots ; List<int> minRoot = null; currentRoots[filter0x0.value] = new List<int>(); while (currentRoots.Count > 0) { nextRoots.Clear(); foreach (ulong data in currentRoots.Keys) { if ( allRoots.ContainsKey(data) == false) { Console.WriteLine("what?"); continue; } List<RootState> tempRoots = allRoots[data]; foreach (RootState state in tempRoots) { List<int> tempList; if (state.parent == 0UL) { tempList = currentRoots[data]; #if DEBUG Console.WriteLine("Root: {0:D}", tempList.Count); #endif if (minRoot == null) { minRoot = tempList; }else if (tempList.Count < minRoot.Count) { minRoot = tempList; } }else{ tempList = new List<int>(state.root); tempList.AddRange(currentRoots[data]); if (nextRoots.ContainsKey(state.parent)) { if (tempList.Count < nextRoots[state.parent].Count) { nextRoots[state.parent] = tempList; } }else{ nextRoots.Add(state.parent, tempList); } } } } tempSwapRoots = currentRoots; currentRoots = nextRoots; nextRoots = tempSwapRoots; } #if DEBUG PuzzleState checker = problem; #endif if (minRoot != null) { foreach (int j in minRoot) { Console.WriteLine(j); #if DEBUG checker = checker.MoveNumber((ulong)j); //checker.Print(); #endif } }else{ Console.WriteLine("Error"); } #if DEBUG if (minRoot != null) { Console.WriteLine("Step {0:D}", minRoot.Count); } if (filter0x0.Match(checker)) { Console.WriteLine("SUCCESS"); }else{ Console.WriteLine("FAILURE"); checker.Print(); } #endif return 0; }
// This generates the successors to the given Node. It uses a helper function called // AddSuccessor to give the successors to the AStar class. The A* specific initialisation // is done for each node internally, so here you just set the state information that // is specific to the application public bool GetSuccessors(AStarSearch astarsearch, PuzzleState parentState) { MapSearchNode parent_node = parentState as MapSearchNode; int parent_x = -1; int parent_y = -1; if (parent_node != null) { parent_x = (int)parent_node.x; parent_y = (int)parent_node.y; } MapSearchNode NewNode; // push each possible move except allowing the search to go backwards if ((GetMap(x - 1, y) < 9) && !((parent_x == x - 1) && (parent_y == y)) ) { NewNode = new MapSearchNode(x - 1, y); astarsearch.AddSuccessor(NewNode); } if ((GetMap(x, y - 1) < 9) && !((parent_x == x) && (parent_y == y - 1)) ) { NewNode = new MapSearchNode(x, y - 1); astarsearch.AddSuccessor(NewNode); } if ((GetMap(x + 1, y) < 9) && !((parent_x == x + 1) && (parent_y == y)) ) { NewNode = new MapSearchNode(x + 1, y); astarsearch.AddSuccessor(NewNode); } if ((GetMap(x, y + 1) < 9) && !((parent_x == x) && (parent_y == y + 1)) ) { NewNode = new MapSearchNode(x, y + 1); astarsearch.AddSuccessor(NewNode); } return true; }
static bool CheckAllMovableRoot(PuzzleState startPuzzle, Filter goalFilter , Dictionary<ulong, List<RootState>> allRoots, Dictionary<ulong, PuzzleState> nextPuzzles) { if (amv_allMovable.ContainsKey(goalFilter.value) == false) { return false; } PuzzleState puzzle = new PuzzleState(amv_allMovable[goalFilter.value]); Stack<int> stackRootNumbers = new Stack<int>(); ulong tempData = puzzle.data; ulong tempData2 = amv_rootData[tempData]; List<int> root = new List<int>(); while (tempData2 != 0UL) { stackRootNumbers.Push((int)PuzzleState.GetDifferenceOneNumber(tempData, tempData2)); tempData = tempData2; tempData2 = amv_rootData[tempData]; } while (stackRootNumbers.Count > 0) { root.Add(stackRootNumbers.Pop()); } if (allRoots.ContainsKey(puzzle.data) == false) { allRoots[puzzle.data] = new List<RootState>(); } allRoots[puzzle.data].Add(new RootState(puzzle.data, startPuzzle.data, root)); nextPuzzles[puzzle.data] = puzzle; return true; }