-
-
Save no-longer-on-githu-b/0eb390f94660768dde33 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Learn more about F# at http://fsharp.net | |
| // See the 'F# Tutorial' project for more help. | |
| open System.Linq | |
| open System.Collections.Generic | |
| open System | |
| type Card = | |
| | Guard | |
| | Priest | |
| | Baron | |
| | Handmaid | |
| | Prince | |
| | King | |
| | Countess | |
| | Princess | |
| type Player = | |
| | PlayerOne = 0 | |
| | PlayerTwo = 1 | |
| | PlayerThree = 2 | |
| | PlayerFour = 3 | |
| type Move = | |
| | GuardMove of target : Player * allegedCard : Card | |
| | PriestMove of target : Player | |
| | BaronMove of target : Player | |
| | HandmaidMove | |
| | PrinceMove of target : Player | |
| | KingMove of target : Player | |
| | CountessMove | |
| | PrincessMove | |
| type EmptyMove = | |
| | EmptyGuardMove (Player -> Card -> Move) | |
| let decide m = match m with | |
| | EmptyGuardMove -> m (nextPlayer) Priest | |
| let fullDeck = seq { | |
| yield! Enumerable.Repeat (Guard, 5) | |
| yield! Enumerable.Repeat (Priest, 2) | |
| yield! Enumerable.Repeat (Baron, 2) | |
| yield! Enumerable.Repeat (Handmaid, 2) | |
| yield! Enumerable.Repeat (Prince, 2) | |
| yield King | |
| yield Countess | |
| yield Princess | |
| } | |
| type GameState (initiallyDiscardedCard : ICard, deck : IEnumerable<Card>) = | |
| member val Discard = initiallyDiscardedCard with get | |
| member val Deck = deck.ToList() with get | |
| member val Hands = [|None; None; None; None|] with get | |
| override this.ToString() = String.Format ("GameState ({0}, {1}, {2}, {3})", | |
| sprintf "%A" this.Hands.[0], | |
| sprintf "%A" this.Hands.[1], | |
| sprintf "%A" this.Hands.[2], | |
| sprintf "%A" this.Hands.[3]) | |
| and ICard = | |
| abstract Value : int | |
| abstract ExecuteMagicPower : GameState -> () | |
| let pop (l: List<'T>) = | |
| if l.Any() then | |
| let head = l.Item 0 | |
| l.RemoveAt 0 | |
| Some head | |
| else | |
| None | |
| let initialHandOut (s :GameState) = | |
| s.Hands.[0] <- pop s.Deck | |
| s.Hands.[1] <- pop s.Deck | |
| s.Hands.[2] <- pop s.Deck | |
| s.Hands.[3] <- pop s.Deck | |
| let createShuffledGameState = | |
| let deck = fullDeck.ToList() | |
| let discard = pop deck | |
| GameState (Option.get discard, deck) | |
| let nextPlayer currentPlayer = | |
| match currentPlayer with | |
| | Player.PlayerOne -> Player.PlayerTwo | |
| | Player.PlayerTwo -> Player.PlayerThree | |
| | Player.PlayerThree -> Player.PlayerFour | |
| | Player.PlayerFour -> Player.PlayerOne | |
| | _ -> failwith "WTF" | |
| let decideMove currentPlayer (oldCard : Card) (newCard : Card) state = | |
| let worseCard = if oldCard < newCard then oldCard else newCard | |
| match worseCard with | |
| | Guard -> GuardMove (target = (nextPlayer currentPlayer), allegedCard = Priest) | |
| | Priest -> PriestMove (target = (nextPlayer currentPlayer)) | |
| | Baron -> BaronMove (target = (nextPlayer currentPlayer)) | |
| | Handmaid -> HandmaidMove | |
| | Prince -> PrinceMove (target = (nextPlayer currentPlayer)) | |
| | King -> KingMove (target = (nextPlayer currentPlayer)) | |
| | Countess -> CountessMove | |
| | Princess -> PrincessMove | |
| let applyCard card s = printf "Applying card %A\n" card | |
| // if you don't have a card in deck, you cannot execute a move | |
| let executeSingleMove currentPlayer (oldCard : Card) (newCard : Card) (s: GameState) = | |
| let move = decideMove currentPlayer oldCard newCard s | |
| match move with | |
| | -> applyCard newCard s | |
| | -> s.Hands.[int currentPlayer] <- Some newCard | |
| applyCard oldCard s | |
| [<EntryPoint>] | |
| let main argv = | |
| let state = createShuffledGameState | |
| initialHandOut state | |
| let mutable currentPlayer = Player.PlayerOne | |
| while state.Deck.Any() do | |
| let newCard = Option.get <| pop state.Deck | |
| let oldCard = Option.get state.Hands.[int currentPlayer] | |
| executeSingleMove currentPlayer oldCard newCard state | |
| currentPlayer <- nextPlayer currentPlayer | |
| printf "%A\n" state | |
| Console.WriteLine state | |
| 0 // return an integer exit code | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment