rotateCurrent :: Game ()
rotateCurrent = gets currentPiece >>= rotate >>= setCurrentPiece
 where
   rotate :: Block -> Game Block
   rotate block@(Block pos@(px,py) grid) = do
     let (R.Z :. oldw :. oldh) = extent grid
         w' = oldh -- height becomes width
         h' = oldw -- width becomes height
         newsh = (R.Z :. w' :. h')
         -- make sure that the px and py values fit the piece on the board!
         permissibleX x
           | x < 0 = 0
           | x >= (boardWidth - w') = boardWidth - w'
           | otherwise = x
         permissibleY y
           | y < 0 = 0
           | y >= (boardHeight - h') = boardHeight - h'
           | otherwise = y
         newpos@(newx, newy) = (permissibleX px, permissibleY py)
         -- shuffle pieces over to their new positions
         translateC (R.Z :. x :. y) = (R.Z :. (oldw - y - 1) :. x)
         newgrid = computeVectorS $ backpermute newsh translateC grid
         newblock = Block { position = newpos, guts = newgrid }
     canMove <- checkPieceCanMove newblock 0 0
     return $ if canMove
              then newblock
              else block -- can't move, keep same
rotateCurrent :: Game ()
rotateCurrent = gets currentPiece >>= rotate >>= setCurrentPiece
 where
   rotate :: Block -> Game Block
   rotate block@(Block pos@(px,py) grid) = do
     let (R.Z :. oldw :. oldh) = extent grid
         w' = oldh -- height becomes width
         h' = oldw -- width becomes height
         newsh = (R.Z :. w' :. h')
         -- make sure that the px and py values fit the piece on the board!
         permissibleX x
           | x < 0 = 0
           | x >= (boardWidth - w') = boardWidth - w'
           | otherwise = x
         permissibleY y
           | y < 0 = 0
           | y >= (boardHeight - h') = boardHeight - h'
           | otherwise = y
         newpos@(newx, newy) = (permissibleX px, permissibleY py)
         -- shuffle pieces over to their new positions
         translateC (R.Z :. x :. y) = (R.Z :. (oldw - y - 1) :. x)
         newgrid = computeVectorS $ backpermute newsh translateC grid
         newblock = Block { position = newpos, guts = newgrid }
     canMove <- checkPieceCanMove newblock 0 0
     return $ if canMove
              then newblock
              else block -- can't move, keep same
rotateCurrent = gets currentPiece >>= rotate >>= setCurrentPiece
 where
   rotate :: Block -> Game Block
   rotate block@(Block pos@(px,py) grid) = do
     let (R.Z :. oldw :. oldh) = extent grid
         w' = oldh -- height becomes width
         h' = oldw -- width becomes height
         newsh = (R.Z :. w' :. h')
         -- make sure that the px and py values fit the piece on the board!
         permissibleX x
           | x < 0 = 0
           | x >= (boardWidth - w') = boardWidth - w'
           | otherwise = x
         permissibleY y
           | y < 0 = 0
           | y >= (boardHeight - h') = boardHeight - h'
           | otherwise = y
         newpos@(newx, newy) = (permissibleX px, permissibleY py)
         -- shuffle pieces over to their new positions
         translateC (R.Z :. x :. y) = (R.Z :. (oldw - y - 1) :. x)
         newgrid = computeVectorS $ backpermute newsh translateC grid
         newblock = Block { position = newpos, guts = newgrid }
     canMove <- checkPieceCanMove newblock 0 0
     return $ if canMove
              then newblock
              else block -- can't move, keep same