private bool TryRotateActivePiece(bool left) { var success = false; var longestDistance = float.MinValue; var centerPoint = new Vector2(); for (int i = 0; i < _activeTiles.Length; i++) { var position = _activeTiles[i]; foreach (var otherPosition in _activeTiles) { var distance = TilePosition.Distance(position, otherPosition); if (distance > longestDistance) { longestDistance = distance; centerPoint = new Vector2(position.X + otherPosition.X, position.Y + otherPosition.Y); centerPoint /= 2; } } } var angle = (float)(Math.PI / 2.0); if (left) { angle *= -1.0f; } var rotation = Matrix3x2.CreateRotation(angle, centerPoint); var newActiveTiles = new TilePosition[_activeTiles.Length]; for (int i = 0; i < _activeTiles.Length; i++) { var position = _activeTiles[i]; var temp = Vector2.Transform(new Vector2(position.X, position.Y), rotation); var newPosition = new TilePosition((int)Math.Ceiling(temp.X), (int)Math.Ceiling(temp.Y)); newActiveTiles[i] = newPosition; } var withinBounds = true; var farthestLeft = int.MaxValue; var farthestRight = int.MinValue; var farthestTop = int.MaxValue; var farthestBottom = int.MinValue; for (int i = 0; i < newActiveTiles.Length; i++) { var newPosition = newActiveTiles[i]; if (newPosition.X < farthestLeft) { farthestLeft = newPosition.X; } if (newPosition.X > farthestRight) { farthestRight = newPosition.X; } if (newPosition.Y < farthestTop) { farthestTop = newPosition.Y; } if (newPosition.Y > farthestBottom) { farthestBottom = newPosition.Y; } if (!((newPosition.X >= 0 && newPosition.X < _boardWidth) && (newPosition.Y >= 0 && newPosition.Y < _boardHeight))) { withinBounds = false; } } if (!withinBounds) { int dx = 0; int dy = 0; if (farthestLeft != int.MaxValue && farthestLeft < 0) { dx = farthestLeft * -1; } else if (farthestRight != int.MinValue && farthestRight >= _boardWidth) { dx = farthestRight - _boardWidth - 1; } if (farthestTop != int.MaxValue && farthestTop < 0) { dy = farthestTop * -1; } else if (farthestBottom != int.MinValue && farthestBottom >= _boardHeight) { dy = farthestBottom - _boardHeight - 1; } while (dx != 0) { var newPiece = TryMovePiece(newActiveTiles, dx < 0 ? -1 : 1, 0, true); if (newPiece != null) { newActiveTiles = newPiece; dx += dx < 0 ? 1 : -1; } else { break; } } while (dy != 0) { var newPiece = TryMovePiece(newActiveTiles, 0, dy < 0 ? -1 : 1, true); if (newPiece != null) { newActiveTiles = newPiece; dy += dy < 0 ? 1 : -1; } else { break; } } } foreach (var newPosition in newActiveTiles) { var overlap = false; foreach (var position in _activeTiles) { if (newPosition == position) { overlap = true; break; } } if (!overlap && _board[newPosition.X, newPosition.Y]) { newActiveTiles = null; break; } } if (newActiveTiles != null) { foreach (var pos in _activeTiles) { _board[pos.X, pos.Y] = false; } foreach (var pos in newActiveTiles) { _board[pos.X, pos.Y] = true; } _activeTiles = newActiveTiles; success = true; } return(success); }