h2048-0.4.0.0: An Implementation of Game 2048

Safe HaskellNone
LanguageHaskell2010

Game.H2048.Gameplay

Description

Game implementation on top of Game.H2048.Core. This module is formally the API for this package, please avoid using Game.H2048.Core directly if possible.

Synopsis

Documentation

data Gameplay Source #

A Gameplay is an obscure data type to keep track of information necessary for a single game play. Its fields can be accessed through functions with _gp prefix.

_gpRule :: Gameplay -> GameRule Source #

Encodes rule of this game. This field must not change after creation.

_gpScore :: Gameplay -> Int Source #

Total score currently collected.

_gpBoard :: Gameplay -> GameBoard Source #

The Game board. If this field is an empty map, that means the game is not yet started.

_gpGen :: Gameplay -> TFGen Source #

Random generator.

randomOp :: (TFGen -> (a, TFGen)) -> Gameplay -> (a, Gameplay) Source #

Lift a function that mutates a TFGen to produce some results to work on Gameplay.

mkGameplay :: TFGen -> GameRule -> Gameplay Source #

Create a Gameplay. Note that the return value must be passed to newGame before it can accept any game moves.

The purpose of this two-step approach (i.e. mkGameplay then newGame) is to separate data type creation from the effect of mutating random generator, which is required at the beginning of a game.

spawnNewCell :: Gameplay -> Set Coord -> Maybe (((Coord, Cell), Set Coord), Gameplay) Source #

spawnNewCell gameplay emptyCells picks an empty cell from emptyCells, and assign it with a cell value. The operation will fail if and only if emptyCells is empty.

Upon successful return, the value wrapped in Just is (sepResult, gameplay') where sepResult indicates coordinate and cell value chosen, and remaining part of emptyCells.

The reason for explicitly passing emptyCells on this operation is to make it easier to pick multiple cells while not touching most parts of Gameplay. In fact you can expect this operation to only mutate the TFGen inside Gameplay.

type GameBoard = Map Coord Cell Source #

A GameBoard is a map from coordinates to Cells for a game.

Note that the map could be empty to indicate that a new game is not started yet.

type CellTier = Int Source #

A CellTier is simply a positive Int. Every time two cell merges, the tier of the resulting cell increases by one relative to cell tier prior to the merge.

data Cell Source #

An obscure data type that wraps CellTier.

Instances
Eq Cell Source # 
Instance details

Defined in Game.H2048.Core

Methods

(==) :: Cell -> Cell -> Bool #

(/=) :: Cell -> Cell -> Bool #

Ord Cell Source # 
Instance details

Defined in Game.H2048.Core

Methods

compare :: Cell -> Cell -> Ordering #

(<) :: Cell -> Cell -> Bool #

(<=) :: Cell -> Cell -> Bool #

(>) :: Cell -> Cell -> Bool #

(>=) :: Cell -> Cell -> Bool #

max :: Cell -> Cell -> Cell #

min :: Cell -> Cell -> Cell #

Show Cell Source # 
Instance details

Defined in Game.H2048.Core

Methods

showsPrec :: Int -> Cell -> ShowS #

show :: Cell -> String #

showList :: [Cell] -> ShowS #

_cTier :: Cell -> CellTier Source #

Tier of this cell.

data Dir Source #

Moves that a user could do.

Constructors

DUp 
DDown 
DLeft 
DRight 
Instances
Bounded Dir Source # 
Instance details

Defined in Game.H2048.Core

Methods

minBound :: Dir #

maxBound :: Dir #

Enum Dir Source # 
Instance details

Defined in Game.H2048.Core

Methods

succ :: Dir -> Dir #

pred :: Dir -> Dir #

toEnum :: Int -> Dir #

fromEnum :: Dir -> Int #

enumFrom :: Dir -> [Dir] #

enumFromThen :: Dir -> Dir -> [Dir] #

enumFromTo :: Dir -> Dir -> [Dir] #

enumFromThenTo :: Dir -> Dir -> Dir -> [Dir] #

Eq Dir Source # 
Instance details

Defined in Game.H2048.Core

Methods

(==) :: Dir -> Dir -> Bool #

(/=) :: Dir -> Dir -> Bool #

Ord Dir Source # 
Instance details

Defined in Game.H2048.Core

Methods

compare :: Dir -> Dir -> Ordering #

(<) :: Dir -> Dir -> Bool #

(<=) :: Dir -> Dir -> Bool #

(>) :: Dir -> Dir -> Bool #

(>=) :: Dir -> Dir -> Bool #

max :: Dir -> Dir -> Dir #

min :: Dir -> Dir -> Dir #

Show Dir Source # 
Instance details

Defined in Game.H2048.Core

Methods

showsPrec :: Int -> Dir -> ShowS #

show :: Dir -> String #

showList :: [Dir] -> ShowS #

type Distrib = Distrib' Int Source #

A Distrib is a non-empty Vector whose each element (a,b) satisfies:

  • a, when taken in sequence, is positive and strictly increasing.
  • b, when taken in sequence, is strictly increasing.

Think this data type as a precomputation result for making weighted random choice.

You can use computeDistrib to generate a value of this.

data GameRule Source #

A data type for encoding game rules that do not necessarily needs to be hard-coded into core logic.

You can use standardGameRule for a standard game rule, or make changes using it as the base.

Constructors

GameRule 

Fields

newGame :: Gameplay -> Gameplay Source #

Initialize a Gameplay so that it's ready to play.

This function should only fail when its GameRule dictates too many initial cells for the whole board to contain.

stepGame :: Dir -> Gameplay -> Maybe Gameplay Source #

stepGame d gp tries to apply move d on current state of the game gp, returns:

  • Nothing if this move is invalid (failed to apply the move).
  • Just moves if this move is valid, also returns all possible moves after the board is fully updated (meaning new cell has been spawned).

standardGameRule :: GameRule Source #

The standard game rule. This value can be used as a base for customized game rules.

hasWon :: Gameplay -> Bool Source #

Whether the Gameplay should be considered already won. Queries GameRule embeded in Gameplay.

isAlive :: Gameplay -> Bool Source #

A Gameplay is considered alive if and only if there are still possible moves.

cellToInt :: Cell -> Int Source #

Convert Cell back into a power of 2.

intToCell :: Int -> Maybe Cell Source #

Safely convert a power of two into Cell.

computeDistrib :: IntMap Int -> Distrib Source #

Computes Distrib for weighted random cell tier spawns.

The input must be a non-empty map from cell tiers to their corresponding weight. All weights must be positive.