fsharp(ygosim): feat: added a lot more stuff to normal summoning
Signed-off-by: prescientmoon <git@moonythm.dev>
This commit is contained in:
parent
4b511c12d3
commit
79726d5ac5
|
@ -3,7 +3,7 @@ module Board
|
||||||
open FSharpPlus.Lens
|
open FSharpPlus.Lens
|
||||||
|
|
||||||
module Side =
|
module Side =
|
||||||
open Card.Card
|
open Card.CardInstance
|
||||||
|
|
||||||
type Side<'s> =
|
type Side<'s> =
|
||||||
{ field: CardInstance<'s> option
|
{ field: CardInstance<'s> option
|
||||||
|
@ -31,7 +31,7 @@ module Side =
|
||||||
|
|
||||||
module Player =
|
module Player =
|
||||||
open Side
|
open Side
|
||||||
open Card.Card
|
open Card.CardInstance
|
||||||
|
|
||||||
type PlayerState =
|
type PlayerState =
|
||||||
| InGame
|
| InGame
|
||||||
|
@ -94,11 +94,13 @@ module Board =
|
||||||
|
|
||||||
and Board =
|
and Board =
|
||||||
{ players: Player * Player
|
{ players: Player * Player
|
||||||
moment: int * Phase }
|
moment: int * Phase
|
||||||
|
lastInstanceId: int }
|
||||||
|
|
||||||
module Board =
|
module Board =
|
||||||
let inline players f board = f board.players <&> fun v -> { board with players = v }
|
let inline players f board = f board.players <&> fun v -> { board with players = v }
|
||||||
let inline moment f board = f board.moment <&> fun v -> { board with moment = v }
|
let inline moment f board = f board.moment <&> fun v -> { board with moment = v }
|
||||||
|
let inline lastInstanceId f board = f board.lastInstanceId <&> fun v -> { board with lastInstanceId = v }
|
||||||
|
|
||||||
let inline turn f board = (moment << _1) f board
|
let inline turn f board = (moment << _1) f board
|
||||||
let inline phase f board = (moment << _2) f board
|
let inline phase f board = (moment << _2) f board
|
||||||
|
@ -113,13 +115,14 @@ module Board =
|
||||||
let inline currentPlayerHand f board = (currentPlayer << Player.hand) f board
|
let inline currentPlayerHand f board = (currentPlayer << Player.hand) f board
|
||||||
let inline currentPlayerLastNormalSummon f board = (currentPlayer << Player.lastNormalSummon) f board
|
let inline currentPlayerLastNormalSummon f board = (currentPlayer << Player.lastNormalSummon) f board
|
||||||
let inline currentPlayerMonsters f board = (currentPlayer << Player.monsters) f board
|
let inline currentPlayerMonsters f board = (currentPlayer << Player.monsters) f board
|
||||||
|
let inline currentPlayerSide f board = (currentPlayer << Player.side) f board
|
||||||
|
|
||||||
let inline firstPlayer f board = (players << _1) f board
|
let inline firstPlayer f board = (players << _1) f board
|
||||||
let inline secondPlayer f board = (players << _2) f board
|
let inline secondPlayer f board = (players << _2) f board
|
||||||
|
|
||||||
type Card = Card.Card<Board>
|
type Card = Card.Card<Board>
|
||||||
|
|
||||||
type CardInstance = Card.CardInstance<Board>
|
type CardInstance = CardInstance.CardInstance<Board>
|
||||||
|
|
||||||
type Monster = Card.Monster<Board>
|
type Monster = Card.Monster<Board>
|
||||||
|
|
||||||
|
@ -131,28 +134,52 @@ module Board =
|
||||||
|
|
||||||
let emptyBoard =
|
let emptyBoard =
|
||||||
{ players = (initialPlayer 8000 0, initialPlayer 8000 1)
|
{ players = (initialPlayer 8000 0, initialPlayer 8000 1)
|
||||||
moment = 0, Draw }
|
moment = 0, Draw
|
||||||
|
lastInstanceId = -1 }
|
||||||
|
|
||||||
|
let instantiate board card =
|
||||||
|
let instance =
|
||||||
|
{ CardInstance.template = card
|
||||||
|
CardInstance.id = board.lastInstanceId }
|
||||||
|
|
||||||
|
(instance, over Board.lastInstanceId <| (+) 1 <| board)
|
||||||
|
|
||||||
module Client =
|
module Client =
|
||||||
open Player
|
open Player
|
||||||
open Turn
|
open Turn
|
||||||
|
open Board
|
||||||
|
open Utils
|
||||||
|
|
||||||
type Log =
|
type Log =
|
||||||
| CardToHand of string
|
| CardToHand of string
|
||||||
|
| MonsterSummoned of Monster * int
|
||||||
| NewPhase of Phase
|
| NewPhase of Phase
|
||||||
| StateChanged of PlayerState * PlayerState
|
| StateChanged of PlayerState * PlayerState
|
||||||
| ChooseZone of int list
|
| ChooseZone of int list
|
||||||
|
| ChooseMonster of Monster list
|
||||||
|
|
||||||
type Client = Log -> int
|
type Client = Log -> int
|
||||||
|
|
||||||
let rec chooseZone client free =
|
let rec chooseZone client free =
|
||||||
let freeIndices = List.mapi (fun i _ -> i) free
|
let result =
|
||||||
let command = ChooseZone freeIndices
|
free
|
||||||
let result = client command
|
|> List.toIndices
|
||||||
|
|> ChooseZone
|
||||||
|
|> client
|
||||||
|
|
||||||
if List.contains result freeIndices then free.[result]
|
if List.containsIndex result free then result
|
||||||
else chooseZone client free
|
else chooseZone client free
|
||||||
|
|
||||||
|
let rec chooseMonster client monsters =
|
||||||
|
let result =
|
||||||
|
monsters
|
||||||
|
|> List.map (fun (m, _) -> m)
|
||||||
|
|> ChooseMonster
|
||||||
|
|> client
|
||||||
|
|
||||||
|
if List.containsIndex result monsters then monsters.[result]
|
||||||
|
else chooseMonster client monsters
|
||||||
|
|
||||||
module Zone =
|
module Zone =
|
||||||
open Player
|
open Player
|
||||||
open Side
|
open Side
|
||||||
|
@ -166,13 +193,16 @@ module Zone =
|
||||||
|
|
||||||
module Summon =
|
module Summon =
|
||||||
open Card.Card
|
open Card.Card
|
||||||
|
open Card.Monster
|
||||||
|
open Card.CardInstance
|
||||||
open Card
|
open Card
|
||||||
open Board
|
open Board
|
||||||
open Zone
|
open Zone
|
||||||
open Client
|
open Client
|
||||||
|
open Utils
|
||||||
|
|
||||||
module Normal =
|
module Normal =
|
||||||
let inline numberOfTributes (monster: Monster) =
|
let numberOfTributes (monster: Monster) =
|
||||||
let level = monster ^. Card.level
|
let level = monster ^. Card.level
|
||||||
|
|
||||||
if level <= 4 then 0
|
if level <= 4 then 0
|
||||||
|
@ -191,23 +221,45 @@ module Summon =
|
||||||
|
|
||||||
requiredTributes <= possibleTributes && freeZones > 0
|
requiredTributes <= possibleTributes && freeZones > 0
|
||||||
|
|
||||||
|
let normalSummonable board =
|
||||||
let hasNormalSummonableMonster board =
|
|
||||||
let hand = board ^. Board.currentPlayerHand
|
let hand = board ^. Board.currentPlayerHand
|
||||||
let monsters = List.choose monster hand
|
let monsters = List.choose monster hand
|
||||||
|
|
||||||
List.exists <| isNormalSummonable board <| monsters
|
let isSummonable = view _1 >> isNormalSummonable board
|
||||||
|
|
||||||
|
List.filter isSummonable monsters
|
||||||
|
|
||||||
|
let hasNormalSummonableMonster =
|
||||||
|
(normalSummonable
|
||||||
|
>> List.length
|
||||||
|
>> (<=) 1)
|
||||||
|
|
||||||
let canNormalSummon board =
|
let canNormalSummon board =
|
||||||
hasNormalSummonableMonster board && board ^. Board.currentPlayerLastNormalSummon < board ^. Board.turn
|
hasNormalSummonableMonster board && board ^. Board.currentPlayerLastNormalSummon < board ^. Board.turn
|
||||||
|
|
||||||
let performNormalSummon client board =
|
let performNormalSummon client board =
|
||||||
|
let summonable = normalSummonable board
|
||||||
|
let target = chooseMonster client summonable
|
||||||
|
let (_, _id) = target
|
||||||
|
|
||||||
let free = freeMonsterZones <| board ^. Board.currentPlayer
|
let free = freeMonsterZones <| board ^. Board.currentPlayer
|
||||||
let zone = chooseZone client free
|
let zone = chooseZone client free
|
||||||
|
|
||||||
let turn = board ^. Board.turn
|
let turn = board ^. Board.turn
|
||||||
|
|
||||||
board |> Board.currentPlayerLastNormalSummon .-> turn
|
let summonedInstance =
|
||||||
|
target
|
||||||
|
|> toCardInstance
|
||||||
|
|> Some
|
||||||
|
|
||||||
|
let removeTarget = List.filter (fun card -> card.id <> _id)
|
||||||
|
|
||||||
|
client <| MonsterSummoned(target ^. _1, zone) |> ignore
|
||||||
|
|
||||||
|
board
|
||||||
|
|> over Board.currentPlayerHand removeTarget
|
||||||
|
|> (Board.currentPlayerMonsters << Lens.indexToLens zone) .-> summonedInstance
|
||||||
|
|> Board.currentPlayerLastNormalSummon .-> turn
|
||||||
|
|
||||||
module Game =
|
module Game =
|
||||||
open Turn
|
open Turn
|
||||||
|
@ -291,5 +343,7 @@ module Game =
|
||||||
if currentState <> InGame then
|
if currentState <> InGame then
|
||||||
let newStates = getPlayerStates newBoard
|
let newStates = getPlayerStates newBoard
|
||||||
client <| StateChanged newStates |> ignore
|
client <| StateChanged newStates |> ignore
|
||||||
|
|
||||||
|
newBoard
|
||||||
else
|
else
|
||||||
game <| switchPhases client newBoard <| client
|
game <| switchPhases client newBoard <| client
|
||||||
|
|
|
@ -130,11 +130,14 @@ module Card =
|
||||||
|
|
||||||
let inline level f card = (_2 << MonsterCardDetails.level) f card
|
let inline level f card = (_2 << MonsterCardDetails.level) f card
|
||||||
|
|
||||||
|
|
||||||
|
module CardInstance =
|
||||||
|
open Card
|
||||||
|
|
||||||
type CardInstance<'s> =
|
type CardInstance<'s> =
|
||||||
{ template: Card<'s>
|
{ template: Card<'s>
|
||||||
id: int }
|
id: int }
|
||||||
|
|
||||||
|
|
||||||
module CardInstance =
|
module CardInstance =
|
||||||
let inline template f card = f card.template <&> fun v -> { card with template = v }
|
let inline template f card = f card.template <&> fun v -> { card with template = v }
|
||||||
let inline _id f card = f card.id <&> fun v -> { card with id = v }
|
let inline _id f card = f card.id <&> fun v -> { card with id = v }
|
||||||
|
@ -142,6 +145,7 @@ module Card =
|
||||||
|
|
||||||
module Monster =
|
module Monster =
|
||||||
open Card
|
open Card
|
||||||
|
open CardInstance
|
||||||
|
|
||||||
let monster card: option<Monster<'s> * int> =
|
let monster card: option<Monster<'s> * int> =
|
||||||
match card.template with
|
match card.template with
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
[<EntryPoint>]
|
[<EntryPoint>]
|
||||||
let main _ =
|
let main _ =
|
||||||
let sampleCard =
|
let sampleCardTemplate =
|
||||||
Monster ({ name= "sampleCard"
|
Monster ({ name= "sampleCard"
|
||||||
text="something"
|
text="something"
|
||||||
effects = []}
|
effects = []}
|
||||||
|
@ -24,8 +24,10 @@
|
||||||
attribute = Fire
|
attribute = Fire
|
||||||
race = Warrior })
|
race = Warrior })
|
||||||
|
|
||||||
|
|
||||||
let board = over Board.secondPlayer <| toDeckBottom sampleCard <| emptyBoard
|
let (sampleCard, initialBoard) = instantiate emptyBoard sampleCardTemplate
|
||||||
|
|
||||||
|
let board = over Board.firstPlayer <| toDeckBottom sampleCard <| initialBoard
|
||||||
|
|
||||||
let client action =
|
let client action =
|
||||||
match action with
|
match action with
|
||||||
|
@ -41,11 +43,20 @@
|
||||||
let i = System.Console.ReadLine() |> int
|
let i = System.Console.ReadLine() |> int
|
||||||
|
|
||||||
free.[i]
|
free.[i]
|
||||||
|
| ChooseMonster monsters ->
|
||||||
|
printfn "What monster do you want to choose? %A" <| List.map (fun (_base, details) -> _base.name) monsters
|
||||||
|
let i = System.Console.ReadLine() |> int
|
||||||
|
|
||||||
|
i
|
||||||
|
| MonsterSummoned (card, zone) ->
|
||||||
|
printfn "Monster %A was summoned in zone %i" card zone
|
||||||
|
0
|
||||||
| _ ->
|
| _ ->
|
||||||
printfn "Something unkown happened"
|
printfn "Something unkown happened"
|
||||||
0
|
0
|
||||||
|
|
||||||
game board client
|
let finalBoard = game board client
|
||||||
|
|
||||||
|
printfn "The final baord was: %A" finalBoard
|
||||||
|
|
||||||
0 // return integer code
|
0 // return integer code
|
||||||
|
|
Loading…
Reference in a new issue