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[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
White Paper
Linux Management with Red Hat Satellite: Measuring Business Impact and ROI

Linux has become a key foundation for supporting today's rapidly growing IT environments. Linux is being used to deploy business applications and databases, trading on its reputation as a low-cost operating environment. For many IT organizations, Linux is a mainstay for deploying Web servers and has evolved from handling basic file, print, and utility workloads to running mission-critical applications and databases, physically, virtually, and in the cloud. As Linux grows in importance in terms of value to the business, managing Linux environments to high standards of service quality — availability, security, and performance — becomes an essential requirement for business success.

Learn More

Sponsored by Red Hat

White Paper
Private PaaS for the Agile Enterprise

If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.

Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.

Learn More

Sponsored by ActiveState