The requirement was to produce a simple (non-graphic) blackjack game that would
learn not to bust.
Kind of a hokey program, perhaps, but I learned a whole lot! My solution is shown below.
The user is the dealer and also the evaluator to help the machine learn not to bust.
Later I went back and restructured the code so that the user can stop
at any time by pressing Esc.
//Matt Hammond
//Final Project, 12/13/95 (brakes added January 1999)
#include <stdio.h>
#include <conio.h>
#include <iostream.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
int SCOREARRAY[21], SCORECELL=0, TOTAL=0, PREVIOUS=0, NUMBERLINE=1,
CARDRECD=0, OLDARRAY[21], R=0, C=0; char EVAL=0; char brake=0;
char answer=0;
struct KARD {char NAME[6];
char SUIT[10];
int VALUE;
int DEALT;
};
KARD CARD, DECK[52], *P;
void display_array()
{
while(EVAL!=27)
{
cout << endl <<endl<< "I'm learning! This chart
shows how I'm doing." << endl
<< "If my hand is at a number with a zero above it, I'd
better not take a hit." <<endl<<endl;
for (SCORECELL=0;SCORECELL<21;SCORECELL++)
printf("%i ", SCOREARRAY[SCORECELL]);
putch(10);putch(13);
NUMBERLINE=0;
for (SCORECELL=0;SCORECELL<9;SCORECELL++)
{printf("%i ", NUMBERLINE++);}
for (SCORECELL=9;SCORECELL<21;SCORECELL++)
{printf("%i ", NUMBERLINE++);}
break;
}
}
void fill_array()
{
for (SCORECELL=0;SCORECELL<21;SCORECELL++)
SCOREARRAY[SCORECELL]=1;
for (SCORECELL=0;SCORECELL<21;SCORECELL++)
OLDARRAY[SCORECELL]=1;
}
void shuffle()
{
int RTR[13]={0,0,0,0,0,0,0,0,0,0,0,0,0};
for(C=0;C<52;C++)DECK[C].DEALT=RTR[C%13];
}
void build_deck()
{
char *PTR[4]={"hearts. ","clubs. ","spades.
","diamonds."};
for(C=0;C<52;C++)strcpy(DECK[C].SUIT,PTR[C % 4]);
char
*QTR[13]={"Ace","Two","Three","Four","Five",
"Six","Seven","Eight","Nine","Ten","Jack","Queen","King"};
for(C=0;C<52;C++)strcpy(DECK[C].NAME,QTR[C % 13]);
int STR[13]={1,2,3,4,5,6,7,8,9,10,10,10,10};
for(C=0;C<52;C++) DECK[C].VALUE=STR[C%13];
for(C=0;C<52;C++) DECK[C].DEALT=0;
shuffle();
}
void consequence ();
void deal ()
{
char V=0;
char R1=0;char Z=0;
R=random(52);
R1=R;
if (DECK[R1].DEALT==0)
{
strcpy (CARD.NAME,DECK[R1].NAME);
strcpy (CARD.SUIT,DECK[R1].SUIT);
CARD.VALUE=DECK[R1].VALUE;
DECK[R1].DEALT=1;
putch (10);putch(13);
for(Z=0;(Z<5&&CARD.NAME[Z]>32);Z++)
printf("%c",CARD.NAME[Z]);
cout << " of ";
for(V=0;V<9;V++)printf("%c", CARD.SUIT[V]);
}
else deal();//Go back to the stack if you pull a duplicate.
}
char bhitme()
{
cout << endl << endl << "Hit me (press any key to hit, 'Esc' to
exit)."
<<endl;
brake=getch();
deal();
CARDRECD=CARD.VALUE;
PREVIOUS=TOTAL;
TOTAL=TOTAL+CARDRECD;
return(brake);
}
char geteval ()
{
if (brake!=27)
{
cout << endl << endl << "My score was "
<< TOTAL << "." << endl << endl;
cout << "How did I do?" << endl <<
"Enter '+' for a good score, '-' for bust." << endl;
EVAL=getche();
return (EVAL);
}
}
void consequence ()
{
shuffle();
EVAL=geteval();
switch (EVAL) {
case 43: SCOREARRAY[PREVIOUS]++;
break;
case 45: {SCOREARRAY[PREVIOUS]--;}
break;
}
if (SCOREARRAY[PREVIOUS]<0)SCOREARRAY[PREVIOUS=0];
if (SCOREARRAY[0]<0)SCOREARRAY[0]=0;
//Prevents negative numbers.
for(SCORECELL=0;SCORECELL<21;SCORECELL++)
OLDARRAY[SCORECELL]=SCOREARRAY[SCORECELL];
//Copies array so we know what we did.
}
char ahitme()
{
cout << endl << endl << "Hit me (press any key to hit, 'Esc' to
exit)."
<<endl;
brake=getch();
deal();
CARDRECD=CARD.VALUE;
TOTAL=CARDRECD;
return (brake);
}
char question()
{
if ((PREVIOUS>=0)&&(TOTAL<21)&&(OLDARRAY[TOTAL]>0))return 'y';
if ((TOTAL<21)&&(brake!=27)&&(OLDARRAY[TOTAL]>0))return 'y';
if ((TOTAL>=21)||(OLDARRAY[TOTAL]<1))
{consequence();TOTAL=0;display_array();return 'y';}
}
main ()
{
clrscr();
randomize();
fill_array();
build_deck();
ahitme();
if (brake==27) return 0;
while (EVAL!=27)
{
bhitme();
question();
if (answer=='y')bhitme();
if (brake==27) return 0;
}
return 0;
}