<commit_before>module Main where

import Control.Lens

data Card =
  NumberCard Int
  | BuffCard Location Int

data Location = Board | Hand | Deck -- | Mult Location Location

type Board = [Card]
type Hand = [Card]
type Deck = [Card]

data PlayerState = PlayerState
  { hand :: Hand
  , deck :: Deck
  , board :: Board
  }

type GameState = [PlayerState]

type PlayerTurn = Int

playCard :: PlayerTurn -> Card -> GameState -> GameState
playCard pt c@(NumberCard nc) gameState = set (element pt) newPlayerState gameState where
  playerState = gameState !! pt
  newPlayerState = set (element 0) c (board playerState)

main :: IO ()
main = do
  putStrLn "hello world"<commit_msg>most basic working engine, using lenses<commit_after>{-# LANGUAGE TemplateHaskell #-}

--module Main where

import Control.Lens

data Card =
  NumberCard Int
  | BuffCard Location Int
  deriving (Show, Eq)

buff f (NumberCard x) = NumberCard (f x)
buff _ c@BuffCard{} = c

data Location = Board | Hand | Deck deriving (Show, Eq)

type Board = [Card]
type Hand = [Card]
type Deck = [Card]

data PlayerState = PlayerState
  { _hand :: Hand
  , _deck :: Deck
  , _board :: Board
  }
  deriving (Show, Eq)

makeLenses ''PlayerState

locAsLens Board = board
locAsLens Hand = hand
locAsLens Deck = hand

data GameState = GameState
  { _playerState :: [PlayerState]
  , _playerTurn :: Int
  }
  deriving (Show)

makeLenses ''GameState

type PlayerTurn = Int
type TurnBound = Int

playCard :: PlayerTurn -> Card -> GameState -> GameState
playCard pt c@NumberCard{} gameState =
  gameState & (playerState . element pt . board . element 0) .~ c
playCard pt (BuffCard loc amount) gameState =
  gameState & (playerState . element pt . locAsLens loc . traverse) %~ buff (+ amount)

drawCard :: PlayerState -> PlayerState
drawCard ps@PlayerState {_deck = [], _hand = _} = ps
-- we can prepend this if the order within hand doesn't matter
-- currently playing cards is based on the first element, so it does
drawCard ps@PlayerState {_deck = (c:d), _hand = h} = ps & deck .~ d & hand .~ h ++ [c]

discardCard :: PlayerState -> PlayerState
discardCard ps@PlayerState {_hand = []} = ps
discardCard ps@PlayerState {_hand = (_:h)} = ps & hand .~ h

executeTurn :: PlayerTurn -> GameState -> GameState
executeTurn pt gameState = afterDiscardCard where
  afterDrawCard = gameState & (playerState . element pt) %~ drawCard
  maybeCardToPlay :: Maybe Card
  maybeCardToPlay = afterDrawCard ^? (playerState . element pt . hand . element 0)
  play :: Maybe Card -> GameState -> GameState
  play (Just c) = playCard pt c
  play Nothing = id
  afterPlayCard = play maybeCardToPlay afterDrawCard
  afterDiscardCard = afterPlayCard & (playerState . element pt) %~ discardCard

advancePlayerTurn :: TurnBound -> PlayerTurn -> PlayerTurn
advancePlayerTurn bound current =
  if candidate > bound
  then 0
  else candidate
  where
  candidate = current + 1

advanceGame :: TurnBound -> GameState -> GameState
advanceGame bound gameState = nextGameState & playerTurn %~ advancePlayerTurn bound where
  nextGameState = executeTurn (_playerTurn gameState) gameState

main :: IO ()
main = do
  putStrLn "hello world"
{'fraction_non_alphanumeric': 0.0979708306911858, 'fraction_numerical': 0.0015852885225110971, 'mean_word_length': 3.9296875, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4755192', 'n_tokens_mistral': 979, 'n_tokens_neox': 968, 'n_words': 347}