Code:
/* tab:8
*
* cribbage.c - Cribbage hand counting for fun and profit
*
* "Copyright (c) 1995 by Steve Lumetta and The Regents of the University
* of California. All rights reserved."
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*
* Author: Steve Lumetta
* Version: 1
* Creation Date: Mon Nov 6 16:32:50 1995
* Filename: cribbage.c
* History:
* SL 1 Mon Nov 6 16:33:22 1995
* First written.
*/
#include <stdio.h>
static void score_hand (int* cards);
int scores[30];
int
main ()
{
int i, cards[5];
for (i = 0; i < 30; i++)
scores[i] = 0;
for (cards[0] = 0; cards[0] < 52; cards[0]++)
for (cards[1] = cards[0] + 1; cards[1] < 52; cards[1]++)
for (cards[2] = cards[1] + 1; cards[2] < 52; cards[2]++)
for (cards[3] = cards[2] + 1; cards[3] < 52; cards[3]++)
for (cards[4] = cards[3] + 1; cards[4] < 52; cards[4]++)
score_hand (cards);
for (i = 0; i < 30; i++)
printf ("%2d %d\n", i, scores[i]);
return 0;
}
static void
score_hand (int* cards)
{
static const int pair_value[4] = {0, 2, 6, 12};
static const int rank_value[13] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10
};
int i, j, rank[5], suit[5], score = 0, r_cnt[4], nobs, next, dup;
int cnt, c3, c4, c5, tot;
/* Find ranks and suits. */
for (i = 0; i < 5; i++) {
rank[i] = cards[i] % 13;
suit[i] = cards[i] / 13;
}
/* Sort by rank. */
for (i = 0; i < 5; i++) {
for (j = i + 1; j < 5; j++) {
if (rank[j] < rank[i]) {
int t;
t = rank[i];
rank[i] = rank[j];
rank[j] = t;
t = suit[i];
suit[i] = suit[j];
suit[j] = t;
}
}
}
/* Prepare to count flushes. */
for (i = 0; i < 4; i++)
r_cnt[i] = 0;
for (i = 0; i < 5; i++)
r_cnt[suit[i]]++;
/* Count pairs. */
for (i = 0; i < 5; ) {
for (j = i + 1; j < 5 && rank[j] == rank[i]; j++);
score += pair_value[j - i - 1];
i = j;
}
/* Count runs. */
for (i = 0; i < 5;) {
next = i;
dup = 1;
cnt = 0;
do {
j = next;
/* Find card duplicity. */
for (next = j + 1; next < 5 && rank[next] == rank[j]; next++);
dup *= (next - j);
cnt++;
} while (next < 5 && rank[next] == rank[j] + 1);
if (cnt >= 3) {
score += cnt * dup;
break;
}
i = next;
}
/* Count his Nobs. */
for (i = 0, nobs = 0; i < 5; i++) {
if (rank[i] != 10 /* Jack */)
continue;
for (j = 0; j < 5; j++)
if (suit[j] == suit[i] && j != i)
nobs++;
}
/* Count 15's. */
for (i = 0; i < 5; i++)
rank[i] = rank_value[rank[i]];
for (i = 4; i > 0; i--) {
for (j = i - 1; j >= 0; j--) {
cnt = rank[i] + rank[j];
if (cnt == 15) {
score += 2;
continue;
}
if (cnt < 15) {
for (c3 = j - 1; c3 >= 0; c3--) {
next = cnt + rank[c3];
if (next == 15) {
score += 2;
continue;
}
if (next < 15) {
for (c4 = c3 - 1; c4 >= 0; c4--) {
tot = next + rank[c4];
if (tot == 15 ||
(c4 > 0 && tot + rank[0] == 15))
score += 2;
}
}
}
}
}
}
/* Count flushes--a four card flush must all be in the hand
(and hence his Nobs must be the upcard). */
for (i = 0; i < 4; i++) {
if (r_cnt[i] == 5) {
score += 5;
break;
}
if (r_cnt[i] == 4) {
scores[score] += (4 - nobs);
scores[score + 1] += nobs;
scores[score + 4] += 1;
return;
}
}
scores[score] += (5 - nobs);
scores[score + 1] += nobs;
}