Skip to content

Instantly share code, notes, and snippets.

@jacobsantos
Last active October 31, 2020 09:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jacobsantos/3c602f522947fda2a7780df3d31837cd to your computer and use it in GitHub Desktop.
Save jacobsantos/3c602f522947fda2a7780df3d31837cd to your computer and use it in GitHub Desktop.
#include <iostream>
using namespace std;
#include <stdlib.h> // For Rand
#include <time.h> // For SRand
#include <GL/glut.h> // For GLUT and OpenGL
#include <GL/glui.h> // For GLUI Menu API
#include <string.h> // For Strings
/*
* TODO:
* 1: Make status Display disappear when new game.
* 2: Betting money should not keep going up or down.
*/
inline int Card() { return(rand() % 12 + 1); }
inline void idle() {}
const int LIMIT = 21;
struct hand // The hand for Computer and Player
{
bool scard1;
bool scard2;
bool scard3;
int card1;
int card2;
int card3;
int card4;
int card5;
int value;
} P1, P2; // P1 is the computer and P2 is the User
struct deck // Holds the cards
{
char ccard;
int value;
} card[] = {
{ ' ', 0 }, // Display nothing at start of game.
{ 'A', 11},
{ '2', 2 },
{ '3', 3 },
{ '4', 4 },
{ '5', 5 },
{ '6', 6 },
{ '7', 7 },
{ '8', 8 },
{ '9', 9 },
{ 'I', 10},
{ 'J', 10},
{ 'Q', 10},
{ 'K', 10}
};
struct bidding // The bidding structure for the Player
{
int cash;
int betting_bid; // This is for the radio on GLUI
int betting_cash; // betting_bid translate in to this
} bid = { // Default values for bidding.
100,
0,
10
};
// Global Values
bool bnew_game = true, done = false; // done is used for stay button
int num_card = 0; // Used for creating new cards for the player.
int main_window; // This is used for something.
int status = 0; // Displaying if the player won, lost, or draw
char dealer[10] = { "Dealer" }; // Text for dealer
char player[10] = { "Player" }; // Text for Player
char cash[10] = { "Cash: $"}; // Text for cash
char backjack[9] = { "Backjack"};// Text for Blackjack
char lost[5] = { "Lost"}; // Text for Lost
char draw[5] = { "Draw"}; // Text for Draw
// I think that perhaps this creates a global structure definition pointer
// used by GLUI but it is strange nevertheless. It works and that is all
// that matters.
GLUI_RadioGroup *radio; // Don't know
GLUI_Panel *game, *betting, *status_p; // Don't know
GLUI_Button *newgame, *stay;
void redisplay(); // redisplay function definition.
void control_glui(int control)
{
switch(control)
{
case 0:
bnew_game = true;
newgame->disable();
break;
case 1:
num_card++;
if((num_card == 1) && (P2.value < LIMIT)) P2.scard1 = true;
if((num_card == 2) && (P2.value < LIMIT)) P2.scard2 = true;
if((num_card == 3) && (P2.value < LIMIT)) P2.scard3 = true;
if(num_card >= 4) glutIdleFunc(idle);
glutIdleFunc(redisplay);
break;
case 2:
newgame->enable();
done = true;
break;
case 3:
switch(bid.betting_bid)
{
case 0:
bid.betting_cash = 10;
break;
case 1:
bid.betting_cash = 50;
break;
case 2:
bid.betting_cash = 100;
break;
default:
break;
}
default:
break;
}
}
void new_game() // This function is init at the beginning of each game.
{
P1.card1 = Card();
P1.value = card[P1.card1].value;
P1.card2 = Card();
P1.value += card[P1.card2].value;
P1.card3 = Card();
P1.card4 = Card();
P1.card5 = Card();
P2.card1 = Card();
P2.value = card[P2.card1].value;
P2.card2 = Card();
P2.value += card[P2.card2].value;
P2.card3 = Card();
P2.card4 = Card();
P2.card5 = Card();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT); // Have no clue what this is but it is needed
char buffer[10];
glColor3f(0.0, 0.0, 0.0); // Black color for Text
glRasterPos2f(-1.0, 0.9); // Position of Text
int i;
for(i=0; i<(int)strlen( dealer ); i++ )
glutBitmapCharacter( GLUT_BITMAP_HELVETICA_18, dealer[i] );
itoa(bid.cash, buffer, 10);
glRasterPos2f(-1.0, 0.0); // Position of Text
for(i=0; i<(int)strlen( player ); i++ )
glutBitmapCharacter( GLUT_BITMAP_HELVETICA_18, player[i] );
glRasterPos2f(0.0, 0.9); // Position of Text
for(i=0; i<(int)strlen( cash ); i++ )
glutBitmapCharacter( GLUT_BITMAP_HELVETICA_18, cash[i] );
for(i=0; i<(int)strlen( buffer ); i++ )
glutBitmapCharacter( GLUT_BITMAP_HELVETICA_18, buffer[i] );
if(done && P2.value <= LIMIT)
{
if(P1.value <= LIMIT)
{
if(P2.value == LIMIT)
{
bid.cash += bid.betting_cash * 2;
status = 1;
}
if(P1.value == P2.value)
{
bid.cash += bid.betting_cash;
status = 3;
}
else if(P1.value > P2.value)
{
bid.cash -= bid.betting_cash;
status = 2;
}
else if(P1.value < P2.value)
{
bid.cash += bid.betting_cash;
status = 3;
}
}
else if(P2.value == LIMIT)
{
bid.cash += bid.betting_cash * 2;
status = 1;
}
else if(P1.value > LIMIT)
{
bid.cash -= bid.betting_cash;
status = 2;
}
}
glRasterPos2f(0.0, 0.0);
switch(status)
{
case 1:
for(i=0; i<(int)strlen( backjack ); i++ )
glutBitmapCharacter( GLUT_BITMAP_HELVETICA_18, backjack[i] );
break;
case 2:
for(i=0; i<(int)strlen( lost ); i++ )
glutBitmapCharacter( GLUT_BITMAP_HELVETICA_18, lost[i] );
break;
case 3:
for(i=0; i<(int)strlen( draw ); i++ )
glutBitmapCharacter( GLUT_BITMAP_HELVETICA_18, draw[i] );
break;
default:
glutBitmapCharacter( GLUT_BITMAP_HELVETICA_18, ' ' );
break;
}
if(bnew_game) // For starting new game, restarts everything
{
new_game();
num_card = 0;
status = 0;
P1.scard1 = false;
P1.scard2 = false;
P1.scard3 = false;
P2.scard1 = false;
P2.scard2 = false;
P2.scard3 = false;
if(P1.value <= 17) P1.scard1 = true;
bnew_game = false;
}
glColor3f(1.0, 0.0, 0.0); // Red Box for Computer
glRectf(-0.2, 0.2, -0.6, 0.8); // Position of second box
glColor3f(0.0, 0.0, 0.0); // Black Color for Text.
glRasterPos2f(-0.3, 0.7); // Position of text
if(card[P1.card2].ccard == 'I')
{
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, '1');
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, '0');
}
else glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, card[P1.card2].ccard);
glColor3f(1.0, 0.0, 0.0); // Red Box for Player
glRectf(-0.2, -0.2, -0.6, -0.8);// Position of Second Box
glColor3f(0.0, 0.0, 0.0); // Black Color for text.
glRasterPos2f(-0.3, -0.3); // Position of text
if(card[P2.card2].ccard == 'I')
{
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, '1');
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, '0');
}
else glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, card[P2.card2].ccard);
glColor3f(0.0, 0.0, 0.0); // Black Box for Computer
glRectf(-0.4, 0.2, -0.8, 0.8); // Computer Card
glRectf(-0.4, -0.2, -0.8, -0.8);// Player card
glColor3f(1.0, 1.0, 1.0); // White Text for card
glRasterPos2f(-0.5, -0.3); // Position of text
if(card[P2.card1].ccard == 'I')
{
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, '1');
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, '0');
}
else glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, card[P2.card1].ccard);
if(P2.scard1) // Display Player Card
{
glColor3f(0.0, 0.0, 1.0);
glRectf(0.0, -0.2, 0.4, -0.8);
glColor3f(0.0, 0.0, 0.0);
glRasterPos2f(0.1, -0.3);
if(card[P2.card3].ccard == 'I')
{
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, '1');
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, '0');
}
else glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, card[P2.card3].ccard);
if(P2.value >= LIMIT)
P2.value = P2.value;
else
P2.value += card[P2.card3].value;
}
if(P2.scard2)
{
glColor3f(0.0, 1.0, 0.0);
glRectf(0.2, -0.2, 0.6, -0.8);
glColor3f(0.0, 0.0, 0.0);
glRasterPos2f(0.3, -0.3);
if(card[P2.card4].ccard == 'I')
{
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, '1');
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, '0');
}
else glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, card[P2.card4].ccard);
if(P2.value >= LIMIT)
P2.value = P2.value;
else
P2.value += card[P2.card4].value;
}
if(P2.scard3)
{
glColor3f(1.0, 0.0, 0.0);
glRectf(0.4, -0.2, 0.8, -0.8);
glColor3f(0.0, 0.0, 0.0);
glRasterPos2f(0.5, -0.3);
if(card[P2.card5].ccard == 'I')
{
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, '1');
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, '0');
}
else glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, card[P2.card5].ccard);
if(P2.value >= LIMIT)
P2.value = P2.value;
else
P2.value += card[P2.card5].value;
}
if(P1.scard1) // Display Computer Card
{
glColor3f(0.0, 0.0, 1.0);
glRectf(0.0, 0.2, 0.4, 0.8);
glColor3f(0.0, 0.0, 0.0);
glRasterPos2f(0.1, 0.7);
if(card[P1.card3].ccard == 'I')
{
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, '1');
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, '0');
}
else glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, card[P1.card3].ccard);
if(P1.value >= LIMIT)
P1.value = P1.value;
else
P1.value += card[P1.card3].value;
if(P1.value < 17) P1.scard2 = true;
}
if(P1.scard2)
{
glColor3f(0.0, 1.0, 0.0);
glRectf(0.2, 0.2, 0.6, 0.8);
glColor3f(0.0, 0.0, 0.0);
glRasterPos2f(0.3, 0.7);
if(card[P1.card4].ccard == 'I')
{
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, '1');
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, '0');
}
else glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, card[P1.card4].ccard);
if(P1.value >= LIMIT)
P1.value = P1.value;
else
P1.value += card[P1.card4].value;
if(P1.value < 17) P1.scard3 = true;
}
if(P1.scard3)
{
glColor3f(1.0, 0.0, 0.0);
glRectf(0.4, 0.2, 0.8, 0.8);
glColor3f(0.0, 0.0, 0.0);
glRasterPos2f(0.5, 0.7);
if(card[P1.card5].ccard == '10')
{
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, '1');
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, '0');
}
else glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, card[P1.card5].ccard);
if(P1.value >= LIMIT)
P1.value = P1.value;
else
P1.value += card[P1.card5].value;
}
glutSwapBuffers();
glFlush();
}
void redisplay()
{
if ( glutGetWindow() != main_window )
glutSetWindow(main_window);
glutPostRedisplay();
if(!P1.scard1 || !P1.scard2 || !P1.scard3 || !P2.scard1 || !P2.scard2 || !P2.scard3)
glutIdleFunc(idle);
}
void keyboard(unsigned char key, int x, int y)
{
switch(key)
{
case 'q':
exit(0);
break;
default:
break;
}
}
int main(int argc, char* argv[])
{
srand(time(NULL));
// Create Window
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(0,0);
main_window = glutCreateWindow("Blackjack");
glutDisplayFunc(display);
glutIdleFunc(redisplay);
glutKeyboardFunc(keyboard);
//Init GLUT; Do not remove
glClearColor(1.0, 1.0, 1.0, 1.0);
/****************************************/
/* Here's the GLUI code */
/****************************************/
GLUI *glui = GLUI_Master.create_glui( "Blackjack Menu", 0, 500, 0 );
GLUI_Master.set_glutKeyboardFunc(keyboard);
GLUI_Master.set_glutIdleFunc(redisplay);
game = glui->add_panel( "Game", GLUI_PANEL_NONE );
newgame = glui->add_button_to_panel(game, "New Game", 0, (GLUI_Update_CB)control_glui);
newgame->disable();
glui->add_separator_to_panel(game);
glui->add_button_to_panel(game, "Hit", 1, (GLUI_Update_CB)control_glui);
stay = glui->add_button_to_panel(game, "Stay", 2, (GLUI_Update_CB)control_glui);
glui->add_button_to_panel(game, "Quit", 0, (GLUI_Update_CB)exit);
betting = glui->add_panel( "Betting" );
radio = glui->add_radiogroup_to_panel(betting, &bid.betting_bid, 3, control_glui);
glui->add_radiobutton_to_group( radio, "$10" );
glui->add_radiobutton_to_group( radio, "$50" );
glui->add_radiobutton_to_group( radio, "$100");
status_p = glui->add_panel( "Options" );
status_p->disable();
glui->add_button_to_panel(status_p, "Insurance", 4, (GLUI_Update_CB)control_glui);
glui->add_button_to_panel(status_p, "Double Down", 5, (GLUI_Update_CB)control_glui);
glui->set_main_gfx_window( main_window );
glutMainLoop();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment