4 people like it.

Baccarat

Shuffles a deck of cards, deals 2 hands applying punto banco rules before declaring a winner or a tie.

  1: 
  2: 
  3: 
  4: 
  5: 
  6: 
  7: 
  8: 
  9: 
 10: 
 11: 
 12: 
 13: 
 14: 
 15: 
 16: 
 17: 
 18: 
 19: 
 20: 
 21: 
 22: 
 23: 
 24: 
 25: 
 26: 
 27: 
 28: 
 29: 
 30: 
 31: 
 32: 
 33: 
 34: 
 35: 
 36: 
 37: 
 38: 
 39: 
 40: 
 41: 
 42: 
 43: 
 44: 
 45: 
 46: 
 47: 
 48: 
 49: 
 50: 
 51: 
 52: 
 53: 
 54: 
 55: 
 56: 
 57: 
 58: 
 59: 
 60: 
 61: 
 62: 
 63: 
 64: 
 65: 
 66: 
 67: 
 68: 
 69: 
 70: 
 71: 
 72: 
 73: 
 74: 
 75: 
 76: 
 77: 
 78: 
 79: 
 80: 
 81: 
 82: 
 83: 
 84: 
 85: 
 86: 
 87: 
 88: 
 89: 
 90: 
 91: 
 92: 
 93: 
 94: 
 95: 
 96: 
 97: 
 98: 
 99: 
100: 
101: 
102: 
103: 
104: 
105: 
106: 
open System

let suits, ranks = "♣♦♥♠", "A123456789TJQK"
let deck = [|for s in suits do for r in ranks -> String[|r;s|]|]
let mutable index = 0
let shuffle () =
    let r = Random()
    let order = [|for _ in 1..deck.Length -> r.Next()|]
    Array.Sort(order,deck)
    index <- 0
do shuffle ()
let take() = let card = deck.[index] in index <- index + 1; card
let value card = 
    let values = 1::[1..9]@[0;0;0;0]
    let rank (card:string) = ranks.IndexOf(card.[0])
    values.[rank card]
let total cards = (cards |> List.sumBy value) % 10
let isNatural hand = let score = total hand in score = 8 || score = 9
type action = Hit | Stand
let playerRule total =
    match total with
    | 6 | 7 -> Stand
    | _ -> Hit
let bankerRule total thirdCardValue =
    let thirdCardIs (values:int list) =
        values |> List.exists ((=) thirdCardValue)
    match total with
    | 0 | 1 | 2 -> Hit
    | 3 when thirdCardIs [1;2;3;4;5;6;7;9;0] -> Hit
    | 4 when thirdCardIs [2;3;4;5;6;7] -> Hit
    | 5 when thirdCardIs [4;5;6;7] -> Hit
    | 6 when thirdCardIs [6;7] -> Hit
    | _ -> Stand
let applyRules player banker =
    if isNatural player || isNatural banker then player, banker
    else
        let draw = function Hit -> [take()] | Stand -> [] 
        let playerAction = playerRule (total player)
        let player = player@(draw playerAction)
        let bankerAction =
            if playerAction = Stand then playerRule (total banker)
            else
                let thirdCard = player.[2]
                bankerRule (total banker) (value thirdCard)    
        player, banker@(draw bankerAction)
let player, banker =
    let c1,c2,c3,c4 = take(), take(), take(), take()
    applyRules [c1;c3] [c2;c4]
let result = 
    let a, b = total player, total banker
    if a > b then sprintf "Player wins with %d to Banker's %d" a b
    elif a < b then sprintf "Banker wins with %d to Player's %d" b a
    else sprintf "Tie on %d" a
let game = 
    let cards xs = String.concat "," xs
    sprintf "Player %s, Banker %s\r\n%s" (cards player) (cards banker) result

