packages feed

boardgame-0.0.0.1: executable/ArithmeticProgressionGame.hs

{-# LANGUAGE CPP #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}

module ArithmeticProgressionGame where

import Data.List  (intercalate)

import Boardgame (
    Player(..)
  , Position(..)
  , PositionalGame(..)
  , patternMatchingGameOver
  )

#ifdef WASM
import Data.Aeson (
    ToJSON(..)
  , object
  , (.=)
  )
#endif

-------------------------------------------------------------------------------
-- * Arithmetic Progression Game
-------------------------------------------------------------------------------

data ArithmeticProgressionGame = ArithmeticProgressionGame Int [Position]

createArithmeticProgressionGame :: Int -> Int -> Maybe ArithmeticProgressionGame
createArithmeticProgressionGame n k = if k < n
  then Just $ ArithmeticProgressionGame k (replicate n Empty)
  else Nothing

instance Show ArithmeticProgressionGame where
  show (ArithmeticProgressionGame _ ps) = (\(is, ps) -> intercalate "," is ++ "\n" ++ intercalate "," ps) $
        unzip $ zipWith (\i p -> (pad $ show i, pad $ showP p)) [1..] ps
    where
      showP Empty              = "  _"
      showP (Occupied Player1) = "  \ESC[34mO\ESC[0m"
      showP (Occupied Player2) = "  \ESC[31mX\ESC[0m"
      pad x = replicate (3 - length x) ' ' ++ x

#ifdef WASM
instance ToJSON ArithmeticProgressionGame where
  toJSON (ArithmeticProgressionGame n ps) = object [
      "n"         .= toJSON n
    , "positions" .= toJSON ps
    ]
#endif

instance PositionalGame ArithmeticProgressionGame Int where
  positions   (ArithmeticProgressionGame _ l)     = l
  getPosition (ArithmeticProgressionGame _ l) i   = if i <= length l then Just $ l !! (i - 1) else Nothing
  setPosition (ArithmeticProgressionGame k l) i p = if i <= length l
    then Just $ ArithmeticProgressionGame k (take (i - 1) l ++ p : drop i l)
    else Nothing
  gameOver a@(ArithmeticProgressionGame k l) = let n = length l
    in patternMatchingGameOver (filter (all (<= n)) $ concat [[take k [i,i+j..] | j <- [1..n-i]] | i <- [1..n]]) a