packages feed

HTicTacToe-0.1: Draw.hs

{-
    The MIT License
    
    Copyright (c) 2010 Korcan Hussein
    
    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:
    
    The above copyright notice and this permission notice shall be included in
    all copies or substantial portions of the Software.
    
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    THE SOFTWARE.
-}
module Draw where

import Control.Monad
import Control.Monad.Trans

import Graphics.UI.SDL hiding (flip)
import qualified Graphics.UI.SDL as SDL (flip)

--import Graphics.UI.SDL.Image

import Graphics.UI.SDL.TTF

import Grid
import GameState hiding (font, screen, grid, winner, stats)
import GameEnv
import Surface

textColor :: Color
textColor = Color 0x00 0xFF 0x00

drawPlayersKey :: AppEnv ()
drawPlayersKey = do
    playerPiece <- getPlayerType
    let aiPiece = swapCell playerPiece
    
    font   <- getFont
    screen <- getScreen
    
    liftIO $ do        
        playerKey <- renderTextSolid font ("Player: " ++ show playerPiece) textColor
        aiKey     <- renderTextSolid font ("CPU: " ++ show aiPiece) textColor
        applySurface 10 10 playerKey screen Nothing
        applySurface 10 (10 + surfaceGetHeight playerKey) aiKey screen Nothing

drawBoard :: AppEnv ()
drawBoard = do

    Rect x y gw gh <- getGridBounds
    winIndices     <- snd `liftM` getWinner
    grid    <- getGrid
    screen  <- getScreen

    let (w,h) = (gw `div` 3, gh `div` 3)
    let (halfW, halfH) = (w `div` 4, h `div` 4)
    
    let applySurf r c = applySurface' (r * w + x + halfW) (c * h + y + halfH)    
    -- draw pieces
    forM_ [(r,c) | r <- [0..2], c <- [0..2]] $ \(r,c) -> do
        case cellAt grid r c of
            Nought -> do
                src <- if (r,c) `elem` winIndices
                        then getOWinSurf
                        else getNought
                applySurf r c src screen Nothing
            Cross  -> do
                src <- if (r,c) `elem` winIndices
                        then getXWinSurf
                        else getCross                
                applySurf r c src screen Nothing
            _      -> return ()
    
    -- draw/overlay grid
    let drawLine' u hh l d = liftIO . drawLine screen u hh l d    
    drawLine' (x + w, y) gh thickness Vertical gridColor
    drawLine' (x + w * 2, y) gh thickness Vertical gridColor
    
    drawLine' (x, y + h) gw thickness Horizontal gridColor
    drawLine' (x, y + h * 2) gw thickness Horizontal gridColor
    
 where gridColor = Pixel 0xFF00FF
       thickness = 5

drawEndGame :: AppEnv ()
drawEndGame = do
    screen <- getScreen
    font   <- getFont
    winner <- fst `liftM` getWinner
    playerResultStr <- winOrLose winner `liftM` getPlayerType
    unless (null playerResultStr) $ liftIO $ do
        textSurface <- renderTextSolid font playerResultStr textColor
        let x = (screenWidth `div` 2) - (surfaceGetWidth textSurface `div` 2)
        applySurface x (screenHeight - 35) textSurface screen Nothing

 where winOrLose Noughts Nought = "YOU WON!"
       winOrLose Crosses Cross  = "YOU WON!"
       winOrLose Noughts Cross  = "YOU LOST!"
       winOrLose Crosses Nought = "YOU LOST!"
       winOrLose Draw _         = "DRAW GAME!"
       winOrLose _ _            = []

drawScore :: AppEnv ()
drawScore = do
    Rect _ ry _ h <- getGridBounds
    font   <- getFont
    screen <- getScreen
    stats  <- getStats                       
    
    let y = ry + h + 20
    liftIO $ do
        scores <- renderTextSolid font ("Player: " ++ (show $ playerCount stats) ++ " CPU: " ++ (show $ aiCount stats) ++ " Ties: " ++ (show $ tieCount stats)) textColor
        let x = (screenWidth `div` 2) - (surfaceGetWidth scores `div` 2)
        applySurface x y scores screen Nothing

render :: AppEnv ()
render = do
    screen <- getScreen
    liftIO $ clear screen 0x00 0x00 0x00
    drawPlayersKey
    drawBoard
    drawScore
    drawEndGame
    liftIO $ SDL.flip screen