From eab212c0394bd4592adb619080de1a0cdf6e7850 Mon Sep 17 00:00:00 2001
From: Matei Adriel <rafaeladriel11@gmail.com>
Date: Sat, 7 Dec 2019 19:31:53 +0200
Subject: [PATCH] fsharp(ygosim): feat: added the basic drawing and next-turn
 stuff

Signed-off-by: prescientmoon <git@moonythm.dev>
---
 fsharp/ygosim/src/Board.fs   | 90 ++++++++++++++++++++++++++++++++----
 fsharp/ygosim/src/Card.fs    |  7 ++-
 fsharp/ygosim/src/Program.fs | 19 +++++++-
 3 files changed, 103 insertions(+), 13 deletions(-)

diff --git a/fsharp/ygosim/src/Board.fs b/fsharp/ygosim/src/Board.fs
index 69e349e..273f94b 100644
--- a/fsharp/ygosim/src/Board.fs
+++ b/fsharp/ygosim/src/Board.fs
@@ -4,11 +4,11 @@ module Side =
     open Card
 
     type Side =
-        { field: Card option
-          monsters: Card list
-          spells: Card list
-          graveyard: Card list
-          deck: Card list }
+        { field: CardInstance option
+          monsters: CardInstance list
+          spells: CardInstance list
+          graveyard: CardInstance list
+          deck: CardInstance list }
 
     let emptySide =
         { field = None
@@ -20,23 +20,95 @@ module Side =
 
 module Player =
     open Side
+    open Card
 
     type Player =
         { lifePoints: int
-          side: Side }
+          side: Side
+          hand: CardInstance list }
 
     let inflictDamage (player: Player) amount = { player with lifePoints = player.lifePoints - amount }
 
     let initialPlayer lp =
         { lifePoints = lp
-          side = emptySide }
+          side = emptySide
+          hand = [] }
 
+module Turn =
+    type Phase =
+        | Draw
+        | Standby
+        | Main1
+        | Battle
+        | Main2
+        | End
 
+    let nextPhase (previous: Phase) (turn: int) =
+        match previous with
+        | Draw -> (Standby, turn)
+        | Standby -> (Main1, turn)
+        | Main1 -> (Battle, turn)
+        | Battle -> (Main2, turn)
+        | Main2 -> (End, turn)
+        | End -> (Draw, turn + 1)
 
 module Board =
     open Player
+    open Turn
 
     type Board =
-        { players: Player * Player }
+        { players: Player * Player
+          turn: int
+          phase: Phase }
 
-    let emptyBoard = { players = (initialPlayer 8000, initialPlayer 8000) }
+    let emptyBoard =
+        { players = (initialPlayer 8000, initialPlayer 8000)
+          turn = 0
+          phase = Draw }
+
+module Game =
+    open Board
+    open Turn
+    open Player
+    open Card
+
+    let draw (player: Player) =
+        match player.side.deck with
+        | [] -> player // TODO: makes this end the game
+        | card :: deck ->
+            { player with
+                  hand = card :: player.hand
+                  side = { player.side with deck = deck } }
+
+    // Player is the last arg to be able to use this with the withCurrentPlayer function
+    let toDeckBottom (card: CardInstance) (player: Player) =
+        { player with side = { player.side with deck = card :: player.side.deck } }
+
+    let currentPlayer (board: Board) =
+        let (first, second) = board.players
+
+        if board.turn % 2 = 0 then first
+        else second
+
+    let withCurrentPlayer callback board =
+        let (first, second) = board.players
+
+        let players =
+            if board.turn % 2 = 0 then (callback first, second)
+            else (first, callback second)
+
+        { board with players = players }
+
+
+    let processTurn (board: Board) =
+        match board.phase with
+        | Draw -> withCurrentPlayer draw board
+        | _ -> board
+
+    let doTurn (board: Board) =
+        let newBoard = processTurn board
+        let (phase, turn) = nextPhase newBoard.phase newBoard.turn
+
+        { newBoard with
+              turn = turn
+              phase = phase }
diff --git a/fsharp/ygosim/src/Card.fs b/fsharp/ygosim/src/Card.fs
index bad35db..87fa4e3 100644
--- a/fsharp/ygosim/src/Card.fs
+++ b/fsharp/ygosim/src/Card.fs
@@ -55,10 +55,10 @@ type Race =
     | Zombie
 
 type SpellCardDetails =
-    { _type: SpellCardType }
+    { spellType: SpellCardType }
 
 type TrapCardDetails =
-    { _type: TrapCardType }
+    { trapType: TrapCardType }
 
 
 type MonsterCardDetails =
@@ -72,3 +72,6 @@ type Card =
     | Monster of BaseCard * MonsterCardDetails
     | Spell of BaseCard * SpellCardDetails
     | Trap of BaseCard * TrapCardDetails
+
+// TODO: actually make this do what its supposed to
+type CardInstance = Card
diff --git a/fsharp/ygosim/src/Program.fs b/fsharp/ygosim/src/Program.fs
index f626d93..1780e8b 100644
--- a/fsharp/ygosim/src/Program.fs
+++ b/fsharp/ygosim/src/Program.fs
@@ -1,5 +1,20 @@
 module Main =
+    open Board
+    open Card
+    open Game
+
     [<EntryPoint>]
     let main argv =
-        printfn "Hello World from F#!"
-        0 // return an integer exit code
+        let board = Board.emptyBoard
+        let sampleCard = Spell ({name= "sampleCard"; text="something"}, {spellType = Card.ContinuosSpell})
+
+        let (first, second) = board.players
+        let secondBoard = withCurrentPlayer <| Game.toDeckBottom sampleCard <| board
+
+        printfn "%A" secondBoard
+
+        let thirdBoard = doTurn secondBoard
+
+        printfn "%A" thirdBoard
+
+        0