Skip to content
MichaelCookPublic

About

Analyze cribbage hands in C++, C, Go, Rust, Nim, TypeScript and Python

Topics

Resources

Stars

4 stars

Watchers

1 watching

Forks

Repository files navigation

Analyze Cribbage Hands

Given a cribbage hand (six cards), which two cards should you discard to the crib to maximize your chances of getting the best score?

This repo contains implementations in multiple computer languages:

  • C
  • C++
  • Go (golang)
  • Nim (nimlang)
  • Python
  • Rust
  • TypeScript
  • Julia

Example Output

Here's a sample run:

$ ./cribbage-cpp "7C 9H 5H 5C 5D JS"
[ JS 5D 5C 7C 5H 9H ]
JS 5D [12.5 3.6 4..29] [-1.4 3.4 -15..8]
JS 5C [12.5 3.6 4..29] [-1.4 3.4 -15..8]
JS 7C [14.6 3.9 8..33] [7.5 3.9 -5..17]
JS 5H [12.5 3.6 4..29] [-1.4 3.4 -15..8]
JS 9H [16.0 4.7 8..35] [7.6 4.0 -9..17]
5D 5C [13.6 4.1 4..32] [-3.9 3.9 -22..6]
5D 7C [15.0 3.5 8..31] [2.5 3.7 -10..13]
5D 5H [13.6 4.1 4..32] [-3.9 3.9 -22..6]
5D 9H [14.6 3.5 8..29] [3.5 3.1 -10..13]
5C 7C [15.1 3.5 8..31] [2.5 3.7 -10..13]
5C 5H [13.6 4.1 4..32] [-3.9 3.9 -22..6]
5C 9H [14.6 3.5 8..29] [3.5 3.1 -10..13]
7C 5H [15.0 3.5 8..31] [2.5 3.7 -10..13]
7C 9H [20.9 4.5 14..41] [12.4 5.5 -10..27]
5H 9H [14.6 3.6 8..29] [3.5 3.1 -10..13]

For example:

7C 9H [20.9 4.5 14..41] [12.4 5.5 -10..27]

This line says if you discard the seven of clubs (7C) and the nine of hearts (9H) you will get an average score of 20.9 if the crib is yours, or 12.4 if the crib is not yours.

The numbers in brackets (e.g., [16.0 4.7 8..35]) show the mean, standard deviation, minimum and maximum scores. The first set of numbers is for when the crib is yours; the second set, the crib is your opponent's. (A smaller standard deviation means you're more likely to get the average score.)

Performance

Elapsed (s) Normalized Language
0.69 1.0 c
1.12 1.6 rust
1.13 1.6 cpp
3.68 5.3 julia
6.62 9.6 typescript
6.82 9.9 go
50.43 73.1 nim
114.03 165.3 python

Run All

$ make TIMING=
./cribbage-c 5H-5C-5S-JD-4C-4D
[ 5H 5C 5S JD 4C 4D ]
5H 5C [15.9 4.4 6..39] [-1.2 4.3 -16..13]
5H 5S [15.9 4.4 6..39] [-1.2 4.3 -16..13]
5H JD [16.1 6.0 6..41] [2.4 6.1 -12..22]
5H 4C [16.3 5.2 8..41] [3.1 3.4 -16..13]
5H 4D [16.3 5.2 8..41] [3.1 3.4 -16..13]
5C 5S [15.9 4.4 6..39] [-1.2 4.3 -16..13]
5C JD [16.1 6.0 6..41] [2.4 6.1 -12..22]
5C 4C [16.3 5.2 8..41] [3.0 3.4 -16..13]
5C 4D [16.3 5.2 8..41] [3.1 3.4 -16..13]
5S JD [16.1 6.0 6..41] [2.4 6.1 -12..22]
5S 4C [16.3 5.2 8..41] [3.1 3.4 -16..13]
5S 4D [16.3 5.2 8..41] [3.1 3.4 -16..13]
JD 4C [16.7 5.4 8..38] [9.1 5.1 -5..23]
JD 4D [16.7 5.4 8..38] [9.1 5.2 -7..23]
4C 4D [22.4 4.5 16..53] [10.9 5.1 -10..27]

cd cribbage-rust && cargo build --release --quiet
cribbage-rust/target/release/cribbage 5H-5C-5S-JD-4C-4D
(same output)

./cribbage-cpp 5H-5C-5S-JD-4C-4D
(same output)

node cribbage.js 5H-5C-5S-JD-4C-4D
(same output)

./cribbage-nim 5H-5C-5S-JD-4C-4D
(same output)

./cribbage.py 5H-5C-5S-JD-4C-4D
(same output)

go build -o cribbage-go cribbage.go
./cribbage-go 5H-5C-5S-JD-4C-4D
(same output)

$

COBOL hand scorer

cribbage.cob is a companion, not a ninth analyzer implementation: it scores a single cribbage hand (4 hand cards + cut) — fifteens, pairs, runs, flush, nobs. Written as a dare, compiled with GnuCOBOL 5, and tested (the 29-hand scores 29).

$ make cribbage-cob
$ echo "5C 5D 5H JS 5S" | ./cribbage-cob
Hand + cut (e.g. 5C 5D 5H JS 5S):
Fifteens: 016
Pairs:    012
Runs:     000
Flush:    00
Nobs:     1
Total:    029

Fortran hand scorer

cribbage.f90 is the same kind of companion as the COBOL scorer: it scores a single cribbage hand (4 hand cards + cut). Written in modern free-form Fortran (2018) and commented for the FORTRAN 77 veteran -- implicit none, whole-array operations, and real bit intrinsics (BTEST, POPCNT) where the COBOL version had to fake it with DIVIDE.

$ make cribbage-fortran
$ echo "5C 5D 5H JS 5S" | ./cribbage-fortran
Hand + cut (e.g. 5C 5D 5H JS 5S):
Fifteens: 16
Pairs:    12
Runs:     0
Flush:    0
Nobs:     1
Total:    29

Pascal hand scorer

cribbage.pas is the same kind of companion: it scores a single cribbage hand (4 hand cards + cut), written in Free Pascal and commented for the non-Pascal speaker -- := vs =, subrange types, begin/end, real bitwise operators, and Pascal's built-in set type (used to test run distinctness).

$ make cribbage-pascal
$ echo "5C 5D 5H JS 5S" | ./cribbage-pascal
Hand + cut (e.g. 5C 5D 5H JS 5S):
Fifteens: 16
Pairs:    12
Runs:     0
Flush:    0
Nobs:     1
Total:    29

Haskell hand scorer

cribbage.hs is the same kind of companion: it scores a single cribbage hand (4 hand cards + cut), written in Haskell and commented for the non-Haskeller. The whole subset-enumeration machinery collapses into Data.List.subsequences -- fifteens is a one-liner, and pairs is the classic group . sort idiom.

$ make cribbage-haskell
$ echo "5C 5D 5H JS 5S" | ./cribbage-haskell
Hand + cut (e.g. 5C 5D 5H JS 5S):
Fifteens: 16
Pairs:    12
Runs:     0
Flush:    0
Nobs:     1
Total:    29

About

Analyze cribbage hands in C++, C, Go, Rust, Nim, TypeScript and Python

Topics

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages