# Dave Taylor's Final Cribbage Script

``````
#!/bin/sh

# Cribbage - program to evaluate a cribbage hand and
# suggest an optimal subset

# In cribbage, you seek cards that add up to 15, sets of 3-4 cards w/ same
# rank, runs of 3 or more cards and sets of 4 cards of the same suit.

# We'll represent our hand in an array of six cards: hand[0-5] where
# each card has a value of 1-52, which breaks down into
# cardnum / 13 = rank and cardnum % 13 = suit

suits="H"; suits="C"; suits="D"; suits="S";
hand=0; hand=0; hand=0; hand=0; hand=0; hand=0;

# combinations of four choose two and four choose three

fourtwo="0 1"; fourtwo="0 2"; fourtwo="0 3"; fourtwo="1 2"
fourtwo="1 3"; fourtwo="2 3"; fourthree="0 1 2";
fourthree="0 1 3"; fourthree="0 2 3"; fourthree="1 2 3"

debug=0

showcard()
{
# given a card value of 0..51 show the suit and rank

suit=\$(( \$1 / 13 ))
rank=\$(( ( \$1 % 13 ) + 1 ))
case \$rank in
1)  orank="A" ;;
11) orank="J" ;;
12) orank="Q" ;;
13) orank="K" ;;
*) orank=\$rank ;;
esac
showcardvalue=\$orank\${suits[\$suit]}
}

dealhand()
{
# we need to establish a deck from which to deal
# the individual cards (to avoid duplication)

for i in {0..51}
do
deck[\$i]=\$i
done

# we're not going to "shuffle" the deck because we can
# just pick from it randomly instead

for card in {0..5} ; do
hand[\$card]=-1
done

# now let's deal some cards!
for card in {0..5} ; do
until [ \${hand[\$card]} -ne -1 ]
do
pick=\$(( \$RANDOM % 52 ))
hand[\$card]=\${deck[\$pick]}
done
deck[\$pick]=-1	# we've now dealt it so it's no longer available
done
}

showhand()
{
# show our hand neatly

/bin/echo -n "Hand: "
for card in {0..4}
do
showcard \${hand[\$card]}
/bin/echo -n "\$showcardvalue, "
done
showcard \${hand}
echo "\$showcardvalue."
}

sorthand()
{
# hand is dealt, now sort it by card rank...

index=0
tempfile=".deleteme"

for card in {0..5}
do
showcard \${hand[\$card]}
echo "\$rank \${hand[\$card]}"
done | sort -n > \$tempfile

do
hand[\$index]=\$value
index=\$(( \$index + 1 ))
done < \$tempfile

rm -f \$tempfile
}

Calc4cardValue()
{
# given four ranks, see if there are any combinations
# that add up to 15, pairs, runs or flushes.

points=0 ; runof3=0

cs0=\$9; cs1=\${10}; cs2=\${11}; cs3=\${12}       # suits

cardrank=\$1; cardrank=\$2; cardrank=\$3; \
cardrank=\$4 # normalized ranks
cardrankfull=\$5; cardrankfull=\$6; cardrankfull=\$7;
cardrankfull=\$8                      # original ranks

# echo "Calc4cardValue() given original ranks: \
#      \${cardrankfull} \${cardrankfull} \${cardrankfull} \
#      \${cardrankfull}"

# two card combos

for mysubhand in {0..5}
do
sum=0

for thecard in \${fourtwo[\$mysubhand]}
do
sum=\$(( \$sum + \${cardrank[\$thecard]} ))
done
if [ \$sum -eq 15 ] ; then
points=\$(( \$points + 2 ))
if [ \$debug -eq 1 ] ; then
echo "fifteen for two"
fi
fi

# now let's look at pairs
#  remember:  \${string:position:length}

twocards=\${fourtwo[\$mysubhand]}
card1=\${twocards:0:1}
card2=\${twocards:2}

if [ \${cardrankfull[\$card1]} = \${cardrankfull[\$card2]} ] ; then
if [ \$debug -eq 1 ] ; then
echo "a pair \${cardrankfull[\$card1]} and \
\${cardrankfull[\$card2]} for two"
fi
points=\$(( \$points + 2 ))
fi

done

# three card combos

for mysubhand in {0..3}
do
sum=0

for thecard in \${fourthree[\$mysubhand]}
do
sum=\$(( \$sum + \${cardrank[\$thecard]} ))
done
if [ \$sum -eq 15 ] ; then
points=\$(( \$points + 2 ))
if [ \$debug -eq 1 ] ; then
echo "three card fifteen for two"
fi
fi

# now let's check for three-card runs
combo=\${fourthree[\$mysubhand]}

if [ \$(( \${cardrankfull[\${combo:0:1}]} + 1 )) -eq \
\${cardrankfull[\${combo:2:1}]} -a \
\$(( \${cardrankfull[\${combo:2:1}]} + 1 )) -eq \
\${cardrankfull[\${combo:4:1}]} ] ; then
if [ \$debug -eq 1 ] ; then
/bin/echo -n "\${cardrankfull[\${combo:0:1}]} + \
\${cardrankfull[\${combo:2:1}]} + "
echo "\${cardrankfull[\${combo:4:1}]} run for three"
fi
points=\$(( \$points + 3 ))
runof3=\$(( \$runof3 + 1 ))
fi

done

# four cards combos

if [ \$(( \${cardrank} + \${cardrank} + \${cardrank} + \
\${cardrank} )) -eq 15 ] ; then
points=\$(( \$points + 2 ))
if [ \$debug -eq 1 ] ; then
echo "four card fifteen for two"
fi
fi

if [ \$cs0 -eq \$cs1 -a \$cs1 -eq \$cs2 -a \$cs2 -eq \$cs3 ] ; then
if [ \$debug -eq 1 ] ; then
echo "four card flush for four."
fi
points=\$(( \$points + 4 ))
fi

if [ \$runof3 -eq 2 ] ; then
if [ \$debug -eq 1 ] ; then
echo "two runs of three = a run of four. minus two"
fi
points=\$(( \$points - 2 ))
fi

if [ \$debug -eq 1 ] ; then
echo "Total point value of that hand: \$points"
fi
}

