1
Fork 0

fsharp(ygosim): feat: finally found a good way of doing the client stuff

Signed-off-by: prescientmoon <git@moonythm.dev>
This commit is contained in:
Matei Adriel 2019-12-10 16:09:06 +02:00 committed by prescientmoon
parent f2bca7d3f0
commit b3f374162e
Signed by: prescientmoon
SSH key fingerprint: SHA256:UUF9JT2s8Xfyv76b8ZuVL7XrmimH4o49p4b+iexbVH4
2 changed files with 42 additions and 67 deletions

View file

@ -41,8 +41,7 @@ module Player =
side: Side<'s> side: Side<'s>
hand: CardInstance<'s> list hand: CardInstance<'s> list
state: PlayerState state: PlayerState
id: int id: int }
lastInitialDraw: int }
module Player = module Player =
let inline lifePoints f player = f player.lifePoints <&> fun v -> { player with lifePoints = v } let inline lifePoints f player = f player.lifePoints <&> fun v -> { player with lifePoints = v }
@ -50,7 +49,6 @@ module Player =
let inline hand f player = f player.hand <&> fun v -> { player with hand = v } let inline hand f player = f player.hand <&> fun v -> { player with hand = v }
let inline state f player = f player.state <&> fun v -> { player with state = v } let inline state f player = f player.state <&> fun v -> { player with state = v }
let inline _id f player = f player.id <&> fun v -> { player with id = v } let inline _id f player = f player.id <&> fun v -> { player with id = v }
let inline lastInitialDraw f player = f player.lastInitialDraw <&> fun v -> { player with lastInitialDraw = v }
let inline deck f player = (side << Side.deck) f player let inline deck f player = (side << Side.deck) f player
@ -59,8 +57,7 @@ module Player =
side = emptySide side = emptySide
hand = [] hand = []
state = InGame state = InGame
id = id id = id }
lastInitialDraw = -1 }
module Turn = module Turn =
type Phase = type Phase =
@ -103,7 +100,6 @@ module Board =
else (players << _1) f board else (players << _1) f board
let inline currentPlayerId f board = (currentPlayer << Player._id) f board let inline currentPlayerId f board = (currentPlayer << Player._id) f board
let inline currentPlayerLastDraw f board = (currentPlayer << Player.lastInitialDraw) f board
let inline currentPlayerState f board = (currentPlayer << Player.state) f board let inline currentPlayerState f board = (currentPlayer << Player.state) f board
let inline currentPlayerDeck f board = (currentPlayer << Player.deck) f board let inline currentPlayerDeck f board = (currentPlayer << Player.deck) f board
let inline currentPlayerHand f board = (currentPlayer << Player.hand) f board let inline currentPlayerHand f board = (currentPlayer << Player.hand) f board
@ -125,55 +121,56 @@ module Board =
module Game = module Game =
open Turn open Turn
open Player open Player
open Side
open Board open Board
type PlayerAction = type Log =
| Pass | CardToHand of string
| NormalSummon | NewPhase of Phase
| InitialDraw | StateChanged of PlayerState
| Activate
| Set
type ClientCommand = Log of string type Client = Log -> int
type ClientResult =
| Zone of int
| Bool of int
| NoResult
type Client = ClientCommand -> ClientResult
let isCurrentPlayer (board: Board) (player: Player) = (board ^. Board.currentPlayerId) = player.id let isCurrentPlayer (board: Board) (player: Player) = (board ^. Board.currentPlayerId) = player.id
let canDrawCard (board: Board) (player: Player) = let canDrawCard (board: Board) (player: Player) =
isCurrentPlayer board player && board ^. Board.currentPlayerLastDraw <> board ^. Board.turn isCurrentPlayer board player && board ^. Board.phase = Draw && board ^. Board.turn <> 0
&& board ^. Board.phase = Draw && board ^. Board.turn <> 0
let draw (board: Board) = let draw (board: Board) =
match board ^. Board.currentPlayerDeck with match board ^. Board.currentPlayerDeck with
| [] -> board |> Board.currentPlayerState .-> Lost "deckout" | [] -> board |> Board.currentPlayerState .-> PlayerState.Lost "deckout"
| card :: deck -> | card :: deck ->
let hand = card :: (board ^. Board.currentPlayerHand) let hand = card :: (board ^. Board.currentPlayerHand)
let turn = board ^. Board.turn
board board
|> Board.currentPlayerHand .-> hand |> Board.currentPlayerHand .-> hand
|> Board.currentPlayerDeck .-> deck |> Board.currentPlayerDeck .-> deck
|> Board.currentPlayerLastDraw .-> turn
let toDeckBottom (card: CardInstance) (player: Player) = over Player.deck (fun d -> card :: d) player let toDeckBottom (card: CardInstance) (player: Player) = over Player.deck (fun d -> card :: d) player
let processAction (client: Client) (board: Board) (player: Player) (action: PlayerAction) = let processPhase client board =
match action with match board ^. Board.phase with
| InitialDraw -> | Draw -> draw board
if canDrawCard board player then | _ -> board
(draw board, true)
else let switchPhases (client: Client) board =
client <| Log "cannot draw card" |> ignore let newBoard = over Board.moment nextPhase board
(board, false)
| Pass -> NewPhase <| newBoard ^. Board.phase
if isCurrentPlayer board player then (over Board.moment nextPhase board, true) |> client
else (board, false) |> ignore
| _ -> (board, true)
newBoard
let rec game board (client: Client) =
let newBoard =
(processPhase client)
>> (switchPhases client)
<| board
let currentState = newBoard ^. Board.currentPlayerState
if currentState <> InGame then
client <| StateChanged currentState |> ignore
failwith "end of game"
else
game newBoard client

View file

@ -9,35 +9,13 @@
let sampleCard = Card.Spell ({name= "sampleCard"; text="something"; effects = []}, {spellType = Card.ContinuosSpell}) let sampleCard = Card.Spell ({name= "sampleCard"; text="something"; effects = []}, {spellType = Card.ContinuosSpell})
let board = over Board.currentPlayer <| toDeckBottom sampleCard <| emptyBoard let board = over Board.currentPlayer <| toDeckBottom sampleCard <| emptyBoard
let consoleClient command = let client action =
match command with match action with
| Log message -> | StateChanged newState -> printfn "The new state you got is: %A" newState
printfn "%s" message | NewPhase phase -> printfn "New phse: %A" phase
NoResult | _ -> printfn "Something unkown happened"
// | _ -> NoResult
let parseAction _ = 0
printf "What action do you want to do?"
let stringified = System.Console.ReadLine() game board client
match stringified with
| "draw" -> InitialDraw
| "pass" -> Pass
| _ -> failwith "unknown command"
let rec loop board =
let action = parseAction
let (newBoard, success) = processAction consoleClient board <| board^. Board.currentPlayer <| action()
if success then
printfn "%A" newBoard
printfn "%b" success
loop newBoard
loop board
0 0