How can a blackjack player be assured that the deck is honest? If someone has replaced a random card in the deck with, say, an Ace, How many hands would you have to play and how many aces would he have to see and count to be confident that the deck was altered?
I started with Rick Wicklin’s blog post on creating, shuffling and randomly dealing a standard deck of 52 cards. Then I created a black jack deck of 6x52 cards. I calculated the binomial probability of drawing at least one ace from any number of deals. I used Proc Freq to count the number of Aces that result from these deals. I did the same with an altered deck where I replaced the 2 of Clubs with an Ace of Clubs.
But I don’t know how to get to the core question: How many deals of the altered deck would it take for a player to be, say, 90% confident that there were too many aces in it?
I’ve attached the code that I developed so far to address this question. I hope someone can bring some insight into how it can be modified to address the question.
Thanks in advance for any guidance you can provide,
Gene
/* Create one deck of cards */
data Cards;
length Value $2 Suit $8 Card $3;
array Values[13] $ _temporary_ ('A','2','3','4','5','6','7','8','9','T','J','Q','K');
array Suits[4] $ _temporary_ ('Clubs', 'Diamonds', 'Hearts', 'Spades');
do v = 1 to 13;
do s = 1 to 4;
Value = Values[v]; Suit = Suits[s]; Card = cats(Value,substr(Suit,1,1));
output;
end;
end;
run;
/*For BlackJack we need 6 Decks */
data work.Deck1 work.Deck2 work.Deck3 work.Deck4 work.Deck5 work.Deck6;
set Cards;
run;
data work.HonestBlackJackDeck;
set work.Deck1 work.Deck2 work.Deck3 work.Deck4 work.Deck5 work.Deck6;
run;
/*Create an altered BlackJackDeck by replacing one 2 of Clubs with an Ace of Clubs */
Proc sort data=HonestBlackJackDeck;
by v s;
run;
data work.AlteredBlackJackDeck;
set HonestBlackJackDeck;
By v;
if first.v and v=2 then do;
Value='A';
Suit="Clubs";
Card='AC';
v=1;
s=1;
end;
run;
/*Set number of cards per player */
%Let nCards=2;
/*Set number of players */
%Let nPlayers=1;
/*Set number of deals */
%Let nDeals=100;
/* HONEST BLACK JACK DECK */
/* Standard deviation of expected frequency of drawing at least one ace
in an honest Black Jack Deck */
data _null_;
Title "Binomial Distribution Calculations: Honest Black Jack Deck";
File Print;
Ctot=(312*311)/(2*1);
Put "Number of possible hands: " Ctot;
/*Hands with no aces */
CnoA=(312-24)*(312-24-1)/(2*1);
Put "Number of hands with no aces: " CnoA;
/*Probability of no aces */
PnoA=CnoA/Ctot;
Put "Probability of no aces: " PnoA;
/*Probability of at least one ace */
PA=1-PnoA;
Put "Probability of at least 1 ace: " PA;
/* Expected number of hands with at least 1 ace */
Ndeals=&ndeals;
Put "Number of Deals: " Ndeals;
Expect=&nDeals*PA;
Put "Expected number of hands with at least 1 ace: " Expect;
/* Standard Deviation of a Binomial Distribution */
sigma=sqrt(&nDeals*PA*PnoA);
Put "Standard deviation of hands with of at least 1 ace: " sigma;
/* 90% Confidence Interval */
CI90=1.645*(sigma/sqrt(ndeals));
Put "90% Confidence Interval: " CI90;
Prob_LE_PA=cdf('binom',Expect,PA,&nDeals);
Put "Probability of less than expected hands with ace: " Prob_LE_PA;
Prob_GE_PA=1-Prob_LE_PA;
Put "Probability of greater than expected hands with ace: " Prob_GE_PA;
run;
/* Wicklin code for creating Black Jack Deals */
proc surveyselect data=HonestBlackJackDeck seed=123 NOPRINT
method=SRS /* sample without replacement */
outrandom /* randomize the order of the cards */
N=%eval(&nCards * &nPlayers) /* num cards per deal */
reps=&nDeals /* total number of deals */
out=AllCards_HonestDeck;
run;
/* assign the cards to players */
data AllDeals_HonestDeck;
set AllCards_HonestDeck;
by Replicate;
if first.Replicate then do;
Cnt = 0;
end;
Player = 1 + floor(Cnt/&nCards);
Cnt + 1;
drop Cnt;
run;
/* OPTIONAL: Convert from long form to wide form */
proc transpose data=AllDeals_HonestDeck
out=HonestDeals(rename=(col1-col&nCards=C1-C&nCards) drop=_NAME_);
var Card;
by Replicate Player;
run;
/* Check for an honest deck */
Proc freq data=HonestBlackJackDeck;
Title "Honest Black Jack Deck";
tables value;
run;
/* Find number of deals that contain aces */
Proc freq data=AllDeals_HonestDeck;
Title1 "Honest Black Jack Deck:";
Title2 "Number of deals that contain at least one ace";
where value contains 'A';
tables value /outexpect;
/* ALTERED BLACK JACK DECK */
/*(1 extra Ace of Clubs replacing a 2 of Clubs) */
/* Standard deviation of expected frequency of drawing at least one ace
in an altered Black Jack Deck */
data _null_;
Title1 "Binomial Distribution Calculations: Altered Black Jack Deck";
Title2 "After Substituting an Ace of Clubs for a Deuce of Clubs";
File Print;
Ctot=(312*311)/(2*1);
Put "Number of possible hands: " Ctot;
/*Hands with no aces after substituting and ace for a deuce for a total of 25 aces */
CnoA=(312-25)*(312-25-1)/(2*1);
Put "Number of hands with no aces: " CnoA;
/*Probability of no aces */
PnoA=CnoA/Ctot;
Put "Probability of no aces: " PnoA;
/*Probability of at least one ace */
PA=1-PnoA;
Put "Probability of at least 1 ace: " PA;
/* Expected number of hands with at least 1 ace */
Ndeals=&ndeals;
Put "Number of Deals: " Ndeals;
Expect=&nDeals*PA;
Put "Expected number of hands with at least 1 ace: " Expect;
/* Standard Deviation of a Binomial Distribution */
sigma=sqrt(&nDeals*PA*PnoA);
Put "Standard deviation of hands with of at least 1 ace: " sigma;
/* 90% Confidence Interval */
CI90=1.645*(sigma/sqrt(ndeals));
Put "90% Confidence Interval: " CI90;
run;
proc surveyselect data=AlteredBlackJackDeck seed=123 NOPRINT
method=SRS /* sample without replacement */
outrandom /* randomize the order of the cards */
N=%eval(&nCards * &nPlayers) /* num cards per deal */
reps=&nDeals /* total number of deals */
out=AllCards_AlteredDeck;
run;
/* assign the cards to players */
data AllDeals_AlteredDeck;
set AllCards_AlteredDeck;
by Replicate;
if first.Replicate then do;
Cnt = 0;
end;
Player = 1 + floor(Cnt/&nCards);
Cnt + 1;
drop Cnt;
run;
/* OPTIONAL: Convert from long form to wide form */
proc transpose data=AllDeals_AlteredDeck
out=AlteredDeals(rename=(col1-col&nCards=C1-C&nCards) drop=_NAME_);
var Card;
by Replicate Player;
run;
/* Check for an honest deck */
Proc freq data=AlteredBlackJackDeck;
Title "Altered Black Jack Deck (1 extra Ace of Clubs replacing a 2 of Clubs)";
tables value;
run;
/* Find number of deals that contain aces */
Proc freq data=AllDeals_AlteredDeck;
Title "Altered Black Jack Deck";
Title2 "Number of deals that contain at least one ace";
where value contains 'A';
tables value /outexpect;
... View more