Skip to content

Instantly share code, notes, and snippets.

@no-longer-on-githu-b
Forked from bananu7/LoveLetter.fs
Created July 19, 2014 13:23
Show Gist options
  • Select an option

  • Save no-longer-on-githu-b/0eb390f94660768dde33 to your computer and use it in GitHub Desktop.

Select an option

Save no-longer-on-githu-b/0eb390f94660768dde33 to your computer and use it in GitHub Desktop.
// 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