diff --git a/fsharp/ygosim/src/Board.fs b/fsharp/ygosim/src/Board.fs index d1ee869..921e9f3 100644 --- a/fsharp/ygosim/src/Board.fs +++ b/fsharp/ygosim/src/Board.fs @@ -56,6 +56,7 @@ module Player = f player.lastNormalSummon <&> fun v -> { player with lastNormalSummon = v } let inline deck f player = (side << Side.deck) f player + let inline monsters f player = (side << Side.monsters) f player let initialPlayer lp id = { lifePoints = lp @@ -111,6 +112,7 @@ module Board = let inline currentPlayerDeck f board = (currentPlayer << Player.deck) f board let inline currentPlayerHand f board = (currentPlayer << Player.hand) f board let inline currentPlayerLastNormalSummon f board = (currentPlayer << Player.lastNormalSummon) f board + let inline currentPlayerMonsters f board = (currentPlayer << Player.monsters) f board let inline firstPlayer f board = (players << _1) f board let inline secondPlayer f board = (players << _2) f board @@ -119,6 +121,8 @@ module Board = type CardInstance = Card.CardInstance + type Monster = Card.Monster + type Effect = Effect.Effect type Condition = Effect.Condition @@ -152,29 +156,58 @@ module Client = module Zone = open Player open Side + open Board - let freeMonsterZones player = List.filter Option.isNone player.side.monsters + let freeMonsterZones (player: Player) = List.filter Option.isNone player.side.monsters let freeMonsterZoneCount = freeMonsterZones >> List.length let hasFreeMonsterZones = (>=) << freeMonsterZoneCount let hasFreeMonsterZone player = hasFreeMonsterZones player 1 + module Summon = open Card.Card + open Card open Board open Zone open Client module Normal = - let inline numberOfTributes monster = + let inline numberOfTributes (monster: Monster) = let level = monster ^. Card.level if level <= 4 then 0 elif level <= 6 then 1 else 2 + let isNormalSummonable board maybeMonster = + match maybeMonster with + | Some monster -> + let requiredTributes = numberOfTributes monster + + let possibleTributes = + board ^. Board.currentPlayerMonsters + |> List.filter Option.isSome + |> List.length + + let freeZones = 5 - possibleTributes + requiredTributes + + Some(requiredTributes <= possibleTributes && freeZones > 0) + | None -> None + + + let hasNormalSummonableMonster board = + let hand = board ^. Board.currentPlayerHand + + let result = + List.tryFind <| (monster + >> (isNormalSummonable board) + >> Option.isSome) + <| hand + + Option.isSome result + let canNormalSummon board = - hasFreeMonsterZone <| board ^. Board.currentPlayer - && board ^. Board.currentPlayerLastNormalSummon < board ^. Board.turn + hasNormalSummonableMonster board && board ^. Board.currentPlayerLastNormalSummon < board ^. Board.turn let performNormalSummon client board = let free = freeMonsterZones <| board ^. Board.currentPlayer @@ -187,10 +220,8 @@ module Summon = let turn = board ^. Board.turn - board |> Board.currentPlayerLastNormalSummon .-> turn - module Game = open Turn open Player diff --git a/fsharp/ygosim/src/Card.fs b/fsharp/ygosim/src/Card.fs index 2363d75..d491e32 100644 --- a/fsharp/ygosim/src/Card.fs +++ b/fsharp/ygosim/src/Card.fs @@ -123,6 +123,11 @@ module Card = | Spell of BaseCard<'s> * SpellCardDetails | Trap of BaseCard<'s> * TrapCardDetails + let monster card: option> = + match card with + | Monster m -> Some m + | _ -> None + module Card = let inline baseCard f card = _1 f card let inline cardDetails f card = _2 f card