1
Fork 0

fsharp(ygosim): feat: added a lot more stuff to normal summoning

Signed-off-by: prescientmoon <git@moonythm.dev>
This commit is contained in:
Matei Adriel 2019-12-15 16:21:09 +02:00 committed by prescientmoon
parent 4b511c12d3
commit 79726d5ac5
Signed by: prescientmoon
SSH key fingerprint: SHA256:UUF9JT2s8Xfyv76b8ZuVL7XrmimH4o49p4b+iexbVH4
3 changed files with 88 additions and 19 deletions

View file

@ -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

View file

@ -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

View file

@ -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