Created
September 28, 2016 16:27
-
-
Save asibahi/493bbe71205fb7cffad2f7b16b98c534 to your computer and use it in GitHub Desktop.
Original baloot functions
This file contains 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
// Types | |
type Team = | |
| Us | |
| Them | |
member this.Opp = | |
match this with | |
| Us -> Them | |
| Them -> Us | |
type Suit = | |
| Hearts | |
| Diamonds | |
| Clubs | |
| Spades | |
type Rank = | |
| Ace | |
| King | |
| Queen | |
| Jack | |
| Ten | |
| Nine | |
| Eight | |
| Seven | |
type Card = | |
{ Rank : Rank | |
Suit : Suit } | |
member this.SunValue = | |
match this.Rank with | |
| Ace -> 11 | |
| Ten -> 10 | |
| King -> 4 | |
| Queen -> 3 | |
| Jack -> 2 | |
| _ -> 0 | |
member this.TrumpValue trump = | |
match this.Rank, this.Suit = trump with | |
| Jack, true -> 20 | |
| Nine, true -> 14 | |
| _ -> this.SunValue | |
member this.IsPicture = | |
match this.Rank with | |
| Nine | Eight | Seven -> false | |
| _ -> true | |
member this.SortValue = | |
match this.Rank with | |
| Ace -> 0 | |
| King -> 1 | |
| Queen -> 2 | |
| Jack -> 3 | |
| Ten -> 4 | |
| Nine -> 5 | |
| Eight -> 6 | |
| Seven -> 7 | |
+ match this.Suit with | |
| Hearts -> 0 | |
| Clubs -> 10 | |
| Diamonds -> 20 | |
| Spades -> 30 | |
override this.ToString() = sprintf "%A of %A" this.Rank this.Suit | |
type Mode = | |
| Sun | |
| Trump of Suit | |
type Project = | |
| Sira | |
| Fifty | |
| Hundred | |
| FourHundred | |
| Baloot | |
type Round = | |
{ Mode : Mode | |
Captured : Card list | |
Projects : Project list | |
Ground : Team | |
Bettor : Team | |
Owner : Team } | |
// Trick Total Point Calculations | |
let capturedTrickPts round = | |
round.Captured | |
|> match round.Mode with | |
| Sun -> List.fold (fun acc card -> acc + (card.SunValue)) 0 | |
| Trump(suit) -> List.fold (fun acc card -> acc + (card.TrumpValue suit)) 0 | |
|> (+) (if round.Ground = round.Owner then 10 | |
else 0) | |
// Captured Cards Point Calculations | |
let sunRoundPts pts = | |
match pts % 10 with | |
| 5 -> pts | |
| n when n < 5 -> pts - n | |
| n -> pts - n + 10 | |
/ 5 | |
let trumpRoundPts pts = | |
match pts % 10 with | |
| n when n <= 5 -> pts - n | |
| n -> pts - n + 10 | |
/ 10 | |
let capturedRoundPts round = | |
let pts = capturedTrickPts round | |
match round.Mode with | |
| Sun -> sunRoundPts pts | |
| Trump(_) -> | |
match pts % 10, round.Owner = round.Bettor with | |
| 6, true -> (trumpRoundPts pts) - 1 | |
| _ -> trumpRoundPts pts | |
// Project Points Calculations | |
let sunProjectPts = | |
function | |
| Sira -> 4 | |
| Fifty -> 10 | |
| Hundred -> 20 | |
| FourHundred -> 40 | |
| _ -> 0 | |
let trumpProjectPts = | |
function | |
| Sira | Baloot -> 2 | |
| Fifty -> 5 | |
| Hundred | FourHundred -> 10 | |
let projectRoundPts (round : Round) = | |
let projectPts = | |
match round.Mode with | |
| Sun -> sunProjectPts | |
| Trump(_) -> trumpProjectPts | |
round.Projects |> List.fold (fun acc pro -> acc + (projectPts pro)) 0 | |
// Total Point for Round | |
// TARGET FUNCTION | |
let roundPts round = (capturedRoundPts round) + (projectRoundPts round) | |
// Type Creations | |
let newRound (mode, captured, projects, ground, bettor, owner) = | |
{ Round.Mode = mode | |
Round.Captured = captured | |
Round.Projects = projects | |
Round.Ground = ground | |
Round.Bettor = bettor | |
Round.Owner = owner } | |
// The Other Team | |
open Microsoft.FSharp.Reflection | |
// Deck Creation and Shuffling | |
let fullDeck = | |
let suits = FSharpType.GetUnionCases typeof<Suit> | |
let ranks = FSharpType.GetUnionCases typeof<Rank> | |
[ for s in suits do | |
let suit = FSharpValue.MakeUnion(s, [||]) :?> Suit | |
for r in ranks do | |
let rank = FSharpValue.MakeUnion(r, [||]) :?> Rank | |
yield { Card.Rank = rank | |
Card.Suit = suit } ] | |
let globalRandom = System.Random() | |
let shuffleDeck = List.sortBy (fun _ -> globalRandom.Next()) | |
let cutDeckRandomly = List.splitAt (globalRandom.Next(7) * 4) | |
// Randomized Round Creation for testing | |
let createTestRounds mode = | |
let rInt = globalRandom.Next(100) | |
let rBettor, rGround = | |
match rInt % 4 with | |
| 0 -> Us, Us | |
| 1 -> Us, Them | |
| 2 -> Them, Them | |
| _ -> Them, Us | |
let capped1, capped2 = | |
fullDeck | |
|> shuffleDeck | |
|> cutDeckRandomly | |
let round1 = newRound (mode, capped1, [], rGround, rBettor, Us) | |
let round2 = newRound (mode, capped2, [], rGround.Opp, rBettor.Opp, Them) | |
round1, round2 | |
(* Project finder *) | |
// only works for lists of distinct integers | |
let hasIntSeqOf n = | |
List.sort | |
>> List.mapi (-) // subtract number from index. results in consecutive numbers having the same result. | |
>> List.groupBy id // Since consecutive numbers will have same results they can be grouped. | |
>> List.filter (snd // If any group has (>= n) members, the sequence exists | |
>> List.length | |
>> (<=) n) | |
>> List.map Some | |
let hasSeqOf n = | |
List.sortBy (fun (c : Card) -> c.SortValue) // To make sure the cards of the same suit are sorted correctly | |
>> List.mapi (fun i c -> (i - c.SortValue, c)) // tuple with the card and the invariant if there are consectuive cards | |
>> List.groupBy fst //group by the invariant | |
>> List.map snd // then strip it out | |
>> List.filter (List.length >> (<=) n) | |
>> List.map ((List.map snd) >> Some) // clean up | |
let hasFourOfAKind = | |
List.groupBy (fun c -> c.Rank) | |
>> List.map snd | |
>> List.tryFind (List.length >> (=) 4) | |
let hasOneSira = | |
hasSeqOf 3 >> function | |
| Some(cl) :: [] when 3 = List.length cl -> Some(cl) | |
| _ -> None | |
let hasTwoSira = | |
hasSeqOf 3 >> function | |
| Some(cl1) :: Some(cl2) :: _ when (List.length cl1) = (List.length cl2) -> Some(cl1 @ cl2) | |
| _ -> None | |
let hasFifty = | |
hasSeqOf 4 >> function // there can be only one (four in a row) | |
| Some(cl) :: _ when 4 = List.length cl -> Some(cl) | |
| _ -> None | |
let hasHundredOne = | |
hasSeqOf 5 >> function // there can be only one (five in a row) | |
| Some(cl) :: _ -> Some(cl) | |
| _ -> None | |
let hasHundredTwo = | |
hasFourOfAKind >> function | |
| Some(c :: tl) when c.IsPicture && c.Rank <> Ace -> Some(c :: tl) | |
| _ -> None | |
let hasFourHundred = | |
hasFourOfAKind >> function | |
| Some(c :: tl) when c.Rank = Ace -> Some(c :: tl) | |
| _ -> None | |
let hasBaloot mode cards = | |
match mode with | |
| Sun -> None | |
| Trump(t) -> | |
let king = List.tryFind (fun c -> c.Rank = King && c.Suit = t) cards | |
let queen = List.tryFind (fun c -> c.Rank = Queen && c.Suit = t) cards | |
match king, queen with | |
| Some(k), Some(q) -> Some([ k; q ]) | |
| _ -> None | |
fullDeck | |
|> shuffleDeck | |
|> Seq.take 7 | |
|> List.ofSeq | |
|> List.sortBy (fun (c : Card) -> c.SortValue) | |
|> hasHundredOne |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment