### rotation

Now that the piece can move, we should try rotation. Given the hard-coded initial state of having T piece at `(5, 17)` and a block at `(0, 0)`, here’s the spec:

``````                                                                              s2"""
Rotating the current piece should
change the blocks in the view.                                            \$rotate1
"""
...

def rotate1 =
rotateCW(s1).blocks map {_.pos} must contain(exactly(
(0, 0), (5, 18), (5, 17), (5, 16), (6, 17)
)).inOrder
``````

This shouldn’t even compile because `Stage` class doesn’t have `rotateCW()` method yet.

``````[error] /Users/eed3si9n/work/tetrix.scala/library/src/test/scala/StageSpec.scala:33: value rorateCCW is not a member of com.eed3si9n.tetrix.Stage
[error]     stage.rotateCW().view.blocks map {_.pos} must contain(
[error]           ^
[error] one error found
[error] (library/test:compile) Compilation failed
``````

Stub it out:

``````  def rotateCW() = this
``````

and we’re back to a failing test case.

First, we implement the rotation at the piece level:

``````  def rotateBy(theta: Double): Piece = {
val c = math.cos(theta)
val s = math.sin(theta)
def roundToHalf(v: (Double, Double)): (Double, Double) =
(math.round(v._1 * 2.0) * 0.5, math.round(v._2 * 2.0) * 0.5)
copy(locals = locals map { case(x, y) => (x * c - y * s, x * s + y * c) } map roundToHalf)
}
``````

And then we copy-paste (!) the `moveBy` method and make it into `rotateBy`:

``````  def rotateCW() = rotateBy(-math.Pi / 2.0)
private[this] def rotateBy(theta: Double): this.type = {
validate(
currentPiece.rotateBy(theta),
``````[info]   Rotating the current piece should