Browse Source

even moar refactoring

adaptedStrategy0
Slash 9 years ago
parent
commit
353b9d063b
4 changed files with 53 additions and 33 deletions
  1. +12
    -0
      src/Datatypes/Game.hs
  2. +1
    -1
      src/Datatypes/Unit.hs
  3. +3
    -2
      src/Strategy0.hs
  4. +37
    -30
      src/VM.hs

+ 12
- 0
src/Datatypes/Game.hs View File

@ -1,9 +1,12 @@
module Datatypes.Game (Game(..), completed) where module Datatypes.Game (Game(..), completed) where
import Data.Hashable (hash)
import Data.Set (Set) import Data.Set (Set)
import qualified Data.Set as Set
import Datatypes.Board (Board) import Datatypes.Board (Board)
import Datatypes.Unit (Unit) import Datatypes.Unit (Unit)
import qualified Datatypes.Unit as Unit
type UnitHash = Int type UnitHash = Int
@ -18,3 +21,12 @@ data Game = Game {
completed :: Game -> Bool completed :: Game -> Bool
completed game = null $ units game completed game = null $ units game
new :: Board -> [Unit] -> Game
new b us = Game {
board = b,
units = (c:cs),
visitedUnits = Set.singleton (hash c),
oldLines = 0,
score = 0
} where (c:cs) = map (flip Unit.centeredIn b) us

+ 1
- 1
src/Datatypes/Unit.hs View File

@ -1,4 +1,4 @@
module Datatypes.Unit (Unit(..), map, collidesWith, isOutsideOf, mergeWith) where
module Datatypes.Unit (Unit(..), map, centeredIn, collidesWith, isOutsideOf, mergeWith) where
import Prelude hiding (map) import Prelude hiding (map)


+ 3
- 2
src/Strategy0.hs View File

@ -1,6 +1,7 @@
module Strategy0 where module Strategy0 where
import Datatypes import Datatypes
import qualified Datatypes.Game as Game
import VM import VM
seswlist = cycle [MoveSE, MoveSW] seswlist = cycle [MoveSE, MoveSW]
@ -16,7 +17,7 @@ stepr game = if notes == GameOver
else (1 + (fst new_step), snd new_step) else (1 + (fst new_step), snd new_step)
where where
(new_game,notes) = step game MoveSE (new_game,notes) = step game MoveSE
score = points new_game
score = Game.score new_game
new_step = (stepl new_game) new_step = (stepl new_game)
stepl :: Game -> (Int,Int) stepl :: Game -> (Int,Int)
@ -25,6 +26,6 @@ stepl game = if notes == GameOver
else (1 + (fst new_step), snd new_step) else (1 + (fst new_step), snd new_step)
where where
(new_game,notes) = step game MoveSW (new_game,notes) = step game MoveSW
score = points new_game
score = Game.score new_game
new_step = (stepr new_game) new_step = (stepr new_game)

+ 37
- 30
src/VM.hs View File

@ -12,6 +12,14 @@ import qualified Datatypes.Game as Game
import Datatypes.Unit (Unit(..)) import Datatypes.Unit (Unit(..))
import qualified Datatypes.Unit as Unit import qualified Datatypes.Unit as Unit
data Command = MoveW
| MoveE
| MoveSW
| MoveSE
| RotateClockwise
| RotateCounterclockwise
deriving (Show,Eq)
data Notes = OK data Notes = OK
| GameOver | GameOver
| Lock { rowsCleaned :: Int } | Lock { rowsCleaned :: Int }
@ -28,14 +36,6 @@ cmdToString (RotateClockwise:cs) = 'd' : cmdToString cs
cmdToString (RotateCounterclockwise:cs) = 'k' : cmdToString cs cmdToString (RotateCounterclockwise:cs) = 'k' : cmdToString cs
cmdToString [] = [] cmdToString [] = []
data Command = MoveW
| MoveE
| MoveSW
| MoveSE
| RotateClockwise
| RotateCounterclockwise
deriving (Show,Eq)
moveScore :: Int -> Int -> Int -> Int moveScore :: Int -> Int -> Int -> Int
moveScore size lines linesOld = points + lineBonus where moveScore size lines linesOld = points + lineBonus where
points = size + 100 * ((1 + lines) * lines) `div` 2 points = size + 100 * ((1 + lines) * lines) `div` 2
@ -44,28 +44,29 @@ moveScore size lines linesOld = points + lineBonus where
else 0 else 0
checkSpawn :: Game -> Game checkSpawn :: Game -> Game
checkSpawn game@(Game _ [] _ _ _) = game
checkSpawn game@(Game board (u:us) oldPos _ _) = if u `Unit.collidesWith` board
then game { Game.units = [] }
else game
checkSpawn game@(Game { units = [] }) = game
checkSpawn game@(Game { units = (u:us), board = b }) =
if u `Unit.collidesWith` b
then game { Game.units = [] }
else game
lockUnit :: Game -> Game lockUnit :: Game -> Game
lockUnit game = game { lockUnit game = game {
board = newBoard, board = newBoard,
units = us,
units = otherUnits,
visitedUnits = Set.empty, visitedUnits = Set.empty,
oldLines = clearedLines, oldLines = clearedLines,
score = Game.score game + newScore score = Game.score game + newScore
} where } where
(u:us) = Game.units game
mergedBoard = u `Unit.mergeWith` (Game.board game)
(currentUnit:otherUnits) = Game.units game
mergedBoard = currentUnit `Unit.mergeWith` (Game.board game)
(newBoard, clearedLines) = Board.clearLines mergedBoard (newBoard, clearedLines) = Board.clearLines mergedBoard
size = Set.size $ Unit.members u
size = Set.size $ Unit.members currentUnit
newScore = moveScore size clearedLines (Game.oldLines game) newScore = moveScore size clearedLines (Game.oldLines game)
testStep = let unit = Unit (0, 0) (Set.fromList [(2,9)]) testStep = let unit = Unit (0, 0) (Set.fromList [(2,9)])
board = Board 5 10 (Set.fromList [(0,8),(1,8),(0,9),(1,9),(4,8),(3,9),(4,9)]) board = Board 5 10 (Set.fromList [(0,8),(1,8),(0,9),(1,9),(4,8),(3,9),(4,9)])
in step (Game board [unit] (Set.fromList []) 0 0) MoveSW
in step (Game board [unit] (Set.fromList []) 0 0) MoveSW
testStep2 = let unit = Unit (2, 4) (Set.fromList [(0,3),(1,3),(2,3),(3,3),(1,4),(2,4),(3,4), (1,5),(2,5),(2,6)]) testStep2 = let unit = Unit (2, 4) (Set.fromList [(0,3),(1,3),(2,3),(3,3),(1,4),(2,4),(3,4), (1,5),(2,5),(2,6)])
board = Board 6 10 (Set.fromList [(0,8),(0,9),(4,6),(3,7),(4,7),(3,8),(4,8),(2,9),(3,9),(4,9),(5,8),(5,9)]) board = Board 6 10 (Set.fromList [(0,8),(0,9),(4,6),(3,7),(4,7),(3,8),(4,8),(2,9),(3,9),(4,9),(5,8),(5,9)])
@ -77,21 +78,27 @@ testStep2 = let unit = Unit (2, 4) (Set.fromList [(0,3),(1,3),(2,3),(3,3),(1,4),
testStep3 = let unit = Unit (0, 0) (Set.fromList [(2,9)]) testStep3 = let unit = Unit (0, 0) (Set.fromList [(2,9)])
board = Board 5 10 (Set.fromList [(0,8),(1,8),(0,9),(1,9),(4,8),(3,9),(4,9)]) board = Board 5 10 (Set.fromList [(0,8),(1,8),(0,9),(1,9),(4,8),(3,9),(4,9)])
in step (Game board [unit] (Set.fromList []) 0 0) MoveSW
in step (Game board [unit] (Set.fromList []) 0 0) MoveSW
step :: Game -> Command -> (Game, Notes) step :: Game -> Command -> (Game, Notes)
step game@(Game _ [] _ _ _) command = (game, ErrorGameEnded)
step game@(Game board (unit:us) oldPositions o l) command =
if newUnit `Unit.collidesWith` board || newUnit `Unit.isOutsideOf` board
then let final = checkSpawn (lockUnit game) in
(if Game.completed final then (final, GameOver) else (final, Lock 0))
else
if Set.member (hash newUnit) oldPositions
then (Game board (newUnit:us) oldPositions o l, ErrorSamePosition)
else (Game board (newUnit:us) newOldPositions o l, OK)
where
newUnit = applyCommand unit command
newOldPositions = Set.insert (hash newUnit) oldPositions
step game@(Game { units = [] }) command = (game, ErrorGameEnded)
step game command =
if shouldLock
then
if Game.completed updatedGame
then (updatedGame, GameOver)
else (updatedGame, Lock (Game.oldLines updatedGame))
else
if Set.member (hash newUnit) (Game.visitedUnits game)
then (game { units = newUnit:otherUnits }, ErrorSamePosition)
else (game { units = newUnit:otherUnits, visitedUnits = newVisitedUnits }, OK)
where
(unit:otherUnits) = Game.units game
newUnit = applyCommand unit command
board = Game.board game
shouldLock = newUnit `Unit.collidesWith` board || newUnit `Unit.isOutsideOf` board
newVisitedUnits = Set.insert (hash newUnit) (Game.visitedUnits game)
updatedGame = checkSpawn $ lockUnit game
applyCommand :: Unit -> Command -> Unit applyCommand :: Unit -> Command -> Unit
applyCommand unit MoveW = Unit.map move unit where applyCommand unit MoveW = Unit.map move unit where


Loading…
Cancel
Save