module ``Baccarat Tests`` = 
    let ``card A♥ value is 1``() =
        assert(value "A♥" = 1)
    let ``card 6♦ value is 6``() =
        assert(value "6♦" = 6)
    let ``card K♠ value is 0``() =
        assert(value "K♠" = 0)
    let ``hand of A♣ & K♠ totals 1``() =
        assert(total ["A♣";"K♠"] = 1)
    let ``hand of 9♦ & 3♥ totals 2``() =
        assert(total ["9♦";"3♥"] = 2)
    let ``hand of K♥ & Q♣ totals 0``() =
        assert(total ["K♥";"Q♣"] = 0)
    let ``hand of 4♠ & 5♦ totals 9``() =
        assert(total ["4♠";"5♦"] = 9)
    let ``hand of 9♥ K♣ is natural``() =
        assert(isNatural ["9♥";"K♣"])
    let ``player stands on a total of 6``() =
        assert(playerRule 6 = Stand)        
    let ``player hits on a total of 5``() =
        assert(playerRule 5 = Hit)       
    let ``test banker rule``() =
        let H = Hit
        let S = Stand
        let table = [
            7,[S;S;S;S;S;S;S;S;S;S]
            6,[S;S;S;S;S;S;H;H;S;S]
            5,[S;S;S;S;H;H;H;H;S;S]
            4,[S;S;H;H;H;H;H;H;S;S]
            3,[H;H;H;H;H;H;H;H;S;H]
            2,[H;H;H;H;H;H;H;H;H;H]
            1,[H;H;H;H;H;H;H;H;H;H]
            0,[H;H;H;H;H;H;H;H;H;H]
            ]
        for total, thirdCards in table do
            thirdCards |> List.iteri (fun i action ->
                assert(action = bankerRule total i)   
            )

    do  ``card A♥ value is 1``()
        ``card 6♦ value is 6``()
        ``card K♠ value is 0``()
        ``hand of A♣ & K♠ totals 1``()
        ``hand of 9♦ & 3♥ totals 2``()
        ``hand of K♥ & Q♣ totals 0``()
        ``hand of 9♥ K♣ is natural``()
        ``player stands on a total of 6``()
        ``player hits on a total of 5``()
        ``test banker rule``()
namespace System
val suits : string

Full name: Script.suits
val ranks : string

Full name: Script.ranks
val deck : String []

Full name: Script.deck
val s : char
val r : char
Multiple items
type String =
  new : value:char -> string + 7 overloads
  member Chars : int -> char
  member Clone : unit -> obj
  member CompareTo : value:obj -> int + 1 overload
  member Contains : value:string -> bool
  member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
  member EndsWith : value:string -> bool + 2 overloads
  member Equals : obj:obj -> bool + 2 overloads
  member GetEnumerator : unit -> CharEnumerator
  member GetHashCode : unit -> int
  ...

Full name: System.String

--------------------
String(value: nativeptr<char>) : unit
String(value: nativeptr<sbyte>) : unit
String(value: char []) : unit
String(c: char, count: int) : unit
String(value: nativeptr<char>, startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int) : unit
String(value: char [], startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int, enc: Text.Encoding) : unit
val mutable index : int

Full name: Script.index
val shuffle : unit -> unit

Full name: Script.shuffle
val r : Random
Multiple items
type Random =
  new : unit -> Random + 1 overload
  member Next : unit -> int + 2 overloads
  member NextBytes : buffer:byte[] -> unit
  member NextDouble : unit -> float

Full name: System.Random

--------------------
Random() : unit
Random(Seed: int) : unit
val order : int []
property Array.Length: int
Random.Next() : int
Random.Next(maxValue: int) : int
Random.Next(minValue: int, maxValue: int) : int
type Array =
  member Clone : unit -> obj
  member CopyTo : array:Array * index:int -> unit + 1 overload
  member GetEnumerator : unit -> IEnumerator
  member GetLength : dimension:int -> int
  member GetLongLength : dimension:int -> int64
  member GetLowerBound : dimension:int -> int
  member GetUpperBound : dimension:int -> int
  member GetValue : [<ParamArray>] indices:int[] -> obj + 7 overloads
  member Initialize : unit -> unit
  member IsFixedSize : bool
  ...

Full name: System.Array
Array.Sort<'T>(array: 'T []) : unit
   (+0 other overloads)
Array.Sort(array: Array) : unit
   (+0 other overloads)
Array.Sort<'T>(array: 'T [], comparison: Comparison<'T>) : unit
   (+0 other overloads)
Array.Sort<'T>(array: 'T [], comparer: Collections.Generic.IComparer<'T>) : unit
   (+0 other overloads)
Array.Sort<'TKey,'TValue>(keys: 'TKey [], items: 'TValue []) : unit
   (+0 other overloads)
Array.Sort(array: Array, comparer: Collections.IComparer) : unit
   (+0 other overloads)
Array.Sort(keys: Array, items: Array) : unit
   (+0 other overloads)
Array.Sort<'TKey,'TValue>(keys: 'TKey [], items: 'TValue [], comparer: Collections.Generic.IComparer<'TKey>) : unit
   (+0 other overloads)
Array.Sort<'T>(array: 'T [], index: int, length: int) : unit
   (+0 other overloads)
Array.Sort(keys: Array, items: Array, comparer: Collections.IComparer) : unit
   (+0 other overloads)
val take : unit -> String

Full name: Script.take
val card : String
val value : card:string -> int

Full name: Script.value
val card : string
val values : int list
val rank : (string -> int)
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = String

