function [ handstats ] = cribbagehand( handstr, iscrib )
%The function takes a six card hand you are delt and determines the
%average, low, and high score you can receive after pegging for all
%combinations of plays. It prints out your hands in order from high to low,
%and returns additional statistics for all possible plays in the structure
%handstats. When returning statistics, the function takes into effect
%whether or not the crib is yours and how many points the crib can get based on the cards
%you give it and the turnover card.
% An example input would be:
% hand = 'As Ad 2d 4h 5c 10c';
% handstats = cribbagehand(hand, 1); if it is your crib, enter 0 instead of
% 1 if it is not your crib
% hand is a string where the cards are entered as mystr = 'As 9c 10d Jc
% 8h 7d'
% iscrib should be 1 if it is your crib and 0 if it is your oppontnets
% crib. Enter any other number if you don't care about the crib.
% handstats has the following fields you can explore for all 15 possible
% plays.
% handstats.c1, .c2, .c3, .c4 are the hold cards.
% handstats.bestTO are the turnover cards that will give you the maximum
% possible points for the given hold cards.
% handstats.avg, .low, .high, and .median are the average, lowest, highest,
% and median score for the given hold cards.
% handstats.ProbAvgOrBetter is probability that you will score higher
% than the average points
% handstats.ProbHigh is the probability of getting the maximum possible
% points for the given hold cards.
deck = {'As', 'Ac', 'Ad', 'Ah', '2s', '2c', '2d', '2h', '3s', '3c', '3d',...
'3h', '4s', '4c', '4d', '4h', '5s', '5c', '5d', '5h', '6s', '6c',...
'6d', '6h', '7s', '7c', '7d', '7h', '8s', '8c', '8d', '8h', '9s',...
'9c', '9d', '9h', '10s', '10c', '10d', '10h', 'Js', 'Jc', 'Jd',...
'Jh', 'Qs', 'Qc', 'Qd', 'Qh', 'Ks', 'Kc', 'Kd', 'Kh'};
spaces = find(handstr == ' ');
hand = cell(1,6);
hand(1) = {handstr(1:spaces(1)-1)};
hand(2) = {handstr(spaces(1)+1:spaces(2)-1)};
hand(3) = {handstr(spaces(2)+1:spaces(3)-1)};
hand(4) = {handstr(spaces(3)+1:spaces(4)-1)};
hand(5) = {handstr(spaces(4)+1:spaces(5)-1)};
hand(6) = {handstr(spaces(5)+1:end)};
%The remaining cards in the deck (rdeck)
rdeck = deck;
indexes = zeros(1,6);
for m = 1:6
indexes(m) = find(strcmp(deck, hand(m)));
end
rdeck(indexes) = [];
%make a matrix of the different possible hands and our cell of stats for
%each one
phands = nchoosek(hand, 4);
tempcell = cell(15,11);
tempcell(1:15,1:4) = phands;
rowheadings = {'c1', 'c2', 'c3', 'c4', 'bestTO' 'avg', 'low', 'high', 'median', 'ProbAvgOrBetter', 'ProbHigh'};
handstats = cell2struct(tempcell, rowheadings, 2);
%% Start putting together and counting points for each possible hand
for m = 1:15
%Reset the points to zero and get the vectors for counting and runs.
%Do the switch for the first 4 cards before going into all possible
%hands so we only do it once for each of the 15 combinations
temphand = phands(m,:);
points = zeros(1,46);
vec4runs = zeros(1,5);
vec15s = zeros(1,5);
isjack = 0;
for k = 1:4
card = phands{m,k};
switch card(1)
case 'A'
vec4runs(k) = 1;
vec15s(k) = 1;
case '2'
vec4runs(k) = 2;
vec15s(k) = 2;
case '3'
vec4runs(k) = 3;
vec15s(k) = 3;
case '4'
vec4runs(k) = 4;
vec15s(k) = 4;
case '5'
vec4runs(k) = 5;
vec15s(k) = 5;
case '6'
vec4runs(k) = 6;
vec15s(k) = 6;
case '7'
vec4runs(k) = 7;
vec15s(k) = 7;
case '8'
vec4runs(k) = 8;
vec15s(k) = 8;
case '9'
vec4runs(k) = 9;
vec15s(k) = 9;
case '1'
vec4runs(k) = 10;
vec15s(k) = 10;
case 'J'
vec4runs(k) = 11;
vec15s(k) = 10;
isjack = 1;
case 'Q'
vec4runs(k) = 12;
vec15s(k) = 10;
case 'K'
vec4runs(k) = 13;
vec15s(k) = 10;
end
end
crib = hand;
cribindex = zeros(1,4);
crib15s = zeros(1,3);
cribruns = zeros(1,3);
%Get the crib
for k = 1:4
cribindex(k) = find(strcmp(hand, temphand(k)));
end
crib(cribindex) = [];
cribjack = 0;
for k = 1:2
card = crib{k};
switch card(1)
case 'A'
cribruns(k) = 1;
crib15s(k) = 1;
case '2'
cribruns(k) = 2;
crib15s(k) = 2;
case '3'
cribruns(k) = 3;
crib15s(k) = 3;
case '4'
cribruns(k) = 4;
crib15s(k) = 4;
case '5'
cribruns(k) = 5;
crib15s(k) = 5;
case '6'
cribruns(k) = 6;
crib15s(k) = 6;
case '7'
cribruns(k) = 7;
crib15s(k) = 7;
case '8'
cribruns(k) = 8;
crib15s(k) = 8;
case '9'
cribruns(k) = 9;
crib15s(k) = 9;
case '1'
cribruns(k) = 10;
crib15s(k) = 10;
case 'J'
cribruns(k) = 11;
crib15s(k) = 10;
cribjack = 1;
case 'Q'
cribruns(k) = 12;
crib15s(k) = 10;
case 'K'
cribruns(k) = 13;
crib15s(k) = 10;
end
end
%Now get the first possible turnover card, finish the crib and start
%counting points.
for n = 1:46
temphand(5) = rdeck(n);
card = rdeck{n};
pntscnt = 0;
cribpnts = 0;
switch card(1)
case 'A'
vec4runs(5) = 1;
vec15s(5) = 1;
cribruns(3) = 1;
crib15s(3) = 1;
case '2'
vec4runs(5) = 2;
vec15s(5) = 2;
cribruns(3) = 2;
crib15s(3) = 2;
case '3'
vec4runs(5) = 3;
vec15s(5) = 3;
cribruns(3) = 3;
crib15s(3) = 3;
case '4'
vec4runs(5) = 4;
vec15s(5) = 4;
cribruns(3) = 4;
crib15s(3) = 4;
case '5'
vec4runs(5) = 5;
vec15s(5) = 5;
cribruns(3) = 5;
crib15s(3) = 5;
case '6'
vec4runs(5) = 6;
vec15s(5) = 6;
cribruns(3) = 6;
crib15s(3) = 6;
case '7'
vec4runs(5) = 7;
vec15s(5) = 7;
cribruns(3) = 7;
crib15s(3) = 7;
case '8'
vec4runs(5) = 8;
vec15s(5) = 8;
cribruns(3) = 8;
crib15s(3) = 8;
case '9'
vec4runs(5) = 9;
vec15s(5) = 9;
cribruns(3) = 9;
crib15s(3) = 9;
case '1'
vec4runs(5) = 10;
vec15s(5) = 10;
cribruns(3) = 10;
crib15s(3) = 10;
case 'J'
vec4runs(5) = 11;
vec15s(5) = 10;
cribruns(3) = 11;
crib15s(3) = 10;
case 'Q'
vec4runs(5) = 12;
vec15s(5) = 10;
cribruns(3) = 12;
crib15s(3) = 10;
case 'K'
vec4runs(5) = 13;
vec15s(5) = 10;
cribruns(3) = 13;
crib15s(3) = 10;
end %end switch
%% Time to start counting points! First, look at the Jack suit if there
%is one.
if isjack
for k = 1:4
if strcmp(temphand{k}(1),'J')
if strcmp(card(end), temphand{k}(2))
pntscnt = pntscnt + 1;
end
end
end
end %end searching for Jack
%% Now check for a flush
if strcmp(temphand{1}(end),temphand{2}(end)) && strcmp(temphand{1}(end), ...
temphand{3}(end)) && strcmp(temphand{1}(end), temphand{4}(end))
pntscnt = pntscnt + 4;
if strcmp(temphand{1}(end),temphand{5}(end))
pntscnt = pntscnt + 1;
end
end % end checking for flush
%% Get 15s
if 15 <= sum(vec15s)
if isequal(sum(vec15s), 15)
pntscnt = pntscnt + 2;
else
twos = nchoosek(vec15s, 2)';
twostotal = sum(twos);
twos15 = find(twostotal == 15);
pntscnt = pntscnt + length(twos15)*2;
threes = nchoosek(vec15s, 3)';
threestotal = sum(threes);
threes15 = find(threestotal == 15);
pntscnt = pntscnt + length(threes15)*2;
fours = nchoosek(vec15s, 4)';
fourstotal = sum(fours);
fours15 = find(fourstotal == 15);
pntscnt = pntscnt + length(fours15)*2;
end
end %end summing 15s
%% Get the vector to start looking for runs and pairs
sortedhand = sort(vec4runs);
pairsorruns = diff(sortedhand);
%Look for pairs
if length(find(pairsorruns == 0)) >= 1
pairs = nchoosek(temphand, 2);
for p = 1:length(pairs(:,1))
if strcmp(pairs{p,1}(1), pairs{p,2}(1))
pntscnt = pntscnt + 2;
end
end
end %end looking for pairs
%% Look for runs
num1s = find(pairsorruns == 1);
num0s = find(pairsorruns == 0);
if length(num1s) >= 2
numrunsof4 = 0;
numrunsof3 = 0;
if all(pairsorruns == 1)
pntscnt = pntscnt + 5;
elseif isequal(length(num1s), 3)
runsof4 = nchoosek(sortedhand, 4)';
isrunof4 = diff(runsof4);
for p = 1:length(isrunof4(1,:))
if all(isrunof4(:,p) == 1)
numrunsof4 = numrunsof4 + 1;
end
end
if numrunsof4 ~= 0
pntscnt = pntscnt + 4*numrunsof4;
else
pntscnt = pntscnt + 3;
end
elseif isequal(length(num1s), 2)
runsof3 = nchoosek(sortedhand, 3)';
isrunof3 = diff(runsof3);
for p = 1: length(isrunof3(1,:))
if all(isrunof3(:,p) == 1)
numrunsof3 = numrunsof3 + 1;
end
end
pntscnt = pntscnt + 3*numrunsof3;
end %end counting points of runs.
end %end for length(num1s) >= 2
%% Done counting the main hand! Time to count the crib!
if cribjack
for k = 1:2
if strcmp(crib{k}(1),'J')
if strcmp(card(end), crib{k}(2))
cribpnts = cribpnts + 1;
end
end
end
end %end searching for Jack
if 15 <= sum(crib15s)
if isequal(sum(crib15s), 15)
cribpnts = 2;
else
cribtwos = nchoosek(crib15s, 2)';
cribtwostotal = sum(cribtwos);
cribtwos15 = find(cribtwostotal == 15);
cribpnts = cribpnts + length(cribtwos15)*2;
end
end %end looking for 15s in the crib
% Find pairs and runs in the crib
sortedcrib = sort(cribruns);
cribrunsorpairs = diff(sortedcrib);
if all(cribrunsorpairs == 0)
cribpnts = cribpnts + 6;
elseif all(cribrunsorpairs == 1)
cribpnts = cribpnts + 3;
elseif isequal(length(find(cribrunsorpairs == 0)), 1)
cribpnts = cribpnts + 2;
end
% Done counting up all points. Add or subtract the crib from the main
% hand and put into the 1 x 46 matrix points at position n. If is crib
% is anything other than 1 or 0, the crib is not counted. Use that
% option for last hand when you don't care about the crib
if isequal(iscrib, 1)
points(n) = pntscnt + cribpnts;
elseif isequal(iscrib, 0)
points(n) = pntscnt - cribpnts;
else
points(n) = pntscnt;
end
end %end for 46 count
%% Now let's put together the statistics for the hand before moving
% to the next one
bestposition = find(points == max(points));
bestTOcards = rdeck(bestposition);
handstats(m).bestTO = bestTOcards;
handstats(m).avg = mean(points);
handstats(m).low = min(points);
handstats(m).high = max(points);
handstats(m).median = median(points);
handstats(m).ProbHigh = length(bestTOcards)/46;
avgorbetter = find(points >= mean(points));
handstats(m).ProbAvgOrBetter = length(avgorbetter)/46;
end %end for 15 hand count
%% Sort Handstats in order of best average hands
[~, order] = sort([handstats(:).avg]);
handstats = handstats(fliplr(order));
% Will use the highest possible hand as the first tie breaker
ties = find([handstats.avg] == max([handstats.avg]));
if length(ties) > 1
temphandstats = handstats(1:length(ties));
[~, tieindex] = sort([temphandstats(1:length(ties)).high], 'descend');
temphandstats = temphandstats(tieindex);
handstats(1:length(ties)) = temphandstats;
end
fprintf('\n\n Hand Rank AVG High Low Median Max%% >AVG%%\n')
for m = 1:9
fprintf('%g) %s %s %s %s %.2f %g %g %g %.2f %.2f\n',...
m, handstats(m).c1, handstats(m).c2, handstats(m).c3, handstats(m).c4,...
handstats(m).avg, handstats(m).high, handstats(m).low,...
handstats(m).median, handstats(m).ProbHigh, handstats(m).ProbAvgOrBetter)
end
for m = 10:15
fprintf('%g)%s %s %s %s %.2f %g %g %g %.2f %.2f\n',...
m, handstats(m).c1, handstats(m).c2, handstats(m).c3, handstats(m).c4,...
handstats(m).avg, handstats(m).high, handstats(m).low,...
handstats(m).median, handstats(m).ProbHigh, handstats(m).ProbAvgOrBetter)
end
fprintf('\n\n')
% fprintf('\nYour best possible hand is %s %s %s %s with the following stats:\n'...
% ,handstats(1).c1,handstats(1).c2, handstats(1).c3, handstats(1).c4)
% fprintf('AVG = %.2f; Low = %.2f; Max = %.2f; Median = %.2f\n',...
% handstats(1).avg, handstats(1).low, handstats(1).high, handstats(1).median)
% fprintf('Probability of high = %.2f; Probability of beating AVG = %.2f \n',...
% handstats(1).ProbHigh, handstats(1).ProbAvgOrBetter)
%
% fprintf('\nYour 2nd best hand is %s %s %s %s with the following stats:\n'...
% ,handstats(2).c1,handstats(2).c2, handstats(2).c3, handstats(2).c4)
% fprintf('AVG = %.2f; Low = %.2f; Max = %.2f; Median = %.2f\n',...
% handstats(2).avg, handstats(2).low, handstats(2).high, handstats(2).median)
% fprintf('Probability of high = %.2f; Probability of beating AVG = %.2f\n',...
% handstats(2).ProbHigh, handstats(2).ProbAvgOrBetter)
%
% fprintf('\nYour 3rd best hand is %s %s %s %s with the following stats:\n'...
% ,handstats(3).c1,handstats(3).c2, handstats(3).c3, handstats(3).c4)
% fprintf('AVG = %.2f; Low = %.2f; Max = %.2f; Median = %.2f\n',...
% handstats(3).avg, handstats(3).low, handstats(3).high, handstats(3).median)
% fprintf('Probability of high = %.2f; Probability of beating AVG = %.2f\n\n',...
% handstats(3).ProbHigh, handstats(3).ProbAvgOrBetter)
end