<commit_before>module Model
  ( Board
  , Player(..)
  , newBoard
  , nextPlayer
  , gameState
  , move
  )
where

import Control.Applicative ((<$>))
import Control.Lens ((^.), (^..), (.~), (&), to, folded)
import Data.Monoid ((<>))
import Data.Maybe (isJust, isNothing)
import Linear (V3(..), _x, _y, _z, transpose)

data Player = X | O
    deriving (Eq, Show)

data Board = Board (V3 (V3 (Maybe Player)))
    deriving (Show)

data GameState =
    InProgress
    | NoMovesLeft
    | Won Player
    deriving (Eq, Show)

nextPlayer :: Player -> Player
nextPlayer X = O
nextPlayer O = X

newBoard :: Board
newBoard = Board (V3 row row row)
    where
        row = V3 Nothing Nothing Nothing

gameState :: Board -> GameState
gameState b =
    if playerWon X b then Won X
    else if playerWon O b then Won O
         else if hasFreeMoves b then InProgress
              else NoMovesLeft

hasFreeMoves :: Board -> Bool
hasFreeMoves (Board m) =
    or $ m^..folded.folded.to isNothing

playerWon :: Player -> Board -> Bool
playerWon p (Board m) =
    or [ playerWonRows p m
       , playerWonRows p $ transpose m
       , playerWonDiagonal p m
       ]

playerWonRows :: Player -> V3 (V3 (Maybe Player)) -> Bool
playerWonRows p m =
    let v = Just p<commit_msg>Model improvements<commit_after>module Model
  ( Board
  , Player(..)
  , GameStatus(..)
  , newBoard
  , toList
  , nextPlayer
  , gameStatus
  , move
  )
where

import Control.Applicative ((<$>))
import Control.Lens ((^.), (^..), (.~), (&), to, folded)
import Data.Monoid ((<>))
import Data.Maybe (isJust, isNothing)
import Linear (V3(..), _x, _y, _z, transpose)

data Player = X | O
    deriving (Eq, Show)

data Board = Board (V3 (V3 (Maybe Player)))
    deriving (Show)

data GameStatus =
    InProgress
    | NoMovesLeft
    | Won Player
    deriving (Eq, Show)

nextPlayer :: Player -> Player
nextPlayer X = O
nextPlayer O = X

newBoard :: Board
newBoard = Board (V3 row row row)
    where
        row = V3 Nothing Nothing Nothing

toList :: Board -> [[Maybe Player]]
toList (Board m) = [m^.._x.folded, m^.._y.folded, m^.._z.folded]

gameStatus :: Board -> GameStatus
gameStatus b =
    if playerWon X b then Won X
    else if playerWon O b then Won O
         else if hasFreeMoves b then InProgress
              else NoMovesLeft

hasFreeMoves :: Board -> Bool
hasFreeMoves (Board m) =
    or $ m^..folded.folded.to isNothing

playerWon :: Player -> Board -> Bool
playerWon p (Board m) =
    or [ playerWonRows p m
       , playerWonRows p $ transpose m
       , playerWonDiagonal p m
       ]

playerWonRows :: Player -> V3 (V3 (Maybe Player)) -> Bool
playerWonRows p m =
    let v = Just p
{'fraction_non_alphanumeric': 0.12010542168674698, 'fraction_numerical': 0.005271084337349397, 'mean_word_length': 2.7212885154061626, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 22, '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': '4499268', 'n_tokens_mistral': 922, 'n_tokens_neox': 911, 'n_words': 304}