-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* finished creation of Game module * we should commit this
- Loading branch information
Showing
6 changed files
with
479 additions
and
348 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,281 @@ | ||
module Game exposing | ||
( Cell | ||
, GameStatus(..) | ||
, Model(..) | ||
, Msg(..) | ||
, Player(..) | ||
, Turn(..) | ||
, currentStatus | ||
, gameboard | ||
, init | ||
, nameToString | ||
, pieceToString | ||
, playerToString | ||
, remainingPieces | ||
, update | ||
) | ||
|
||
import Dict | ||
import Game.Board as Board | ||
exposing | ||
( Board | ||
, BoardStatus(..) | ||
) | ||
import Game.Core exposing (Cellname(..), Gamepiece) | ||
import Helpers exposing (andThen, map, noCmds, withCmd) | ||
import List.Nonempty as Listn | ||
import Process | ||
import Random | ||
import Shared exposing (Model) | ||
import Task | ||
|
||
|
||
|
||
-- DOMAIN | ||
|
||
|
||
type Player | ||
= Human | ||
| Computer | ||
|
||
|
||
type alias ActivePlayer = | ||
Player | ||
|
||
|
||
type alias Winner = | ||
Player | ||
|
||
|
||
type alias Cell = | ||
{ name : Cellname | ||
, status : Maybe Gamepiece | ||
} | ||
|
||
|
||
type alias ChosenPiece = | ||
Gamepiece | ||
|
||
|
||
type GeneratorOptions | ||
= GetGamepiece | ||
| GetCell | ||
|
||
|
||
type Turn | ||
= ChoosingPiece | ||
| ChoosingCellToPlay ChosenPiece | ||
|
||
|
||
type GameStatus | ||
= InPlay ActivePlayer Turn | ||
| Won Winner | ||
| Draw | ||
|
||
|
||
type Model | ||
= Model { board : Board, status : GameStatus } | ||
|
||
|
||
|
||
-- INIT | ||
|
||
|
||
initStatus : GameStatus | ||
initStatus = | ||
InPlay Human ChoosingPiece | ||
|
||
|
||
init : Model | ||
init = | ||
Model { board = Board.init, status = initStatus } | ||
|
||
|
||
|
||
-- Msg | ||
|
||
|
||
type Msg | ||
= HumanSelectedPiece Gamepiece | ||
| HumanSelectedCell Cellname | ||
| RestartWanted | ||
| ComputerSelectedCell Cellname | ||
| ComputerSelectedPiece Gamepiece | ||
| NoOp | ||
|
||
|
||
|
||
-- UPDATE | ||
|
||
|
||
update : Msg -> Model -> ( Model, Cmd Msg ) | ||
update msg (Model model) = | ||
case ( msg, model.status ) of | ||
( HumanSelectedPiece piece, InPlay Human ChoosingPiece ) -> | ||
Model model | ||
|> noCmds | ||
|> map (nextPlayerStartsPlaying Human piece) | ||
|> withCmd (wait 2) | ||
|> andThen (computerChooses GetCell) | ||
|
||
( ComputerSelectedCell name, InPlay Computer (ChoosingCellToPlay piece) ) -> | ||
Model model | ||
|> noCmds | ||
|> map (playerMakesPlay name piece) | ||
|> andThen (checkForWin Computer) | ||
|
||
( ComputerSelectedPiece piece, InPlay Computer ChoosingPiece ) -> | ||
Model model | ||
|> noCmds | ||
|> map (nextPlayerStartsPlaying Computer piece) | ||
|
||
( HumanSelectedCell name, InPlay Human (ChoosingCellToPlay piece) ) -> | ||
Model model | ||
|> noCmds | ||
|> map (playerMakesPlay name piece) | ||
|> andThen (checkForWin Human) | ||
|
||
( RestartWanted, _ ) -> | ||
init |> noCmds | ||
|
||
( NoOp, _ ) -> | ||
Model model |> noCmds | ||
|
||
_ -> | ||
Model model |> noCmds | ||
|
||
|
||
nextPlayerStartsPlaying : ActivePlayer -> Gamepiece -> Model -> Model | ||
nextPlayerStartsPlaying player piece (Model model) = | ||
Model { model | status = InPlay (switch player) (ChoosingCellToPlay piece) } | ||
|
||
|
||
computerChooses : GeneratorOptions -> Model -> ( Model, Cmd Msg ) | ||
computerChooses opt (Model model) = | ||
let | ||
helper : (a -> Msg) -> List a -> ( Model, Cmd Msg ) | ||
helper msg lst = | ||
lst | ||
|> Listn.fromList | ||
|> Maybe.map | ||
(\items -> | ||
( Model model, Random.generate msg (Listn.sample items) ) | ||
) | ||
|> Maybe.withDefault (Model model |> noCmds) | ||
in | ||
case opt of | ||
GetCell -> | ||
Board.openCells model.board | ||
|> helper ComputerSelectedCell | ||
|
||
GetGamepiece -> | ||
Board.unPlayedPieces model.board | ||
|> helper ComputerSelectedPiece | ||
|
||
|
||
playerMakesPlay : Cellname -> Gamepiece -> Model -> Model | ||
playerMakesPlay name piece (Model model) = | ||
let | ||
newBoard = | ||
Board.update name piece model.board | ||
in | ||
Model { model | board = newBoard } | ||
|
||
|
||
checkForWin : ActivePlayer -> Model -> ( Model, Cmd Msg ) | ||
checkForWin player (Model ({ board, status } as model)) = | ||
case ( player, Board.status board ) of | ||
( Computer, CanContinue ) -> | ||
Model model | ||
|> noCmds | ||
|> map (playerStartsChoosing Computer) | ||
|> withCmd (wait 2) | ||
|> andThen (computerChooses GetGamepiece) | ||
|
||
( Human, CanContinue ) -> | ||
Model model | ||
|> noCmds | ||
|> map (playerStartsChoosing Human) | ||
|
||
( _, MatchFound ) -> | ||
Model { model | status = Won player } | ||
|> noCmds | ||
|
||
( _, Full ) -> | ||
Model { model | status = Draw } |> noCmds | ||
|
||
|
||
playerStartsChoosing : Player -> Model -> Model | ||
playerStartsChoosing player (Model model) = | ||
Model { model | status = InPlay player ChoosingPiece } | ||
|
||
|
||
|
||
-- Cmd Msg | ||
|
||
|
||
type Seconds | ||
= Seconds Int | ||
|
||
|
||
wait : Int -> Cmd Msg | ||
wait i = | ||
delay (Seconds i) NoOp | ||
|
||
|
||
delay : Seconds -> Msg -> Cmd Msg | ||
delay (Seconds time) msg = | ||
Process.sleep (toFloat <| time * 1000) | ||
|> Task.andThen (always <| Task.succeed msg) | ||
|> Task.perform identity | ||
|
||
|
||
|
||
-- UTILITY | ||
|
||
|
||
switch : ActivePlayer -> ActivePlayer | ||
switch player = | ||
if player == Human then | ||
Computer | ||
|
||
else | ||
Human | ||
|
||
|
||
gameboard : Model -> (Cellname -> Cell) | ||
gameboard (Model model) = | ||
\name -> | ||
Board.playedPieces model.board | ||
|> Dict.get (Board.nameToString name) | ||
|> Cell name | ||
|
||
|
||
remainingPieces : Model -> List Gamepiece | ||
remainingPieces (Model model) = | ||
Board.unPlayedPieces model.board | ||
|
||
|
||
currentStatus : Model -> GameStatus | ||
currentStatus (Model model) = | ||
model.status | ||
|
||
|
||
playerToString : Player -> String | ||
playerToString player = | ||
case player of | ||
Human -> | ||
"Human" | ||
|
||
Computer -> | ||
"Computer" | ||
|
||
|
||
nameToString : Cellname -> String | ||
nameToString = | ||
Board.nameToString | ||
|
||
|
||
pieceToString : Gamepiece -> String | ||
pieceToString = | ||
Board.pieceToString |
Oops, something went wrong.