Full name: Microsoft.FSharp.Core.string
String.IndexOf(value: string) : int
String.IndexOf(value: char) : int
String.IndexOf(value: string, comparisonType: StringComparison) : int
String.IndexOf(value: string, startIndex: int) : int
String.IndexOf(value: char, startIndex: int) : int
String.IndexOf(value: string, startIndex: int, comparisonType: StringComparison) : int
String.IndexOf(value: string, startIndex: int, count: int) : int
String.IndexOf(value: char, startIndex: int, count: int) : int
String.IndexOf(value: string, startIndex: int, count: int, comparisonType: StringComparison) : int
val total : cards:string list -> int

Full name: Script.total
val cards : string list
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
  | ( [] )
  | ( :: ) of Head: 'T * Tail: 'T list
  interface IEnumerable
  interface IEnumerable<'T>
  member Head : 'T
  member IsEmpty : bool
  member Item : index:int -> 'T with get
  member Length : int
  member Tail : 'T list
  static member Cons : head:'T * tail:'T list -> 'T list
  static member Empty : 'T list

Full name: Microsoft.FSharp.Collections.List<_>
val sumBy : projection:('T -> 'U) -> list:'T list -> 'U (requires member ( + ) and member get_Zero)

Full name: Microsoft.FSharp.Collections.List.sumBy
val isNatural : hand:string list -> bool

Full name: Script.isNatural
val hand : string list
val score : int
type action =
  | Hit
  | Stand

Full name: Script.action
union case action.Hit: action
union case action.Stand: action
val playerRule : total:int -> action

Full name: Script.playerRule
val total : int
val bankerRule : total:int -> thirdCardValue:int -> action

Full name: Script.bankerRule
val thirdCardValue : int
val thirdCardIs : (int list -> bool)
Multiple items
val int : value:'T -> int (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int

--------------------
type int = int32

Full name: Microsoft.FSharp.Core.int

--------------------
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>
type 'T list = List<'T>

Full name: Microsoft.FSharp.Collections.list<_>
val exists : predicate:('T -> bool) -> list:'T list -> bool

Full name: Microsoft.FSharp.Collections.List.exists
val applyRules : player:string list -> banker:string list -> string list * string list

Full name: Script.applyRules
val player : string list
val banker : string list
val draw : (action -> String list)
val playerAction : action
val bankerAction : action
val thirdCard : string
val player : string list

Full name: Script.player
val banker : string list

Full name: Script.banker
val c1 : String
val c2 : String
val c3 : String
val c4 : String
val result : string

Full name: Script.result
val a : int
val b : int
val sprintf : format:Printf.StringFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
val game : string

Full name: Script.game
val cards : (seq<string> -> string)
val xs : seq<string>
val concat : sep:string -> strings:seq<string> -> string

Full name: Microsoft.FSharp.Core.String.concat
val ( card A♥ value is 1 ) : unit -> unit

Full name: Script.Baccarat Tests.( card A♥ value is 1 )
val ( card 6♦ value is 6 ) : unit -> unit

Full name: Script.Baccarat Tests.( card 6♦ value is 6 )
val ( card K♠ value is 0 ) : unit -> unit

Full name: Script.Baccarat Tests.( card K♠ value is 0 )
val ( hand of A♣ & K♠ totals 1 ) : unit -> unit

Full name: Script.Baccarat Tests.( hand of A♣ & K♠ totals 1 )
val ( hand of 9♦ & 3♥ totals 2 ) : unit -> unit

Full name: Script.Baccarat Tests.( hand of 9♦ & 3♥ totals 2 )
val ( hand of K♥ & Q♣ totals 0 ) : unit -> unit

Full name: Script.Baccarat Tests.( hand of K♥ & Q♣ totals 0 )
val ( hand of 4♠ & 5♦ totals 9 ) : unit -> unit

Full name: Script.Baccarat Tests.( hand of 4♠ & 5♦ totals 9 )
val ( hand of 9♥ K♣ is natural ) : unit -> unit

Full name: Script.Baccarat Tests.( hand of 9♥ K♣ is natural )
val ( player stands on a total of 6 ) : unit -> unit

Full name: Script.Baccarat Tests.( player stands on a total of 6 )
val ( player hits on a total of 5 ) : unit -> unit

Full name: Script.Baccarat Tests.( player hits on a total of 5 )
val ( test banker rule ) : unit -> unit

Full name: Script.Baccarat Tests.( test banker rule )
val H : action
val S : action
val table : (int * action list) list
val thirdCards : action list
val iteri : action:(int -> 'T -> unit) -> list:'T list -> unit

Full name: Microsoft.FSharp.Collections.List.iteri
val i : int
Multiple items
val action : action

--------------------
type action =
  | Hit
  | Stand

Full name: Script.action

More information

Link:http://fssnip.net/9O
Posted:12 years ago
Author:Phillip Trelford
Tags: card , game