#!/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[0]="H"; suits[1]="C"; suits[2]="D"; suits[3]="S";
hand[0]=0; hand[1]=0; hand[2]=0; hand[3]=0; hand[4]=0; hand[5]=0;
# combinations of four choose two and four choose three
fourtwo[0]="0 1"; fourtwo[1]="0 2"; fourtwo[2]="0 3"; fourtwo[3]="1 2"
fourtwo[4]="1 3"; fourtwo[5]="2 3"; fourthree[0]="0 1 2";
fourthree[1]="0 1 3"; fourthree[2]="0 2 3"; fourthree[3]="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
# start with an undealt hand:
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[5]}
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
while read rank value
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.
# return total point value of the four card subhand
points=0 ; runof3=0
cs0=$9; cs1=${10}; cs2=${11}; cs3=${12} # suits
cardrank[0]=$1; cardrank[1]=$2; cardrank[2]=$3; \
cardrank[3]=$4 # normalized ranks
cardrankfull[0]=$5; cardrankfull[1]=$6; cardrankfull[2]=$7;
cardrankfull[3]=$8 # original ranks
# echo "Calc4cardValue() given original ranks: \
# ${cardrankfull[0]} ${cardrankfull[1]} ${cardrankfull[2]} \
# ${cardrankfull[3]}"
# 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[0]} + ${cardrank[1]} + ${cardrank[2]} + \
${cardrank[3]} )) -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
## Ready to start calculating!
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]="0 1 2 3"; sixfour[1]="0 1 2 4"; sixfour[2]="0 1 2 5"; \
sixfour[3]="0 1 3 4"
sixfour[4]="0 1 3 5"; sixfour[5]="0 1 4 5"; sixfour[6]="0 2 3 4"; \
sixfour[7]="0 2 3 5"
sixfour[8]="0 2 4 5"; sixfour[9]="0 3 4 5"; sixfour[10]="1 2 3 4"; \
sixfour[11]="1 2 3 5"
sixfour[12]="1 2 4 5"; sixfour[13]="1 3 4 5"; sixfour[14]="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[0]} ${oursubhand[1]} ${oursubhand[2]} \
${oursubhand[3]}
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