public GameBlockWrapper(IGameBlock gameBlock) { this.gameBlock = gameBlock; if (this.gameBlock is GameBlockPlayer) { this.blockType = GameBoard.GameBlockType.Player; } else if (this.gameBlock is GameBlockNormal) { this.blockType = GameBoard.GameBlockType.Normal; } else if (this.gameBlock is GameBlockChangeDirection) { this.blockType = GameBoard.GameBlockType.ChangeDirection; } else if (this.gameBlock is GameBlockExtraMove) { this.blockType = GameBoard.GameBlockType.ExtraMove; } else if (this.gameBlock is GameBlockMultipleMoves) { this.blockType = GameBoard.GameBlockType.MultipleMoves; } else { this.blockType = GameBoard.GameBlockType.Null; } }
public GameBlockWrapper(IGameBlock gameBlock) { this.gameBlock = gameBlock; if (this.gameBlock is GameBlockPlayer) { this.blockType = GameBoard.GameBlockType.Player; } else if (this.gameBlock is GameBlockNormal) { this.blockType = GameBoard.GameBlockType.Normal; } else if (this.gameBlock is GameBlockChangeDirection) { this.blockType = GameBoard.GameBlockType.ChangeDirection; } else if (this.gameBlock is GameBlockExtraMove) { this.blockType = GameBoard.GameBlockType.ExtraMove; } else if (this.gameBlock is GameBlockMultipleMoves) { this.blockType = GameBoard.GameBlockType.MultipleMoves; } else { this.blockType = GameBoard.GameBlockType.Null; } }
public abstract bool ApplyReverseMoveForLoop( IGameBlockDestination destinationBlock, MovementDirection directionInReverse, int numberOfBlocksToMove, out BlockMovement move, IGameBlock previousBlock, IGameBlockDestination previousDestination, Queue <IGameBlock> blockHistory);
/// <summary> /// Отрисовка следующего блока /// </summary> private void DisplayFallingBlock(IGameBlock fallingBlock) { if (fallingBlock == null) { return; } _gameGrid[fallingBlock.Left.Row, fallingBlock.Left.Column].SetColor(fallingBlock.Left.Color); _gameGrid[fallingBlock.Right.Row, fallingBlock.Right.Column].SetColor(fallingBlock.Right.Color); }
/// <summary> /// 交换两个方块的位置 /// </summary> /// <param name="coordinateA"></param> /// <param name="coordinateB"></param> private void SwapBlock(BlockCoordinate coordinateA, BlockCoordinate coordinateB) { IGameBlock T = this[coordinateA]; this[coordinateA] = this[coordinateB]; this[coordinateA].Coordinate = coordinateA; this[coordinateB] = T; this[coordinateB].Coordinate = coordinateB; }
public override void Copy(IGameBlock source) { GameBlockNormal gameBlockNormal = source as GameBlockNormal; if (gameBlockNormal != null) { this.isAvailable = gameBlockNormal.isAvailable; } }
public override void Copy(IGameBlock source) { GameBlockPlayer gameBlockPlayer = source as GameBlockPlayer; if (gameBlockPlayer != null) { this.availableMoves = gameBlockPlayer.availableMoves; } }
public override void Copy(IGameBlock source) { GameBlockMultipleMoves gameBlockMultipleMoves = source as GameBlockMultipleMoves; if (gameBlockMultipleMoves != null) { this.numberOfMovesApplied = gameBlockMultipleMoves.numberOfMovesApplied; this.numberOfMovesNeeded = gameBlockMultipleMoves.numberOfMovesNeeded; } }
public override bool ApplyReverseMoveForLoop( IGameBlockDestination destinationBlock, MovementDirection directionInReverse, int numberOfBlocksToMove, out BlockMovement move, IGameBlock previousBlock, IGameBlockDestination previousDestination, Queue <IGameBlock> blockHistory) { move = null; return(false); }
private void InitBlocks() { GameBlockStart = (Instantiate(BlockStartPrefab, new Vector3(0, 0, 0), Quaternion.identity)).GetComponent <IGameBlock>(); GameBlockStart.GetGameObject().SetActive(false); GameBlockEnd = (Instantiate(BlockEndPrefab, new Vector3(0, 0, 0), Quaternion.identity)).GetComponent <IGameBlock>(); GameBlockEnd.GetGameObject().SetActive(false); for (int i = 0; i < 10; i++) { GameBlockList.Add((Instantiate(Block1Prefab, new Vector3(0, 0, 0), Quaternion.identity)).GetComponent <IGameBlock>()); GameBlockList.Add((Instantiate(Block2Prefab, new Vector3(0, 0, 0), Quaternion.identity)).GetComponent <IGameBlock>()); GameBlockList.Add((Instantiate(Block3Prefab, new Vector3(0, 0, 0), Quaternion.identity)).GetComponent <IGameBlock>()); } foreach (IGameBlock t in GameBlockList) { t.GetGameObject().SetActive(false); } }
public object Clone() { GameBoard clone = new GameBoard(); clone.gameBlocks = new IGameBlock[this.gameBlocks.GetLength(0), this.gameBlocks.GetLength(1)]; foreach (IGameBlock gameBlock in this.gameBlocks) { if (gameBlock != null) { IGameBlock block = (IGameBlock)gameBlock.Clone(); block.GameBoard = clone; } } return(clone); }
/// <summary> /// Here the GameBlocks are given to the system to work with. The order it is given is the order it will activate them. /// </summary> /// <param name="gameInstance">The Game Linked to this system</param> /// <param name="buildingBlocks">The building blocks in correct order</param> public BaseGameBlockSystem(T gameInstance, ScriptableGameBlock[] buildingBlocks) { List <IGameBlock <T> > gameBlockItems = new List <IGameBlock <T> >(); for (int i = 0; i < buildingBlocks.Length; i++) { IGameBlock <T> item = buildingBlocks[i] as IGameBlock <T>; if (item != null) { gameBlockItems.Add(item); } else { Debug.LogError("Items must be of type: '" + typeof(T) + "'!"); } } Initialization(gameInstance, gameBlockItems.ToArray()); }
public override bool ApplyReverseMove( IGameBlockDestination destinationBlock, MovementDirection directionInReverse, int numberOfBlocksToMove, out BlockMovement move, IGameBlock previousBlock, IGameBlockDestination previousDestinationBlock, Queue <IGameBlock> blockHistory) { // Already used if (this.AvailableMoves > 0) { move = null; return(false); } // This block is a valid "starting" point move = new BlockMovement(this, directionInReverse); return(true); }
public string GetBoardStringFull() { StringBuilder stringBuilder = new StringBuilder(); for (int i = -1; i < this.gameBlocks.GetLength(0); i++) { for (int j = 0; j < this.gameBlocks.GetLength(1); j++) { if (i == -1) { if (j == 0) { stringBuilder.Append(j.ToString(BlockStrings.NullBlockBoardString)); } stringBuilder.Append(j.ToString("D2")); } else { if (j == 0) { stringBuilder.Append(i.ToString("D2")); } IGameBlock gameBlock = this.gameBlocks[i, j]; if (gameBlock == null) { stringBuilder.Append(" "); } else { stringBuilder.Append(gameBlock.GetBlockStringFull()); } } } stringBuilder.AppendLine(); } return(stringBuilder.ToString()); }
public string GetBoardDestinationStringLong() { StringBuilder stringBuilder = new StringBuilder(); IGameBlock[,] trimmedBoard = this.GetTrimmedBoard(); for (int i = 0; i < trimmedBoard.GetLength(0); i++) { for (int j = 0; j < trimmedBoard.GetLength(1); j++) { IGameBlock gameBlock = trimmedBoard[i, j]; if (gameBlock == null || gameBlock is GameBlockPlayer) { stringBuilder.Append(BlockStrings.NullBlock); } else { stringBuilder.Append(gameBlock.GetBlockString()); } } } return(stringBuilder.ToString()); }
public override bool ApplyReverseMove( IGameBlockDestination destinationBlock, MovementDirection directionInReverse, int numberOfBlocksToMove, out BlockMovement move, IGameBlock previousBlock, IGameBlockDestination previousDestinationBlock, Queue <IGameBlock> blockHistory) { move = null; // This block can't be the destination if (destinationBlock == null) { return(false); } // This block forces the next move to be a certain direction, so depending on what "forceDirection" is, // the next move is always going to be the one in that direction. As a reverse move, previousBlock will // need to be the correct block based on this requirement. IGameBlock forcedPreviousBlock; switch (this.forceDirection) { default: case MovementDirection.Up: forcedPreviousBlock = this.Top; break; case MovementDirection.Down: forcedPreviousBlock = this.Bottom; break; case MovementDirection.Left: forcedPreviousBlock = this.Left; break; case MovementDirection.Right: forcedPreviousBlock = this.Right; break; } if (!ReferenceEquals(forcedPreviousBlock, previousBlock)) { return(false); } blockHistory.Enqueue(this); // It can be any direction except for the forced direction, so try any one of the three others // until one of them works (at random) List <MovementDirection> directions = new List <MovementDirection> { MovementDirection.Down, MovementDirection.Up, MovementDirection.Left, MovementDirection.Right }; switch (this.forceDirection) { case MovementDirection.Up: directions.Remove(MovementDirection.Down); break; case MovementDirection.Down: directions.Remove(MovementDirection.Up); break; case MovementDirection.Left: directions.Remove(MovementDirection.Right); break; case MovementDirection.Right: directions.Remove(MovementDirection.Left); break; } // Shuffle Random random = new Random(); for (int i = 0; i < 3; i++) { MovementDirection remove = directions[random.Next(0, 2)]; directions.Remove(remove); directions.Add(remove); } bool moveApplied = false; foreach (MovementDirection movementDirectionInReverse in directions) { switch (movementDirectionInReverse) { default: case MovementDirection.Up: if (this.Bottom == null) { moveApplied = false; } else { moveApplied = this.Bottom.ApplyReverseMove( destinationBlock, movementDirectionInReverse, numberOfBlocksToMove, out move, this, previousDestinationBlock, blockHistory); } break; case MovementDirection.Down: if (this.Top == null) { moveApplied = false; } else { moveApplied = this.Top.ApplyReverseMove( destinationBlock, movementDirectionInReverse, numberOfBlocksToMove, out move, this, previousDestinationBlock, blockHistory); } break; case MovementDirection.Left: if (this.Right == null) { moveApplied = false; } else { moveApplied = this.Right.ApplyReverseMove( destinationBlock, movementDirectionInReverse, numberOfBlocksToMove, out move, this, previousDestinationBlock, blockHistory); } break; case MovementDirection.Right: if (this.Left == null) { moveApplied = false; } else { moveApplied = this.Left.ApplyReverseMove( destinationBlock, movementDirectionInReverse, numberOfBlocksToMove, out move, this, previousDestinationBlock, blockHistory); } break; } // One of the moves worked, so break out if (moveApplied) { break; } } return(moveApplied); }
public override void Copy(IGameBlock source) { GameBlockPlayer gameBlockPlayer = source as GameBlockPlayer; if (gameBlockPlayer != null) { this.availableMoves = gameBlockPlayer.availableMoves; } }
public override bool ApplyReverseMove( IGameBlockDestination destinationBlock, MovementDirection directionInReverse, int numberOfBlocksToMove, out BlockMovement move, IGameBlock previousBlock, IGameBlockDestination previousDestinationBlock, Queue <IGameBlock> blockHistory) { move = null; // Starting with a non-filled block isn't valid if (destinationBlock != null && this.numberOfMovesApplied == 0) { return(false); } // If this is the destination bool thisIsFinalMove = destinationBlock == null; int availableBlocksToUse = this.CountUsedBlocks(directionInReverse, new Dictionary <IGameBlock, IGameBlock>()); // See if there are enough blocks to do this move if (thisIsFinalMove && availableBlocksToUse < numberOfBlocksToMove - 1) { return(false); } bool isThisBlockUsedInLoop = ReferenceEquals(destinationBlock, this) || blockHistory.Contains(this); blockHistory.Enqueue(this); // Use this block as the destination block if destinationBlock is null IGameBlockDestination destination = destinationBlock ?? this; bool moveApplied; switch (directionInReverse) { default: case MovementDirection.Up: if (this.numberOfMovesApplied == numberOfMovesNeeded && !isThisBlockUsedInLoop) { if (this.Top == null) { moveApplied = false; } else { moveApplied = this.Top.ApplyReverseMoveForLoop( destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } // Loop failed, so try non-looped if (!moveApplied && this.Bottom != null) { moveApplied = this.Bottom.ApplyReverseMove( destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } } else { if (this.Bottom == null) { moveApplied = false; } else { moveApplied = this.Bottom.ApplyReverseMove( destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } } break; case MovementDirection.Down: if (this.numberOfMovesApplied == numberOfMovesNeeded && !isThisBlockUsedInLoop) { if (this.Bottom == null) { moveApplied = false; } else { moveApplied = this.Bottom.ApplyReverseMoveForLoop( destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } // Loop failed, so try non-looped if (!moveApplied && this.Top != null) { moveApplied = this.Top.ApplyReverseMove( destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } } else { if (this.Top == null) { moveApplied = false; } else { moveApplied = this.Top.ApplyReverseMove( destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } } break; case MovementDirection.Left: if (this.numberOfMovesApplied == numberOfMovesNeeded && !isThisBlockUsedInLoop) { if (this.Left == null) { moveApplied = false; } else { moveApplied = this.Left.ApplyReverseMoveForLoop( destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } // Loop failed, so try non-looped if (!moveApplied && this.Right != null) { moveApplied = this.Right.ApplyReverseMove( destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } } else { if (this.Right == null) { moveApplied = false; } else { moveApplied = this.Right.ApplyReverseMove( destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } } break; case MovementDirection.Right: if (this.numberOfMovesApplied == numberOfMovesNeeded && !isThisBlockUsedInLoop) { if (this.Right == null) { moveApplied = false; } else { moveApplied = this.Right.ApplyReverseMoveForLoop( destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } // Loop failed, so try non-looped if (!moveApplied && this.Left != null) { moveApplied = this.Left.ApplyReverseMove( destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } } else { if (this.Left == null) { moveApplied = false; } else { moveApplied = this.Left.ApplyReverseMove( destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } } break; } if (moveApplied && !this.IsFullyAvailable && move != null) { this.SetAvailability(true); move.InsertDestinationBlock(this); move.SourceBlock.AvailableMoves++; } return(moveApplied); }
public override void Copy(IGameBlock source) { GameBlockMultipleMoves gameBlockMultipleMoves = source as GameBlockMultipleMoves; if (gameBlockMultipleMoves != null) { this.numberOfMovesApplied = gameBlockMultipleMoves.numberOfMovesApplied; this.numberOfMovesNeeded = gameBlockMultipleMoves.numberOfMovesNeeded; } }
public override bool ApplyReverseMoveForLoop( IGameBlockDestination destinationBlock, MovementDirection directionInReverse, int numberOfBlocksToMove, out BlockMovement move, IGameBlock previousBlock, IGameBlockDestination previousDestination, Queue <IGameBlock> blockHistory) { move = null; // There should already be a destination block if (destinationBlock == null) { return(false); } blockHistory.Enqueue(this); bool moveApplied; switch (directionInReverse) { default: case MovementDirection.Down: if (this.Bottom == null) { moveApplied = false; } else { moveApplied = this.Bottom.ApplyReverseMoveForLoop( destinationBlock, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } break; case MovementDirection.Up: if (this.Top == null) { moveApplied = false; } else { moveApplied = this.Top.ApplyReverseMoveForLoop( destinationBlock, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } break; case MovementDirection.Right: if (this.Right == null) { moveApplied = false; } else { moveApplied = this.Right.ApplyReverseMoveForLoop( destinationBlock, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } break; case MovementDirection.Left: if (this.Left == null) { moveApplied = false; } else { moveApplied = this.Left.ApplyReverseMoveForLoop( destinationBlock, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } break; } if (moveApplied && !this.isAvailable && move != null) { this.IsAvailable = true; move.InsertDestinationBlock(this); move.SourceBlock.AvailableMoves++; } return(moveApplied); }
public override bool ApplyReverseMoveForLoop( IGameBlockDestination destinationBlock, MovementDirection directionInReverse, int numberOfBlocksToMove, out BlockMovement move, IGameBlock previousBlock, IGameBlockDestination previousDestinationBlock, Queue<IGameBlock> blockHistory) { move = null; // This block can't be the destination if (destinationBlock == null) { return false; } // This block forces the next move to be a certain direction, so depending on what "forceDirection" is, // the next move is always going to be the one in that direction. As a reverse move, previousBlock will // need to be the correct block based on this requirement. IGameBlock forcedPreviousBlock; switch (this.forceDirection) { default: case MovementDirection.Up: forcedPreviousBlock = this.Top; break; case MovementDirection.Down: forcedPreviousBlock = this.Bottom; break; case MovementDirection.Left: forcedPreviousBlock = this.Left; break; case MovementDirection.Right: forcedPreviousBlock = this.Right; break; } if (!ReferenceEquals(forcedPreviousBlock, previousBlock)) { return false; } bool isPossibleLoopDirection; // This is trying to make a loop, so it has to be the opposite direction switch (this.forceDirection) { case MovementDirection.Up: isPossibleLoopDirection = directionInReverse == MovementDirection.Down; break; case MovementDirection.Down: isPossibleLoopDirection = directionInReverse == MovementDirection.Up; break; case MovementDirection.Left: isPossibleLoopDirection = directionInReverse == MovementDirection.Right; break; case MovementDirection.Right: isPossibleLoopDirection = directionInReverse == MovementDirection.Left; break; default: throw new ArgumentOutOfRangeException(); } if (!isPossibleLoopDirection) { return false; } blockHistory.Enqueue(this); bool moveApplied; switch (directionInReverse) { default: case MovementDirection.Up: if (this.Bottom == null) { moveApplied = false; } else { moveApplied = this.Bottom.ApplyReverseMove( destinationBlock, directionInReverse, numberOfBlocksToMove, out move, this, previousDestinationBlock, blockHistory); } break; case MovementDirection.Down: if (this.Top == null) { moveApplied = false; } else { moveApplied = this.Top.ApplyReverseMove( destinationBlock, directionInReverse, numberOfBlocksToMove, out move, this, previousDestinationBlock, blockHistory); } break; case MovementDirection.Left: if (this.Right == null) { moveApplied = false; } else { moveApplied = this.Right.ApplyReverseMove( destinationBlock, directionInReverse, numberOfBlocksToMove, out move, this, previousDestinationBlock, blockHistory); } break; case MovementDirection.Right: if (this.Left == null) { moveApplied = false; } else { moveApplied = this.Left.ApplyReverseMove( destinationBlock, directionInReverse, numberOfBlocksToMove, out move, this, previousDestinationBlock, blockHistory); } break; } return moveApplied; }
public void SetContext(IGameBlock gameBlock) { _gameBlock = gameBlock; }
public override bool ApplyReverseMoveForLoop( IGameBlockDestination destinationBlock, MovementDirection directionInReverse, int numberOfBlocksToMove, out BlockMovement move, IGameBlock previousBlock, IGameBlockDestination previousDestination, Queue<IGameBlock> blockHistory) { move = null; // There should already be a destination block if (destinationBlock == null) { return false; } blockHistory.Enqueue(this); bool moveApplied; switch (directionInReverse) { default: case MovementDirection.Down: if (this.Bottom == null) { moveApplied = false; } else { moveApplied = this.Bottom.ApplyReverseMoveForLoop( destinationBlock, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } break; case MovementDirection.Up: if (this.Top == null) { moveApplied = false; } else { moveApplied = this.Top.ApplyReverseMoveForLoop( destinationBlock, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } break; case MovementDirection.Right: if (this.Right == null) { moveApplied = false; } else { moveApplied = this.Right.ApplyReverseMoveForLoop( destinationBlock, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } break; case MovementDirection.Left: if (this.Left == null) { moveApplied = false; } else { moveApplied = this.Left.ApplyReverseMoveForLoop( destinationBlock, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } break; } if (moveApplied && !this.isAvailable && move != null) { this.IsAvailable = true; move.InsertDestinationBlock(this); move.SourceBlock.AvailableMoves++; } return moveApplied; }
public abstract bool ApplyReverseMoveForLoop( IGameBlockDestination destinationBlock, MovementDirection directionInReverse, int numberOfBlocksToMove, out BlockMovement move, IGameBlock previousBlock, IGameBlockDestination previousDestination, Queue<IGameBlock> blockHistory);
public virtual void Copy(IGameBlock source) { }
public virtual void Copy(IGameBlock source) { }
public override bool ApplyReverseMoveForLoop( IGameBlockDestination destinationBlock, MovementDirection directionInReverse, int numberOfBlocksToMove, out BlockMovement move, IGameBlock previousBlock, IGameBlockDestination previousDestinationBlock, Queue<IGameBlock> blockHistory) { move = null; // This can't be the final destination block if (destinationBlock == null) { return false; } // It needs at least 2 previous blocks if (previousDestinationBlock == null) { return false; } if (destinationBlock == previousDestinationBlock) { return false; } bool moveApplied; switch (directionInReverse) { default: case MovementDirection.Down: if (this.Bottom == null) { moveApplied = false; } else { moveApplied = this.Bottom.ApplyReverseMoveForLoop( destinationBlock, directionInReverse, numberOfBlocksToMove - 1, out move, this, previousDestinationBlock, blockHistory); } break; case MovementDirection.Up: if (this.Top == null) { moveApplied = false; } else { moveApplied = this.Top.ApplyReverseMoveForLoop( destinationBlock, directionInReverse, numberOfBlocksToMove - 1, out move, this, previousDestinationBlock, blockHistory); } break; case MovementDirection.Right: if (this.Right == null) { moveApplied = false; } else { moveApplied = this.Right.ApplyReverseMoveForLoop( destinationBlock, directionInReverse, numberOfBlocksToMove - 1, out move, this, previousDestinationBlock, blockHistory); } break; case MovementDirection.Left: if (this.Left == null) { moveApplied = false; } else { moveApplied = this.Left.ApplyReverseMoveForLoop( destinationBlock, directionInReverse, numberOfBlocksToMove - 1, out move, this, previousDestinationBlock, blockHistory); } break; } if (moveApplied) { // It requires 1 less move if this block is used move.SourceBlock.AvailableMoves--; } return moveApplied; }
public override bool ApplyReverseMoveForLoop( IGameBlockDestination destinationBlock, MovementDirection directionInReverse, int numberOfBlocksToMove, out BlockMovement move, IGameBlock previousBlock, IGameBlockDestination previousDestinationBlock, Queue <IGameBlock> blockHistory) { move = null; // This block can't be the destination if (destinationBlock == null) { return(false); } // This block forces the next move to be a certain direction, so depending on what "forceDirection" is, // the next move is always going to be the one in that direction. As a reverse move, previousBlock will // need to be the correct block based on this requirement. IGameBlock forcedPreviousBlock; switch (this.forceDirection) { default: case MovementDirection.Up: forcedPreviousBlock = this.Top; break; case MovementDirection.Down: forcedPreviousBlock = this.Bottom; break; case MovementDirection.Left: forcedPreviousBlock = this.Left; break; case MovementDirection.Right: forcedPreviousBlock = this.Right; break; } if (!ReferenceEquals(forcedPreviousBlock, previousBlock)) { return(false); } bool isPossibleLoopDirection; // This is trying to make a loop, so it has to be the opposite direction switch (this.forceDirection) { case MovementDirection.Up: isPossibleLoopDirection = directionInReverse == MovementDirection.Down; break; case MovementDirection.Down: isPossibleLoopDirection = directionInReverse == MovementDirection.Up; break; case MovementDirection.Left: isPossibleLoopDirection = directionInReverse == MovementDirection.Right; break; case MovementDirection.Right: isPossibleLoopDirection = directionInReverse == MovementDirection.Left; break; default: throw new ArgumentOutOfRangeException(); } if (!isPossibleLoopDirection) { return(false); } blockHistory.Enqueue(this); bool moveApplied; switch (directionInReverse) { default: case MovementDirection.Up: if (this.Bottom == null) { moveApplied = false; } else { moveApplied = this.Bottom.ApplyReverseMove( destinationBlock, directionInReverse, numberOfBlocksToMove, out move, this, previousDestinationBlock, blockHistory); } break; case MovementDirection.Down: if (this.Top == null) { moveApplied = false; } else { moveApplied = this.Top.ApplyReverseMove( destinationBlock, directionInReverse, numberOfBlocksToMove, out move, this, previousDestinationBlock, blockHistory); } break; case MovementDirection.Left: if (this.Right == null) { moveApplied = false; } else { moveApplied = this.Right.ApplyReverseMove( destinationBlock, directionInReverse, numberOfBlocksToMove, out move, this, previousDestinationBlock, blockHistory); } break; case MovementDirection.Right: if (this.Left == null) { moveApplied = false; } else { moveApplied = this.Left.ApplyReverseMove( destinationBlock, directionInReverse, numberOfBlocksToMove, out move, this, previousDestinationBlock, blockHistory); } break; } return(moveApplied); }
public override bool ApplyReverseMove( IGameBlockDestination destinationBlock, MovementDirection directionInReverse, int numberOfBlocksToMove, out BlockMovement move, IGameBlock previousBlock, IGameBlockDestination previousDestinationBlock, Queue<IGameBlock> blockHistory) { move = null; // This block can't be the destination if (destinationBlock == null) { return false; } // This block forces the next move to be a certain direction, so depending on what "forceDirection" is, // the next move is always going to be the one in that direction. As a reverse move, previousBlock will // need to be the correct block based on this requirement. IGameBlock forcedPreviousBlock; switch (this.forceDirection) { default: case MovementDirection.Up: forcedPreviousBlock = this.Top; break; case MovementDirection.Down: forcedPreviousBlock = this.Bottom; break; case MovementDirection.Left: forcedPreviousBlock = this.Left; break; case MovementDirection.Right: forcedPreviousBlock = this.Right; break; } if (!ReferenceEquals(forcedPreviousBlock, previousBlock)) { return false; } blockHistory.Enqueue(this); // It can be any direction except for the forced direction, so try any one of the three others // until one of them works (at random) List<MovementDirection> directions = new List<MovementDirection> { MovementDirection.Down, MovementDirection.Up, MovementDirection.Left, MovementDirection.Right }; switch (this.forceDirection) { case MovementDirection.Up: directions.Remove(MovementDirection.Down); break; case MovementDirection.Down: directions.Remove(MovementDirection.Up); break; case MovementDirection.Left: directions.Remove(MovementDirection.Right); break; case MovementDirection.Right: directions.Remove(MovementDirection.Left); break; } // Shuffle Random random = new Random(); for (int i = 0; i < 3; i++) { MovementDirection remove = directions[random.Next(0, 2)]; directions.Remove(remove); directions.Add(remove); } bool moveApplied = false; foreach (MovementDirection movementDirectionInReverse in directions) { switch (movementDirectionInReverse) { default: case MovementDirection.Up: if (this.Bottom == null) { moveApplied = false; } else { moveApplied = this.Bottom.ApplyReverseMove( destinationBlock, movementDirectionInReverse, numberOfBlocksToMove, out move, this, previousDestinationBlock, blockHistory); } break; case MovementDirection.Down: if (this.Top == null) { moveApplied = false; } else { moveApplied = this.Top.ApplyReverseMove( destinationBlock, movementDirectionInReverse, numberOfBlocksToMove, out move, this, previousDestinationBlock, blockHistory); } break; case MovementDirection.Left: if (this.Right == null) { moveApplied = false; } else { moveApplied = this.Right.ApplyReverseMove( destinationBlock, movementDirectionInReverse, numberOfBlocksToMove, out move, this, previousDestinationBlock, blockHistory); } break; case MovementDirection.Right: if (this.Left == null) { moveApplied = false; } else { moveApplied = this.Left.ApplyReverseMove( destinationBlock, movementDirectionInReverse, numberOfBlocksToMove, out move, this, previousDestinationBlock, blockHistory); } break; } // One of the moves worked, so break out if (moveApplied) { break; } } return moveApplied; }
/// <summary> /// Отрисовка следующего блока /// </summary> private void DisplayNextBlock(IGameBlock nextBlock) { _gameGrid[_nextBlockRow, _nextBlockCol].SetColor(nextBlock.Left.Color); _gameGrid[_nextBlockRow, _nextBlockCol + 1].SetColor(nextBlock.Right.Color); }
public override bool ApplyReverseMove( IGameBlockDestination destinationBlock, MovementDirection directionInReverse, int numberOfBlocksToMove, out BlockMovement move, IGameBlock previousBlock, IGameBlockDestination previousDestinationBlock, Queue <IGameBlock> blockHistory) { move = null; // Starting with a non-filled block isn't valid if (destinationBlock != null && this.isAvailable) { return(false); } // If this is the destination bool thisIsFinalMove = destinationBlock == null; int availableBlocksToUse = this.CountUsedBlocks(directionInReverse, new Dictionary <IGameBlock, IGameBlock>()); // See if there are enough blocks to do this move if (thisIsFinalMove && availableBlocksToUse < numberOfBlocksToMove) { return(false); } else if (destinationBlock == this) { // If it came back around to this block again, then it's in a loop. It needs to break out. return(false); } else if (blockHistory.Contains(this)) { // If it came back around to this block again, then it's in a loop. It needs to break out. return(false); } blockHistory.Enqueue(this); // Use this block as the destination block if destinationBlock is null IGameBlockDestination destination = destinationBlock ?? this; bool moveApplied; switch (directionInReverse) { default: case MovementDirection.Up: if (this.Bottom == null) { moveApplied = false; } else { moveApplied = this.Bottom.ApplyReverseMove( destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } break; case MovementDirection.Down: if (this.Top == null) { moveApplied = false; } else { moveApplied = this.Top.ApplyReverseMove( destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } break; case MovementDirection.Left: if (this.Right == null) { moveApplied = false; } else { moveApplied = this.Right.ApplyReverseMove( destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } break; case MovementDirection.Right: if (this.Left == null) { moveApplied = false; } else { moveApplied = this.Left.ApplyReverseMove( destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } break; } if (moveApplied && !this.isAvailable && move != null) { this.IsAvailable = true; move.InsertDestinationBlock(this); move.SourceBlock.AvailableMoves++; } return(moveApplied); }
public override bool ApplyReverseMoveForLoop( IGameBlockDestination destinationBlock, MovementDirection directionInReverse, int numberOfBlocksToMove, out BlockMovement move, IGameBlock previousBlock, IGameBlockDestination previousDestinationBlock, Queue<IGameBlock> blockHistory) { move = null; // This can't be the final destination block if (destinationBlock == null) { return false; } // It needs at least 2 previous blocks if (previousDestinationBlock == null) { return false; } if (destinationBlock == previousDestinationBlock) { return false; } bool moveApplied; switch (directionInReverse) { default: case MovementDirection.Down: if (this.Bottom == null) { moveApplied = false; } else { moveApplied = this.Bottom.ApplyReverseMoveForLoop( destinationBlock, directionInReverse, numberOfBlocksToMove - 1, out move, this, previousDestinationBlock, blockHistory); } break; case MovementDirection.Up: if (this.Top == null) { moveApplied = false; } else { moveApplied = this.Top.ApplyReverseMoveForLoop( destinationBlock, directionInReverse, numberOfBlocksToMove - 1, out move, this, previousDestinationBlock, blockHistory); } break; case MovementDirection.Right: if (this.Right == null) { moveApplied = false; } else { moveApplied = this.Right.ApplyReverseMoveForLoop( destinationBlock, directionInReverse, numberOfBlocksToMove - 1, out move, this, previousDestinationBlock, blockHistory); } break; case MovementDirection.Left: if (this.Left == null) { moveApplied = false; } else { moveApplied = this.Left.ApplyReverseMoveForLoop( destinationBlock, directionInReverse, numberOfBlocksToMove - 1, out move, this, previousDestinationBlock, blockHistory); } break; } if (moveApplied) { // It requires 1 less move if this block is used move.SourceBlock.AvailableMoves--; } return moveApplied; }
public IGameBlock[,] GetTrimmedBoard() { // Don't use full null rows and columns int startingRow = this.gameBlocks.GetLength(0); int endingRow = 0; int startingColumn = this.gameBlocks.GetLength(1); int endingColumn = 0; for (int i = 0; i < this.gameBlocks.GetLength(0); i++) { bool allNull = true; for (int j = 0; j < this.gameBlocks.GetLength(1); j++) { IGameBlock gameBlock = this.gameBlocks[i, j]; if (gameBlock != null && !(gameBlock is GameBlockNull)) { allNull = false; break; } } if (!allNull) { startingRow = i; break; } } for (int i = this.gameBlocks.GetLength(0) - 1; i >= 0; i--) { bool allNull = true; for (int j = 0; j < this.gameBlocks.GetLength(1); j++) { IGameBlock gameBlock = this.gameBlocks[i, j]; if (gameBlock != null && !(gameBlock is GameBlockNull)) { allNull = false; break; } } if (!allNull) { endingRow = i + 1; break; } } for (int i = 0; i < this.gameBlocks.GetLength(1); i++) { bool allNull = true; for (int j = 0; j < this.gameBlocks.GetLength(0); j++) { IGameBlock gameBlock = this.gameBlocks[j, i]; if (gameBlock != null && !(gameBlock is GameBlockNull)) { allNull = false; break; } } if (!allNull) { startingColumn = i; break; } } for (int i = this.gameBlocks.GetLength(1) - 1; i >= 0; i--) { bool allNull = true; for (int j = 0; j < this.gameBlocks.GetLength(0); j++) { IGameBlock gameBlock = this.gameBlocks[j, i]; if (gameBlock != null && !(gameBlock is GameBlockNull)) { allNull = false; break; } } if (!allNull) { endingColumn = i + 1; break; } } int totalRows = endingRow - startingRow; int totalColumns = endingColumn - startingColumn; IGameBlock[,] blocks = new IGameBlock[totalRows, totalColumns]; for (int i = startingRow, iNew = 0; i < endingRow; i++, iNew++) { for (int j = startingColumn, jNew = 0; j < endingColumn; j++, jNew++) { blocks[iNew, jNew] = this.gameBlocks[i, j]; } } return(blocks); }
private void LoadPuzzleIntoTable() { // Clear the animation queue this.setAnimationQueue.Clear(); // Clear the history this.movesHistory = new Stack <BlockMovement>(); // Fudge Factor so it doesn't use up the whole space, just most of it const float FudgeFactor = .95f; string puzzleName = this.specialStageMode ? this.SpecialStage.LevelMapping.Mapping[this.Level] : this.levelMapping.Mapping[this.Level]; this.GameBoard = GameBoardXmlIo.ReadGameBoard(puzzleName); TutorialMessage tutorial = null; if (!this.specialStageMode) { tutorial = this.Tutorials.FirstOrDefault(t => t.Level == this.Level); } // Set the number of columns IGameBlock[,] trimmedBoard = this.GameBoard.GetTrimmedBoard(); int rows = trimmedBoard.GetLength(0); int columns = trimmedBoard.GetLength(1); this.Table.columns = columns; GamePiece[,] gamePieces = new GamePiece[rows, columns]; // Calculate what is available for width and height float availableWidth = this.TableLimits.localSize.x * FudgeFactor; float availableHeight = this.TableLimits.localSize.y * FudgeFactor; // Show the tutorial if (tutorial != null) { // Account for the size of the tutorial tip availableHeight -= this.TutorialSize; this.TutorialTipStripObject.SetActive(true); this.TutorialTipStripMessage.text = tutorial.Message; } else { this.TutorialTipStripObject.SetActive(false); } availableWidth /= columns; availableHeight /= rows; // Choose the smallest size otherwise it will be too big to fit this.BlockSize = Math.Min((int)Math.Floor(Math.Min(availableWidth, availableHeight)), this.MaxBlockSize); for (int i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { IGameBlock gameBlock = trimmedBoard[i, j]; GamePiece block = NGUITools.AddChild(this.Table.gameObject, this.GamePiece.gameObject).GetComponent <GamePiece>(); block.GameBlock = gameBlock; block.SetBlockSize(this.BlockSize); block.SetAnimationMappings(this.animationMappingsDictionary); block.LoadImage(); block.SubscribeToGameBlockEvents(); if (gameBlock != null) { block.name = string.Format("{0}-{1}: {2}", gameBlock.IndexRow, gameBlock.IndexColumn, gameBlock.GetBlockString()); } else { block.name = "Null Block"; } this.Table.children.Add(block.transform); gamePieces[i, j] = block; } } // Center the table float heightOffset = (float)(rows * this.BlockSize) / 2; float widthOffset = -(float)(columns * this.BlockSize) / 2; this.Table.transform.localPosition = new Vector3(widthOffset, heightOffset + this.VerticalOffset); this.Table.enabled = true; this.Table.repositionNow = true; this.firstMove = true; // Show the indicator that this is the first time the level is played string key = this.specialStageMode ? string.Format("{0}_{1}_{2}", SharedResources.TimesLevelPlayedPrefix, this.SpecialStage.StageId, this.Level) : string.Format("{0}_{1}", SharedResources.TimesLevelPlayedPrefix, this.Level); int timesPlayed = PlayerPrefsFast.GetInt(key, 0); this.FirstTimeIndicator.SetActive(timesPlayed == 0); this.CurrentLevelText.text = string.Format("Level {0}", this.Level); if (!this.specialStageMode) { foreach (TutorialAnimation tutorialAnimation in this.TutorialAnimations) { if (tutorialAnimation.Level == this.Level) { NGUITools.AddChild(gamePieces[tutorialAnimation.Row, tutorialAnimation.Column].gameObject, tutorialAnimation.Animation); } } } }
public override bool ApplyReverseMoveForLoop( IGameBlockDestination destinationBlock, MovementDirection directionInReverse, int numberOfBlocksToMove, out BlockMovement move, IGameBlock previousBlock, IGameBlockDestination previousDestination, Queue<IGameBlock> blockHistory) { move = null; // Starting with a non-filled block isn't valid if (destinationBlock != null && this.numberOfMovesApplied == 0) { return false; } // If this is the destination bool thisIsFinalMove = destinationBlock == null; int availableBlocksToUse = this.CountUsedBlocks(directionInReverse, new Dictionary<IGameBlock, IGameBlock>()); // See if there are enough blocks to do this move if (thisIsFinalMove && availableBlocksToUse < numberOfBlocksToMove) { return false; } // Use this block as the destination block if destinationBlock is null IGameBlockDestination destination = destinationBlock ?? this; blockHistory.Enqueue(this); bool moveApplied; switch (directionInReverse) { default: case MovementDirection.Up: if (this.Top == null) { moveApplied = false; } else { moveApplied = this.Top.ApplyReverseMoveForLoop( destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } break; case MovementDirection.Down: if (this.Bottom == null) { moveApplied = false; } else { moveApplied = this.Bottom.ApplyReverseMoveForLoop( destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } break; case MovementDirection.Left: if (this.Left == null) { moveApplied = false; } else { moveApplied = this.Left.ApplyReverseMoveForLoop( destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } break; case MovementDirection.Right: if (this.Right == null) { moveApplied = false; } else { moveApplied = this.Right.ApplyReverseMoveForLoop( destination, directionInReverse, numberOfBlocksToMove, out move, this, this, blockHistory); } break; } if (moveApplied && !this.IsFullyAvailable && move != null) { this.SetAvailability(true); move.InsertDestinationBlock(this); move.SourceBlock.AvailableMoves++; } return moveApplied; }
public override bool ApplyReverseMove( IGameBlockDestination destinationBlock, MovementDirection directionInReverse, int numberOfBlocksToMove, out BlockMovement move, IGameBlock previousBlock, IGameBlockDestination previousDestinationBlock, Queue<IGameBlock> blockHistory) { // Already used if (this.AvailableMoves > 0) { move = null; return false; } // This block is a valid "starting" point move = new BlockMovement(this, directionInReverse); return true; }
public override void Copy(IGameBlock source) { GameBlockNormal gameBlockNormal = source as GameBlockNormal; if (gameBlockNormal != null) { this.isAvailable = gameBlockNormal.isAvailable; } }
public override bool ApplyReverseMoveForLoop( IGameBlockDestination destinationBlock, MovementDirection directionInReverse, int numberOfBlocksToMove, out BlockMovement move, IGameBlock previousBlock, IGameBlockDestination previousDestination, Queue<IGameBlock> blockHistory) { // Failed to find a looped reverse move move = null; return false; }