Main Logic
Includes and defines...
#include <allegro.h>
#include <vector>
#include <sstream>
#include "deck.h"
#include "player.h"
#include "card.h"
#include "button.h"
#include "time.h"
#define AI_X 200
#define AI_Y 20
#define PLAYER_X 200
#define PLAYER_Y 300
#define B_HIT 0
#define B_STAND 1
#define B_NEW 2
#define B_EXIT 3
void init();
void deinit();
Once in main, the program runs init() to initialize and setup Allegro, a graphics library.
int main() {
init();
After that is finished, it declares all the variables that will be needed during gameplay, such as the Deck, the two Players, the BITMAP buffer, etc.
std::srand(time(0)); // seed the random generator for shuffling
std::stringstream ss; // std::stringstreams are used for num -> text
Deck deck;
Player player;
Player ai;
BITMAP *buf;
BITMAP *bjpplogo;
int turn = 0;
bool done=false;
bool ai_facedown=true;
bool finish_game=false;
bool new_game=true;
int wins=0;
int ties=0;
int losses=0;
std::vector<Button> buttons;
buf = create_bitmap(SCREEN_W,SCREEN_H); // Create our bitmap to draw to
clear_to_color(buf,makecol(0,128,0)); // Clear it to a lovely green
bjpplogo = load_bitmap("images/bjppsm.bmp",default_palette);
// Initialize the vector of buttons...
buttons.push_back(Button(buf,"Hit Me",20,300,100,20,makecol(255,255,255),makecol(0,128,0)));
buttons.push_back(Button(buf,"Stand",20,325,100,20,makecol(255,255,255),makecol(0,128,0)));
buttons.push_back(Button(buf,"New Game",20,400,100,20,makecol(255,255,255),makecol(0,128,0)));
buttons.push_back(Button(buf,"Exit",20,425,100,20,makecol(255,255,255),makecol(0,128,0)));
Now we get to the main game loop...
while (!done) {
// If a new round is starting, we need to shuffle the deck, clean
// up the player hands, and draw some starting cards
if (new_game) {
deck.shuffle();
player.clear();
ai.clear();
ai_facedown=true;
new_game=false;
player.drawCard(&deck,2);
ai.drawCard(&deck,2);
turn = 0;
}
clear_to_color(buf,makecol(0,128,0));
if (bjpplogo) blit(bjpplogo,buf,0,0,15,25,bjpplogo->w,bjpplogo->h);
// If a key is pressed, this will grab it. Just checks for ESC to exit.
if (keypressed()) {
char k = readkey() >> 8;
if (k==KEY_ESC)
done=true;
}
// Loop through the buttons to update and draw each of them, and react
// to clicks
for (int i=0;i<buttons.size();i++) {
buttons[i].update();
buttons[i].draw();
if (buttons[i].isClicked()) {
switch (i) {
case B_HIT:
player.drawCard(&deck,1);
turn++;
break;
case B_STAND:
player.stand();
turn++;
break;
case B_NEW:
new_game=true;
break;
case B_EXIT:
done=true;
break;
}
}
}
// Computer's turn... AI stands on 17
if (turn == 1) {
if (ai.value()<17) {
ai.drawCard(&deck,1);
} else {
ai.stand();
}
turn = 0;
}
// Make the player stand if they bust
if (player.value() > 21) {
player.stand();
}
// Give the turn back to the computer if the player has stood
if (turn==0 && player.isStanding()) turn = 1;
// When both are done, finish out the round
if (ai.isStanding() && player.isStanding()) {
finish_game = true;
}
ss<<"Wins: " << wins;
textout_centre_ex(buf,font,ss.str().c_str(),70,360,makecol(255,255,255),-1);
ss.str("");
ss.clear();
ss<<"Ties: " << ties;
textout_centre_ex(buf,font,ss.str().c_str(),70,370,makecol(255,255,255),-1);
ss.str("");
ss.clear();
ss<<"Losses: " << losses;
textout_centre_ex(buf,font,ss.str().c_str(),70,380,makecol(255,255,255),-1);
ss.str("");
ss.clear();
// Draw the player hands
player.draw(buf,PLAYER_X,PLAYER_Y,false);
ai.draw(buf,AI_X,AI_Y,finish_game?false:true);
if (finish_game) {
int outcome = 0; // Outcome: 0 = loss, 1 = win, 2 = tie
bool p_bj = false;
bool ai_bj = false;
// Check for Busting...
if (ai.value()>21) outcome = 1;
if (player.value()>21) outcome = 0;
if (ai.value()>21&&player.value()>21) outcome = 2;
// otherwise continue...
if (ai.value()<=21&&player.value()<=21) {
// Checking for blackjacks
if (player.handSize() == 2 && player.value() == 21) p_bj=true;
if (ai.handSize() == 2 && ai.value() == 21) ai_bj=true;
// Simple less than comparisons...
if (player.value() < ai.value()) outcome = 0;
if (player.value() > ai.value()) outcome = 1;
if (player.value() == ai.value()) {
outcome = 2; // Equal so tie unless...
if (p_bj&&!ai_bj) outcome = 1; // only player has a blackjack
if (ai_bj&&!p_bj) outcome = 0; // or only AI has a blackjack
}
}
// Displays the outcome to the user and waits for them to hit "OK"
Button ok(buf,"Ok",SCREEN_W/2-50,SCREEN_H/2,100,20,makecol(255,255,255),makecol(40,128,128));
rectfill(buf,SCREEN_W/2-150,SCREEN_H/2-50,SCREEN_W/2+150,SCREEN_H/2+50,makecol(40,128,128));
rect(buf,SCREEN_W/2-150,SCREEN_H/2-50,SCREEN_W/2+150,SCREEN_H/2+50,makecol(255,255,255));
switch (outcome) {
case 0:
textout_centre_ex(buf,font,"You lose. Try again!",
SCREEN_W/2,SCREEN_H/2-22,makecol(255,255,255),-1);
break;
case 1:
textout_centre_ex(buf,font,"You win. CONGRATULATIONS!",
SCREEN_W/2,SCREEN_H/2-22,makecol(255,255,255),-1);
break;
case 2:
textout_centre_ex(buf,font,"You tied. Try again!",
SCREEN_W/2,SCREEN_H/2-22,makecol(255,255,255),-1);
break;
}
textout_centre_ex(buf,font,"Click OK",SCREEN_W/2,SCREEN_H/2-12,makecol(255,255,255),-1);
while (!ok.isClicked()) {
ok.update();
ok.draw();
blit(buf,screen,0,0,0,0,buf->w,buf->h);
rest(1);
}
// Keeps a record of Player losses, wins, and ties
if (outcome==0) losses++;
if (outcome==1) wins++;
if (outcome==2) ties++;
finish_game=false;
new_game=true;
}
// Draw the game board to the screen.
blit(buf,screen,0,0,0,0,buf->w,buf->h);
rest(1);
}
And then wrap up main with a deinit() that just clears the keybuffer.
Note: END_OF_MAIN() is an Allegro-specific macro which does not require a semicolon at the end...
deinit();
return 0;
}
END_OF_MAIN()
And the init() and deinit() functions that were prototyped earlier.
void init() {
int depth, res;
allegro_init();
depth = desktop_color_depth();
if (depth == 0) depth = 32;
set_color_depth(depth);
res = set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
if (res != 0) {
allegro_message(allegro_error);
exit(-1);
}
install_timer();
install_keyboard();
install_mouse();
enable_hardware_cursor();
show_mouse(screen);
set_window_title("Blackjack++");
}
void deinit() {
clear_keybuf();
}
Stephen Cole - Pitt Community College - December 2006
|