packages feed

4Blocks-0.2: Core/Well.hs

module Core.Well ( Well,
                   createWell,
                   generateWell,
                   getBlocksFromWell,
                   getSizeFromWell,
                   clearFullLinesFromWell,
                   gameEndWell
                 )

where

import Core.ColouredPoint
import Core.SimplePoint
import Core.Colour

data Well = Well {
              blocks :: [ColouredPoint],
              size :: SimplePoint
            }
            
--------------------------------------------------------------
createWell :: [ColouredPoint] -> SimplePoint -> Well
createWell blocks size = Well blocks size

generateWell :: SimplePoint -> Well
generateWell (x,y) = Well blocks size
  where 
    size = (x+2,y+3)
    blocks = addBorderBlocks size
         
addBorderBlocks :: SimplePoint -> [ColouredPoint]
addBorderBlocks (x,y) = leftBorderBlocks ++ bottomBorderBlocks ++ rightBorderBlocks
  where 
    leftBorderBlocks   = [(0,j,Grey_Colour) | j <- [1..(y-1)]]
    bottomBorderBlocks = [(i,0,Grey_Colour) | i <- [0..(x-1)]]
    rightBorderBlocks  = [(x-1,j,Grey_Colour) | j <- [1..(y-1)]]
    
-------------------------------------------------------------- 
    
getBlocksFromWell :: Well -> [ColouredPoint]
getBlocksFromWell = blocks

getSizeFromWell :: Well -> SimplePoint
getSizeFromWell = size

--------------------------------------------------------------
    
splitLinesOfBlocksAtFullLine :: Int -> [[ColouredPoint]] -> ([[ColouredPoint]],[ColouredPoint],[[ColouredPoint]])
splitLinesOfBlocksAtFullLine fullLineSize wellLines = (beforeFullLine,fullLine,afterFullLine)
  where 
    (beforeFullLine,fullLineAndRest) = span ((< fullLineSize).length) wellLines
    (fullLine,afterFullLine) = if (fullLineAndRest == []) then ([],[]) else (head fullLineAndRest, tail fullLineAndRest)
    
moveLinesOfBlocksDown :: [ColouredPoint] -> [[ColouredPoint]] -> [[ColouredPoint]]
moveLinesOfBlocksDown fullContentsLine beforeContentsLines
  = if (fullContentsLine /= []) 
      then map (map moveColouredPointDown) beforeContentsLines 
      else beforeContentsLines

clearFullLineFromWell :: Well -> Well
clearFullLineFromWell (Well blocks (sizeX,sizeY)) = Well newBlocks (sizeX,sizeY)
  where 
    -- extract and structure blocks for use
    (wellBorderBlocks,wellContentsBlocks) = extractColouredPoints Grey_Colour blocks
    wellContentsLines = getLinesOfColouredPoints wellContentsBlocks
    -- split lines at full line and move lines before full line downwards
    (beforeContentsLines,fullContentsLine,afterContentsLines) = splitLinesOfBlocksAtFullLine (truncate (sizeX-2)) wellContentsLines      
    updatedBeforeContentsLines = moveLinesOfBlocksDown fullContentsLine beforeContentsLines
    -- convert lines back to blocks and create one list
    updatedBeforeContentsBlocks = getColouredPointsFromLines updatedBeforeContentsLines
    afterContentsBlocks = getColouredPointsFromLines afterContentsLines       
    newBlocks = updatedBeforeContentsBlocks ++ afterContentsBlocks ++ wellBorderBlocks
    
--------------------------------------------------------------

clearFullLinesFromWell :: Well -> Int -> (Well,Int)
clearFullLinesFromWell well currentTimes = (newWell,newTimes)
  where tempWell = clearFullLineFromWell well
        hasClearedLines = (length (blocks well) /= length (blocks tempWell))
        (newWell,newTimes) = if (hasClearedLines)
                               then clearFullLinesFromWell tempWell (currentTimes+1)
                               else (well,currentTimes)
    
--------------------------------------------------------------
gameEndWell :: Well -> Well
gameEndWell (Well blocks size) = Well (convertAllColouredPointsToColour Dark_Grey_Colour blocks) size