Skip to content

Commit f5dde69

Browse files
committed
informed
1 parent dca64c5 commit f5dde69

3 files changed

Lines changed: 163 additions & 91 deletions

File tree

players/35-informed/blackjack.conf

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
decks = 0 # infinite decks
2-
flat_bet = 1
3-
no_insurance = 1
4-
# error_standard_deviations = 3
5-
# h17 = 0
6-
# rng_seed = 1
7-
hands = 1e6
1+
decks = 1
2+
enhc = false
3+
flat_bet = true
4+
no_insurance = true
5+
shuffle_every_hand = true
6+
# cards = 3 2 5
7+
cards = 2 3 5
88
player = informed

src/players/informed.cpp

Lines changed: 151 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -57,20 +57,25 @@ namespace lbj {
5757
Informed::Informed(Configuration &conf) : Player(conf) {
5858
// TODO: read conf
5959

60-
// TODO. move to reset
61-
decks = 1;
60+
decks = conf.getInt("decks");
61+
enhc = true;
62+
verbose = true;
63+
64+
return;
65+
}
66+
67+
void Informed::reset(void) {
68+
6269
remaining_cards = 52*decks;
63-
for (int rank = 1; rank < 9; rank++) {
70+
for (int rank = 1; rank < 10; rank++) {
6471
remaining[rank] = 4*decks;
6572
}
6673
// first 4 = 4 ranks (T,J,Q,K)
6774
// second 4 = 4 suits (H,S,C,D)
6875
remaining[10] = 4*4*decks;
6976

70-
if (decks != 0) {
71-
verbose = true;
72-
}
73-
77+
// aces are both at 1 & 11
78+
remaining[11] = remaining[1];
7479
return;
7580
}
7681

@@ -103,19 +108,41 @@ int Informed::play() {
103108
// compute the expected values
104109
// -------------------------------------------------------
105110
init();
106-
for (int i = 0; i < 8; i++) {
111+
for (int i = 0; i < 100; i++) {
107112
dealer_bust_european_iteration();
108113
}
109114
dealer_european_to_american();
110115

111116
stand(upcard);
112117

113-
for (int i = 0; i < 8; i++) {
118+
for (int i = 0; i < 100; i++) {
114119
hit_iteration();
115120
}
116121
double_down();
117122
// -------------------------------------------------------
118123

124+
#define BJDEBUG
125+
#ifdef BJDEBUG
126+
for (int f = 0; f < 23; f++) {
127+
std::cout << f << "\t";
128+
for (int i = 0; i < 31; i++) {
129+
std::cout << dealer_hard[f][i] << "\t";
130+
}
131+
std::cout << std::endl;
132+
}
133+
std::cout << std::endl;
134+
135+
for (int f = 0; f < 23; f++) {
136+
std::cout << f << "\t";
137+
for (int i = 0; i < 31; i++) {
138+
std::cout << dealer_soft[f][i] << "\t";
139+
}
140+
std::cout << std::endl;
141+
}
142+
143+
exit(1);
144+
#endif
145+
119146
actionTaken = lbj::PlayerActionTaken::None;
120147
if (canSplit) {
121148
pairs();
@@ -135,8 +162,6 @@ int Informed::play() {
135162
break;
136163

137164
case lbj::PlayerActionRequired::None:
138-
std::cout << "mongocho" << std::endl;
139-
// TODO: count cards!
140165
break;
141166

142167
}
@@ -199,16 +224,28 @@ void Informed::dealer_bust_european_iteration(void) {
199224
// the probability of getting final_total starting from initial_total is
200225
// the sum over n of the existing probabilities (initial+n)->final * chances of getting a card equal to n
201226
// TODO: real cards left
202-
dealer_hard[final_total][initial] = 1.0/13.0*(dealer_hard[final_total][initial+2]) +
203-
1.0/13.0*(dealer_hard[final_total][initial+3]) +
204-
1.0/13.0*(dealer_hard[final_total][initial+4]) +
205-
1.0/13.0*(dealer_hard[final_total][initial+5]) +
206-
1.0/13.0*(dealer_hard[final_total][initial+6]) +
207-
1.0/13.0*(dealer_hard[final_total][initial+7]) +
208-
1.0/13.0*(dealer_hard[final_total][initial+8]) +
209-
1.0/13.0*(dealer_hard[final_total][initial+9]) +
210-
4.0/13.0*(dealer_hard[final_total][initial+10]) +
211-
1.0/13.0*(dealer_soft[final_total][initial+11]);
227+
if (decks == 0) {
228+
dealer_hard[final_total][initial] = 1.0/13.0*(dealer_hard[final_total][initial+2]) +
229+
1.0/13.0*(dealer_hard[final_total][initial+3]) +
230+
1.0/13.0*(dealer_hard[final_total][initial+4]) +
231+
1.0/13.0*(dealer_hard[final_total][initial+5]) +
232+
1.0/13.0*(dealer_hard[final_total][initial+6]) +
233+
1.0/13.0*(dealer_hard[final_total][initial+7]) +
234+
1.0/13.0*(dealer_hard[final_total][initial+8]) +
235+
1.0/13.0*(dealer_hard[final_total][initial+9]) +
236+
4.0/13.0*(dealer_hard[final_total][initial+10]) +
237+
1.0/13.0*(dealer_soft[final_total][initial+11]);
238+
239+
} else {
240+
241+
dealer_hard[final_total][initial] = 0;
242+
// TODO: divide at the end
243+
double den = remaining_cards;
244+
for (int d = 2; d < 11; d++) {
245+
dealer_hard[final_total][initial] += remaining[d] * dealer_hard[final_total][initial + d] / den;
246+
}
247+
dealer_hard[final_total][initial] += remaining[11] * dealer_soft[final_total][initial + 11] / den;
248+
}
212249
}
213250

214251
// With a soft 22, that's going to be the same thing as a hard 12.
@@ -217,22 +254,31 @@ void Informed::dealer_bust_european_iteration(void) {
217254
}
218255

219256
for (int initial = 16; initial > 11; initial--) {
220-
dealer_soft[final_total][initial] = 1.0/13.0*(dealer_soft[final_total][initial+1]) +
221-
1.0/13.0*(dealer_soft[final_total][initial+2]) +
222-
1.0/13.0*(dealer_soft[final_total][initial+3]) +
223-
1.0/13.0*(dealer_soft[final_total][initial+4]) +
224-
1.0/13.0*(dealer_soft[final_total][initial+5]) +
225-
1.0/13.0*(dealer_soft[final_total][initial+6]) +
226-
1.0/13.0*(dealer_soft[final_total][initial+7]) +
227-
1.0/13.0*(dealer_soft[final_total][initial+8]) +
228-
1.0/13.0*(dealer_soft[final_total][initial+9]) +
229-
4.0/13.0*(dealer_soft[final_total][initial+10]);
257+
if (decks == 0) {
258+
dealer_soft[final_total][initial] = 1.0/13.0*(dealer_soft[final_total][initial+1]) +
259+
1.0/13.0*(dealer_soft[final_total][initial+2]) +
260+
1.0/13.0*(dealer_soft[final_total][initial+3]) +
261+
1.0/13.0*(dealer_soft[final_total][initial+4]) +
262+
1.0/13.0*(dealer_soft[final_total][initial+5]) +
263+
1.0/13.0*(dealer_soft[final_total][initial+6]) +
264+
1.0/13.0*(dealer_soft[final_total][initial+7]) +
265+
1.0/13.0*(dealer_soft[final_total][initial+8]) +
266+
1.0/13.0*(dealer_soft[final_total][initial+9]) +
267+
4.0/13.0*(dealer_soft[final_total][initial+10]);
268+
} else {
269+
dealer_soft[final_total][initial] = 0;
270+
double den = remaining_cards;
271+
for (int d = 1; d < 11; d++) {
272+
dealer_soft[final_total][initial] += remaining[d] * dealer_soft[final_total][initial + d] / den;
273+
}
274+
}
230275
}
231276
}
232277

233278
return;
234279
}
235280

281+
// TODO: nicer name
236282
void Informed::dealer_european_to_american(void) {
237283

238284
// TODO: explain!
@@ -241,25 +287,40 @@ void Informed::dealer_european_to_american(void) {
241287
dealer_american[outcome][total] = dealer_hard[outcome][total];
242288
}
243289

244-
dealer_american[outcome][10] = 1.0/12.0*(dealer_hard[outcome][10+2]) +
245-
1.0/12.0*(dealer_hard[outcome][10+3]) +
246-
1.0/12.0*(dealer_hard[outcome][10+4]) +
247-
1.0/12.0*(dealer_hard[outcome][10+5]) +
248-
1.0/12.0*(dealer_hard[outcome][10+6]) +
249-
1.0/12.0*(dealer_hard[outcome][10+7]) +
250-
1.0/12.0*(dealer_hard[outcome][10+8]) +
251-
1.0/12.0*(dealer_hard[outcome][10+9]) +
252-
4.0/12.0*(dealer_hard[outcome][10+10]);
290+
if (enhc == true) {
291+
292+
} else if (decks == 0) {
293+
dealer_american[outcome][10] = 1.0/12.0*(dealer_hard[outcome][10+2]) +
294+
1.0/12.0*(dealer_hard[outcome][10+3]) +
295+
1.0/12.0*(dealer_hard[outcome][10+4]) +
296+
1.0/12.0*(dealer_hard[outcome][10+5]) +
297+
1.0/12.0*(dealer_hard[outcome][10+6]) +
298+
1.0/12.0*(dealer_hard[outcome][10+7]) +
299+
1.0/12.0*(dealer_hard[outcome][10+8]) +
300+
1.0/12.0*(dealer_hard[outcome][10+9]) +
301+
4.0/12.0*(dealer_hard[outcome][10+10]);
253302

254-
dealer_american[outcome][11] = 1.0/9.0*(dealer_soft[outcome][11+1] +
255-
dealer_soft[outcome][11+2] +
256-
dealer_soft[outcome][11+3] +
257-
dealer_soft[outcome][11+4] +
258-
dealer_soft[outcome][11+5] +
259-
dealer_soft[outcome][11+6] +
260-
dealer_soft[outcome][11+7] +
261-
dealer_soft[outcome][11+8] +
262-
dealer_soft[outcome][11+9]);
303+
dealer_american[outcome][11] = 1.0/9.0*(dealer_soft[outcome][11+1] +
304+
dealer_soft[outcome][11+2] +
305+
dealer_soft[outcome][11+3] +
306+
dealer_soft[outcome][11+4] +
307+
dealer_soft[outcome][11+5] +
308+
dealer_soft[outcome][11+6] +
309+
dealer_soft[outcome][11+7] +
310+
dealer_soft[outcome][11+8] +
311+
dealer_soft[outcome][11+9]);
312+
} else {
313+
double den = remaining_cards - remaining[11];
314+
dealer_american[outcome][10] = 0;
315+
for (int d = 2; d < 11; d++) {
316+
dealer_american[outcome][10] += remaining[d] * dealer_hard[outcome][10 + d] / den;
317+
}
318+
den = remaining_cards - remaining[10];
319+
dealer_american[outcome][11] = 0;
320+
for (int d = 1; d < 10; d++) {
321+
dealer_american[outcome][11] += remaining[d] * dealer_soft[outcome][11 + d] / den;
322+
}
323+
}
263324
}
264325

265326
return;
@@ -269,33 +330,49 @@ void Informed::hit_iteration() {
269330

270331
// do not go below 3 if not needed by value
271332
for (int player = 20; player > 3; player--) {
272-
hard_hit[player] = 1.0/13.0*(max(hard_stand[player+2], hard_hit[player+2])) +
273-
1.0/13.0*(max(hard_stand[player+3], hard_hit[player+3])) +
274-
1.0/13.0*(max(hard_stand[player+4], hard_hit[player+4])) +
275-
1.0/13.0*(max(hard_stand[player+5], hard_hit[player+5])) +
276-
1.0/13.0*(max(hard_stand[player+6], hard_hit[player+6])) +
277-
1.0/13.0*(max(hard_stand[player+7], hard_hit[player+7])) +
278-
1.0/13.0*(max(hard_stand[player+8], hard_hit[player+8])) +
279-
1.0/13.0*(max(hard_stand[player+9], hard_hit[player+9])) +
280-
4.0/13.0*(max(hard_stand[player+10], hard_hit[player+10])) +
281-
1.0/13.0*(max(soft_stand[player+11], soft_hit[player+11]));
333+
if (decks == 0) {
334+
hard_hit[player] = 1.0/13.0*(max(hard_stand[player+2], hard_hit[player+2])) +
335+
1.0/13.0*(max(hard_stand[player+3], hard_hit[player+3])) +
336+
1.0/13.0*(max(hard_stand[player+4], hard_hit[player+4])) +
337+
1.0/13.0*(max(hard_stand[player+5], hard_hit[player+5])) +
338+
1.0/13.0*(max(hard_stand[player+6], hard_hit[player+6])) +
339+
1.0/13.0*(max(hard_stand[player+7], hard_hit[player+7])) +
340+
1.0/13.0*(max(hard_stand[player+8], hard_hit[player+8])) +
341+
1.0/13.0*(max(hard_stand[player+9], hard_hit[player+9])) +
342+
4.0/13.0*(max(hard_stand[player+10], hard_hit[player+10])) +
343+
1.0/13.0*(max(soft_stand[player+11], soft_hit[player+11]));
344+
} else {
345+
hard_hit[player] = 0;
346+
double den = remaining_cards;
347+
for (int d = 2; d < 12; d++) {
348+
hard_hit[player] += remaining[d] * (max(hard_stand[player+d], hard_hit[player+d])) / den;
349+
}
350+
}
282351
}
283-
352+
284353
for (int player = 31; player > 21; player--) {
285354
soft_hit[player] = hard_hit[player-10];
286355
}
287356

288357
for (int player = 21; player > 11; player--) {
289-
soft_hit[player] = 1.0/13.0*(max(soft_stand[player+1], soft_hit[player+1])) +
290-
1.0/13.0*(max(soft_stand[player+2], soft_hit[player+2])) +
291-
1.0/13.0*(max(soft_stand[player+3], soft_hit[player+3])) +
292-
1.0/13.0*(max(soft_stand[player+4], soft_hit[player+4])) +
293-
1.0/13.0*(max(soft_stand[player+5], soft_hit[player+5])) +
294-
1.0/13.0*(max(soft_stand[player+6], soft_hit[player+6])) +
295-
1.0/13.0*(max(soft_stand[player+7], soft_hit[player+7])) +
296-
1.0/13.0*(max(soft_stand[player+8], soft_hit[player+8])) +
297-
1.0/13.0*(max(soft_stand[player+9], soft_hit[player+9])) +
298-
4.0/13.0*(max(soft_stand[player+10], soft_hit[player+10]));
358+
if (decks == 0) {
359+
soft_hit[player] = 1.0/13.0*(max(soft_stand[player+1], soft_hit[player+1])) +
360+
1.0/13.0*(max(soft_stand[player+2], soft_hit[player+2])) +
361+
1.0/13.0*(max(soft_stand[player+3], soft_hit[player+3])) +
362+
1.0/13.0*(max(soft_stand[player+4], soft_hit[player+4])) +
363+
1.0/13.0*(max(soft_stand[player+5], soft_hit[player+5])) +
364+
1.0/13.0*(max(soft_stand[player+6], soft_hit[player+6])) +
365+
1.0/13.0*(max(soft_stand[player+7], soft_hit[player+7])) +
366+
1.0/13.0*(max(soft_stand[player+8], soft_hit[player+8])) +
367+
1.0/13.0*(max(soft_stand[player+9], soft_hit[player+9])) +
368+
4.0/13.0*(max(soft_stand[player+10], soft_hit[player+10]));
369+
} else {
370+
soft_hit[player] = 0;
371+
double den = remaining_cards;
372+
for (int d = 1; d < 11; d++) {
373+
soft_hit[player] += remaining[d] * (max(soft_stand[player+d], soft_hit[player+d])) / den;
374+
}
375+
}
299376
}
300377

301378
return;
@@ -306,7 +383,8 @@ void Informed::stand(int upcard) {
306383
// The only way he's going to win is if the dealer busts.
307384
// His expected value is the probability of the dealer busting
308385
// minus the probability of anything else happening.
309-
//So, he can expect to lose by standing on a four against a two of about 29.3% of his bet. That's the same number for standing on everything all the way through a 16 because a 16 is no better than a four or a zero.
386+
// So, he can expect to lose by standing on a four against a two of about 29.3% of his bet.
387+
// That's the same number for standing on everything all the way through a 16 because a 16 is no better than a four or a zero.
310388
for (int player = 4; player < 17; player++) {
311389
hard_stand[player] = dealer_american[22][upcard] - dealer_american[21][upcard] - dealer_american[20][upcard] - dealer_american[19][upcard] - dealer_american[18][upcard] - dealer_american[17][upcard];
312390
}
@@ -317,7 +395,7 @@ void Informed::stand(int upcard) {
317395
hard_stand[20] = dealer_american[22][upcard] - dealer_american[21][upcard] + dealer_american[19][upcard] + dealer_american[18][upcard] + dealer_american[17][upcard] ;
318396
hard_stand[21] = dealer_american[22][upcard] + dealer_american[20][upcard] + dealer_american[19][upcard] + dealer_american[18][upcard] + dealer_american[17][upcard] ;
319397

320-
// soft stand
398+
// soft stand, as for standing it does not make a difference if it is soft or hards
321399
for (int player = 12; player < 22; player++) {
322400
soft_stand[player] = hard_stand[player];
323401
}
@@ -419,16 +497,7 @@ void Informed::info(lbj::Info msg, int p1, int p2) {
419497

420498
case lbj::Info::Shuffle:
421499
std::cout << "Shuffle" << std::endl;
422-
// TODO: reset()
423-
424-
remaining_cards = 52*decks;
425-
for (int rank = 1; rank < 9; rank++) {
426-
remaining[rank] = 4*decks;
427-
}
428-
// first 4 = 4 ranks (T,J,Q,K)
429-
// second 4 = 4 suits (H,S,C,D)
430-
remaining[10] = 4*4*decks;
431-
500+
reset();
432501
break;
433502

434503
case lbj::Info::NewHand:

src/players/informed.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ class Informed : public Player {
4141
private:
4242

4343
// number of decks (0 = infinite)
44-
int decks;
44+
int decks = 0;
45+
bool enhc = false;
4546

4647
// ditto
4748
int remaining_cards;
@@ -52,7 +53,8 @@ class Informed : public Player {
5253
// index = 2 -> deuce
5354
// ...
5455
// index = 10 -> faces
55-
int remaining[11];
56+
// index = 11 -> again ace
57+
int remaining[12];
5658

5759
// dealer's probability of getting a total equal to the first index starting from a total equal to the second
5860
double dealer_hard[SIZE][SIZE]; // european hard hand
@@ -70,6 +72,7 @@ class Informed : public Player {
7072
double split[SIZE];
7173

7274
void init(void);
75+
void reset(void);
7376
void dealer_bust_european_iteration(void);
7477
void dealer_european_to_american(void);
7578
void stand(int upcard);

0 commit comments

Comments
 (0)