handvalue4()
{
# given four cards, how much are they worth unto themselves?

c1=\$1; c2=\$2; c3=\$3; c4=\$4
s1=\$(( \$c1 / 13 )); s2=\$(( \$c2 / 13 ))
s3=\$(( \$c3 / 13 )); s4=\$(( \$c4 / 13 ))

r1=\$(( ( \$c1 % 13 ) + 1 )); r2=\$(( ( \$c2 % 13 ) + 1 ))
r3=\$(( ( \$c3 % 13 ) + 1 )); r4=\$(( ( \$c4 % 13 ) + 1 ))

# now fix rank to normalize for value=10
case \$r1 in
11|12|13) nr1=10 ;;
*) nr1=\$r1 ;;
esac
case \$r2 in
11|12|13) nr2=10 ;;
*) nr2=\$r2 ;;
esac
case \$r3 in
11|12|13) nr3=10 ;;
*) nr3=\$r3 ;;
esac
case \$r4 in
11|12|13) nr4=10 ;;
*) nr4=\$r4 ;;
esac

if [ \$debug -eq 1 ] ; then
echo ""
fi
Calc4cardValue \$nr1 \$nr2 \$nr3 \$nr4 \$r1 \$r2 \$r3 \$r4 \$s1 \$s2 \$s3 \$s4
}

if [ \$# -gt 0 ] ; then
debug=1
fi

dealhand;
sorthand;
showhand;

# six choose four

sixfour="0 1 2 3";  sixfour="0 1 2 4";  sixfour="0 1 2 5";  \
sixfour="0 1 3 4"
sixfour="0 1 3 5";  sixfour="0 1 4 5";  sixfour="0 2 3 4";  \
sixfour="0 2 3 5"
sixfour="0 2 4 5";  sixfour="0 3 4 5";  sixfour="1 2 3 4"; \
sixfour="1 2 3 5"
sixfour="1 2 4 5"; sixfour="1 3 4 5"; sixfour="2 3 4 5"

handvalue=0
besthand=-1

for subhand in {0..14}
do
if [ \$debug -eq 1 ] ; then
/bin/echo -n "Subhand \${subhand}:"
fi
cardnum=0  # start over
for thecard in \${sixfour[\$subhand]}
do
if [ \$debug -eq 1 ] ; then
showcard \${hand[\$thecard]}
/bin/echo -n "  \$showcardvalue"
fi
oursubhand[\$cardnum]=\${hand[\$thecard]}
cardnum=\$(( \$cardnum + 1 ))
done
handvalue4 \${oursubhand} \${oursubhand} \${oursubhand} \
\${oursubhand}

if [ \$debug -eq 1 ] ; then
echo ""
fi

if [ \$points -gt \$handvalue ] ; then
if [ \$debug -eq 1 ] ; then
echo "** hand \$subhand is the best yet, adding up to \$points points"
fi
besthand=\$subhand
handvalue=\$points
fi

done

/bin/echo -n "Your best subhand is worth \$handvalue points: "

for thecard in \${sixfour[\$besthand]}
do
showcard \${hand[\$thecard]}
/bin/echo -n "  \$showcardvalue"
done

echo ""

exit 0
``````