/// <summary> /// Move a <see cref="Tetrimino" /> towards a <see cref="MoveDirection" /> if permits. /// The <see cref="Tetrimino" /> will not be changed if the operation fails. /// </summary> /// <param name="collisionChecker"> /// A <see cref="Func{Block, Boolean}" /> which returns true. /// when the block will collide /// </param> /// <param name="direction">Direction to move</param> /// <returns>Whether the <see cref="TryMove(MoveDirection, Func{Block, bool})" /> step succeeds</returns> public bool TryMove(MoveDirection direction, Func <Block, bool> collisionChecker) { var position = Position; if (direction == MoveDirection.Down) { var row = position.Y + 1; position = new Position(position.X, row); } else { var delta = direction == MoveDirection.Right ? 1 : -1; var column = position.X + delta; position = new Position(column, position.Y); } var newBlocks = GeneratorHelper.CreateOffsetBlocks(Kind, position, FacingDirection); if (newBlocks.Any(collisionChecker)) { return(false); } GeneratorHelper.MapAtomicNumberForNewBlocks(Blocks, newBlocks); Position = position; Blocks = newBlocks; return(true); }
protected Tetrimino(TetriminoKind kind, Position position, Position firstBlockPosition, Direction facingDirection) { Kind = kind; Position = position; FacingDirection = facingDirection; FirstBlockPosition = firstBlockPosition; Blocks = GeneratorHelper.CreateOffsetBlocks(kind, Position, facingDirection); }
/// <summary> /// Rotate a <see cref="Tetrimino" /> towards a <see cref="RotationDirection" /> if permits. /// The <see cref="Tetrimino" /> will not be changed if the operation fails. /// </summary> /// <param name="collisionChecker"> /// A <see cref="Func{Block, Boolean}" /> which returns true when the block will /// collide /// </param> /// <param name="rotationDirection">Direction to rotate</param> /// <returns>Whether the <see cref="TryRotate" /> step succeeds</returns> public bool TryRotate(RotationDirection rotationDirection, Func <Block, bool> collisionChecker) { var count = Enum.GetValues(typeof(Direction)).Length; var delta = rotationDirection == RotationDirection.Right ? 1 : -1; var direction = (int)FacingDirection + delta; if (direction < 0) { direction += count; } if (direction >= count) { direction %= count; } var adjustPattern = Kind == TetriminoKind.Linear ? new[] { 0, 1, -1, 2, -2 } : new[] { 0, 1, -1 }; foreach (var adjust in adjustPattern) { var newPos = new Position(Position.X + adjust, Position.Y); var newBlocks = GeneratorHelper.CreateOffsetBlocks(Kind, newPos, (Direction)direction); if (!newBlocks.Any(collisionChecker)) { GeneratorHelper.MapAtomicNumberForNewBlocks(Blocks, newBlocks); FacingDirection = (Direction)direction; Position = newPos; Blocks = newBlocks; return(true); } } return(false); }