4 people like it.
Like the snippet!
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