home *** CD-ROM | disk | FTP | other *** search
- /*
- * One-Armed Bandit, v 1.01, by Pete Granger (December 13, 1988)
- *
- * Abstract:
- *
- * This is a slot machine simulation which uses curses routines. The
- * setup and payoffs are described in comments below, and the means of
- * play can be read in the print_instructions() routine.
- *
- * Notes:
- *
- * This program has been compiled and run on a VAX running Ultrix 3.0,
- * and on a Sun-3, Sun-4, and Sun-386i. It will compile on an IBM
- * AT-compatible, but there are problems with the stty and curses
- * commands. Fixes for the AT are forthcoming at an undetermined date.
- *
- * If your machine does not have the random() and srandom() functions,
- * then set the value of RANDOM to 0, prior to compiling, and rand() and
- * srand() will be used instead.
- *
- * In order to compile, the -lcurses and -ltermcap options must be
- * used.
- *
- * Release:
- *
- * This program is released to the public domain via usenet on February
- * 15th, 1989. You may redistribute freely, on the condition that no
- * attempt is made to earn a profit for distributing this software. You
- * may change the code as necessary to fit the system on which you wish
- * to run it. The author bears no responsibility for the use or misuse
- * of this game, or any damages caused thereby.
- *
- * Revision History:
- *
- * 1.0 12/09/88 Pete Granger
- * First release for public use. Incorporates all basic functions.
- *
- * 1.01 12/13/88 Pete Granger
- * Added the "refresh" option in play_game().
- *
- */
-
- /*
- This is the configuration and payoff chart for a fair but profitable
- slot machine. It has a 9.54% chance of paying off on each play, and
- (on one-dollar bets) will pay back an average of 91.47% of all bets.
-
- Wheel 1 Wheel 2 Wheel 3
- ----- ----- -----
- Bars 1 1 1
- Bells 2 1 1
- Oranges 1 5 1
- Lemons 3 1 4
- Plums 3 2 3
- Cherries 4 4 4
-
-
- Combination Pays Frequency Total Payoff
- ----- ---- ----- -----
- Bar * 3 1000 1 1000
- Bell * 3 100 2 200
- Orange * 3 50 5 250
- Lemon * 3 20 12 240
- Plum * 3 10 18 180
- Cherry * 3 5 64 320
- Cherry * 2 + Any 2 160 320
- _____ _____
- 262 2510
- (234 profit)
- */
-
- #include <stdio.h>
- #include <curses.h>
-
- #define RANDOM 0
-
- typedef unsigned char u_8;
- typedef char s_8;
- typedef unsigned short u_16;
- typedef short s_16;
- typedef unsigned long u_32;
- typedef long s_32;
-
- #define NUMSYMS 6
- #define NAMELEN 8
- #define ON_WHEEL 14
- #define MIN_ROW 0
- #define MAX_ROW 23
- #define MIN_COL 0
- #define MAX_COL 78
-
- #define BAR 0
- #define BELL 1
- #define ORANGE 2
- #define LEMON 3
- #define PLUM 4
- #define CHERRY 5
-
- #define BAR3 000
- #define BELL3 111
- #define ORANGE3 222
- #define LEMON3 333
- #define PLUM3 444
- #define CHERRY3 555
- #define W_BAR 550
- #define W_BELL 551
- #define W_ORANGE 552
- #define W_LEMON 553
- #define W_PLUM 554
-
- #define PAY_BAR 1000
- #define PAY_BELL 100
- #define PAY_ORANGE 50
- #define PAY_LEMON 20
- #define PAY_PLUM 10
- #define PAY_CHERRY 5
- #define PAY_WILD 2
- #define BUST 0
-
- #define START_MONEY 100
-
- typedef int wheel[ON_WHEEL];
-
- static wheel w1 = {BAR, PLUM, CHERRY, BELL, LEMON, PLUM, CHERRY,
- ORANGE, LEMON, PLUM, CHERRY, BELL, LEMON, CHERRY};
-
- static wheel w2 = {ORANGE, BAR, CHERRY, ORANGE, PLUM, ORANGE, CHERRY,
- BELL, ORANGE, CHERRY, PLUM, LEMON, ORANGE, CHERRY};
-
- static wheel w3 = {BELL, LEMON, CHERRY, ORANGE, PLUM, LEMON, CHERRY,
- BAR, PLUM, CHERRY, LEMON, PLUM, LEMON, CHERRY};
-
- static char symnames[NUMSYMS][NAMELEN+1] = {" *BAR* ", " BELL ",
- " ORANGE ", " LEMON ",
- " PLUM ", " CHERRY " };
-
- static char winflash[6][35] = { "* * *** * * * * **** **** *",
- "* * * ** * ** * * * * *",
- "* ** * * * * * * * * *** **** *",
- "** ** * * ** * ** * * * ",
- "* * *** * * * * **** * * *",
- " " };
-
- #define W1ROW 10
- #define W1COL 5
- #define W2ROW 10
- #define W2COL 17
- #define W3ROW 10
- #define W3COL 29
-
- #define ODDS_R 6
- #define ODDS_C 43
- #define QUERY_R 19
- #define QUERY_C 6
- #define INVALID_R 18
- #define INVALID_C 6
- #define PAY_R 14
- #define PAY_C 6
- #define TOTAL_R 15
- #define TOTAL_C 6
-
-
- #define do_wheel1(W1) { \
- move(W1ROW,W1COL); \
- addstr(symnames[w1[W1]]); \
- refresh(); \
- }
-
- #define do_wheel2(W2) { \
- move(W2ROW,W2COL); \
- addstr(symnames[w2[W2]]); \
- refresh(); \
- }
-
- #define do_wheel3(W3) { \
- move(W3ROW,W3COL); \
- addstr(symnames[w3[W3]]); \
- refresh(); \
- }
-
- #define str_out(R,C) { \
- move((R),(C)); \
- addstr(outbuf); \
- refresh(); \
- }
-
- #define MIN(A,B) (((A)<(B)) ? (A) : (B))
-
- char replybuf[80];
- char outbuf[80];
-
- /*
- * Initialize the random number generator.
- */
-
- void init_rand()
- {
- u_32 z;
-
- z = time((long *)NULL);
- #if RANDOM
- srandom(z);
- #else
- srand(z);
- #endif
- }
-
- /*
- * Returns an integer in the range from min to max, inclusive.
- */
-
- s_16 range(min,max)
- u_16 min, max;
- {
- u_8 det;
- u_16 dist;
- s_16 return_val, discard;
-
- #if RANDOM
- det = random() % 100 + 1;
- #else
- det = rand() % 100 + 1;
- #endif
- dist = max - min + 1;
- if (det > 50)
- #if RANDOM
- discard = random();
- return_val = random() % dist + min;
- #else
- discard = rand();
- return_val = rand() % dist + min;
- #endif
- return(return_val);
- }
-
- /*
- * Prompt the user at a break in the instructions.
- */
-
- rest()
- {
- printf(" -- More -- ");
- while (getchar() != ' ');
- }
-
- /*
- * Give the user instructions on the game.
- */
-
- void print_instructions(in_char)
- char in_char;
- {
- system("clr");
- if (in_char != 'y' && in_char != 'Y') return;
- system("stty cbreak -echo");
- printf(" Instructions for One-Armed Bandit\n");
- printf(" by\n");
- printf(" Pete Granger\n\n");
- printf("OBJECT: To amass a fortune, of course. Also to have a good time\n");
- printf(" playing the slots.\n\n");
- printf(" MEANS: I have designed a slot machine which I consider to be\n");
- printf(" fairly honest. By both statistical and empirical means,\n");
- printf(" it is calculated to have a payoff rate of about 91 percent.\n");
- printf(" The payoffs are as follows:\n\n");
- printf(" Combination Pays Frequency Total Payoff\n");
- printf(" ----- ---- ----- -----\n");
- printf(" Bar * 3 1000 1 1000\n");
- printf(" Bell * 3 100 2 200\n");
- printf(" Orange * 3 50 5 250\n");
- printf(" Lemon * 3 20 12 240\n");
- printf(" Plum * 3 10 18 180\n");
- printf(" Cherry * 3 5 64 320\n");
- printf(" Cherry * 2 + Any 2 160 320\n");
- printf(" ----- -----\n");
- printf(" 262 2510\n");
- rest();
- printf("\n\n\n\n");
- printf(" You will be given an initial bankroll of $%d. Not\n",
- START_MONEY);
- printf(" bad for a day at the casino, right? On each play, you can\n");
- printf(" bet from $1 to $5, and the payoff will be proportional\n");
- printf(" to the bet. You may also place a bet of 0, which means you\n");
- printf(" want to sit out this round, and watch the wheels spin. The\n");
- printf(" catch, of course, is that you don't win anything this way.\n");
- printf(" The only other restriction is that your bet can't exceed\n");
- printf(" your current bankroll.\n");
- printf("\n");
- printf(" If you wish to refresh the screen (e.g. after receiving\n");
- printf(" system messages) enter a 'r' at the 'Bet?' prompt.\n");
- printf("\n");
- printf(" If you decide you want to quit, just enter a 'q' at the\n");
- printf(" 'Bet?' prompt. You can then cash in your winnings and\n");
- printf(" leave the casino.\n");
- printf("\n");
- printf(" Also, if your bankroll reaches 0, you will be asked to\n");
- printf(" leave the casino. But don't worry, you can always come\n");
- printf(" back later.\n");
- printf("\n");
- printf(" Good luck, and enjoy One-Armed Bandit!\n");
- printf("\n");
- rest();
- system("stty -cbreak echo");
- system("clr");
- }
-
- /*
- * Blank part of a line with curses.
- */
-
- void blank_seg(row,col,length)
- u_16 row,col,length;
- {
- char locbuf[80];
- u_8 i;
-
- if (row >= MIN_ROW && row <= MAX_ROW && col >= MIN_COL && col <= MAX_COL)
- {
- if ((col+length-1) > MAX_COL)
- length = MAX_COL - col + 1;
- for (i = 0; i < length; i++)
- locbuf[i] = ' ';
- locbuf[i] = '\0';
- move(row,col);
- addstr(locbuf);
- refresh();
- }
- }
-
- /*
- * Print an odds chart on the screen.
- */
-
- void show_odds()
- {
- extern char outbuf[];
- extern char symnames[NUMSYMS][NAMELEN+1];
-
- sprintf(outbuf," Pete Granger's");
- str_out(ODDS_R-5,ODDS_C);
- sprintf(outbuf," ONE-ARMED BANDIT");
- str_out(ODDS_R-4,ODDS_C);
- sprintf(outbuf," Combination | Odds");
- str_out(ODDS_R-2,ODDS_C);
- sprintf(outbuf,"---------------------------+------");
- str_out(ODDS_R-1,ODDS_C);
- sprintf(outbuf,"%s %s %s | %4d",
- symnames[BAR],symnames[BAR],symnames[BAR],PAY_BAR);
- str_out(ODDS_R,ODDS_C);
- sprintf(outbuf,"%s %s %s | %4d",
- symnames[BELL],symnames[BELL],symnames[BELL],PAY_BELL);
- str_out(ODDS_R+BELL,ODDS_C);
- sprintf(outbuf,"%s %s %s | %4d",
- symnames[ORANGE],symnames[ORANGE],symnames[ORANGE],PAY_ORANGE);
- str_out(ODDS_R+ORANGE,ODDS_C);
- sprintf(outbuf,"%s %s %s | %4d",
- symnames[LEMON],symnames[LEMON],symnames[LEMON],PAY_LEMON);
- str_out(ODDS_R+LEMON,ODDS_C);
- sprintf(outbuf,"%s %s %s | %4d",
- symnames[PLUM],symnames[PLUM],symnames[PLUM],PAY_PLUM);
- str_out(ODDS_R+PLUM,ODDS_C);
- sprintf(outbuf,"%s %s %s | %4d",
- symnames[CHERRY],symnames[CHERRY],symnames[CHERRY],PAY_CHERRY);
- str_out(ODDS_R+CHERRY,ODDS_C);
- sprintf(outbuf,"%s %s %s | %4d",
- symnames[CHERRY],symnames[CHERRY]," *wild* ",PAY_WILD);
- str_out(ODDS_R+CHERRY+1,ODDS_C);
- }
-
-
- /*
- * Draw a box with curses, given the top left and bottom right corners.
- */
-
- void draw_box(tlr,tlc,brr,brc)
- s_16 tlr,tlc,brr,brc;
- {
- u_8 i, j;
- u_16 tmp;
-
- if (tlc > brc)
- {
- tmp = brc; brc = tlc; tlc = tmp;
- }
- if (tlr > brr)
- {
- tmp = brr; brr = tlr; tlr = tmp;
- }
- if (tlc < 0) tlc = 0;
- else if (tlc > 78) tlc = 78;
- if (brc < 0) brc = 0;
- else if (brc > 78) brc = 78;
- if (tlr < 0) tlr = 0;
- else if (tlr > 23) tlr = 23;
- if (brr < 0) brr = 0;
- else if (brr > 23) brr = 23;
- move(tlr,tlc); addch('+'); refresh();
- move(brr,tlc); addch('+'); refresh();
- for (i = tlc + 1; i < brc; i++)
- {
- move(tlr,i); addch('-'); refresh();
- move(brr,i); addch('-'); refresh();
- }
- move(tlr,brc); addch('+'); refresh();
- move(brr,brc); addch('+'); refresh();
- for (i = tlr + 1; i < brr; i++)
- {
- move(i,tlc); addch('|'); refresh();
- for (j = tlc + 1; j < brr; j++)
- {
- move(i,j); addch(' '); refresh();
- }
- move(i,brc); addch('|'); refresh();
- }
- }
-
- /*
- * Draw the three windows where the wheels appear.
- */
-
- void draw_windows()
- {
- extern void draw_box();
-
- draw_box(W1ROW-2,W1COL-2,W1ROW+2,W1COL+NAMELEN+1);
- draw_box(W2ROW-2,W2COL-2,W2ROW+2,W2COL+NAMELEN+1);
- draw_box(W3ROW-2,W3COL-2,W3ROW+2,W3COL+NAMELEN+1);
- }
-
- /*
- * Convert the three wheel indices into a simple integer.
- */
-
- u_16 wheel_sum(s1,s2,s3)
- u_8 s1,s2,s3;
- {
- extern wheel w1, w2, w3;
-
- u_16 return_val;
-
- return_val = (100 * w1[s1]) + (10 * w2[s2]) + w3[s3];
- return(return_val);
- }
-
- /*
- * Determine the payoff odds based on the three wheel indices.
- */
-
- u_16 payoff(s1,s2,s3)
- u_8 s1,s2,s3;
- {
- extern u_16 wheel_sum();
-
- u_16 payoff_index, return_val;
-
- payoff_index = wheel_sum(s1,s2,s3);
- switch (payoff_index)
- {
- case BAR3: return_val = PAY_BAR;
- break;
- case BELL3: return_val = PAY_BELL;
- break;
- case ORANGE3: return_val = PAY_ORANGE;
- break;
- case LEMON3: return_val = PAY_LEMON;
- break;
- case PLUM3: return_val = PAY_PLUM;
- break;
- case CHERRY3: return_val = PAY_CHERRY;
- break;
- case W_BAR:
- case W_BELL:
- case W_ORANGE:
- case W_LEMON:
- case W_PLUM: return_val = PAY_WILD;
- break;
- default: return_val = BUST;
- break;
- }
- return(return_val);
- }
-
- /*
- * Flash the "WINNER!" box on a jackpot.
- */
-
- void flash_win(payoff)
- u_16 payoff;
- {
- extern void draw_box();
- extern void blank_seg();
- extern char winflash[6][35];
- extern char outbuf[];
-
- u_8 i, j, flashes;
-
- draw_box(1,W1COL-2,W1ROW-3,W3COL+NAMELEN+1);
- if (payoff >= PAY_BAR)
- flashes = 10;
- else if (payoff >= PAY_ORANGE)
- flashes = 6;
- else
- flashes = 3;
- #if 0
- for (i = 0; i < flashes; i++)
- {
- for (j = 0; j < 5; j++)
- {
- sprintf(outbuf,winflash[j]);
- str_out(j+2,W1COL-1);
- }
- if (i == flashes - 1)
- sleep(8);
- else
- for (j = 0; j < 5; j++)
- {
- sprintf(outbuf,winflash[j]);
- str_out(j+2,W1COL-1);
- }
- }
- #else
- for (j = 0; j < 5; j++)
- {
- sprintf(outbuf,winflash[j]);
- str_out(j+2,W1COL-1);
- }
- sleep(1);
- #endif
- for (i = 0; i < 7; i++)
- blank_seg(i+1,W1COL-2,36);
- }
-
- /*
- * Refresh the screen at the user's request. Handy if you get mail in
- * the middle of a game or something.
- */
-
- void refresh_screen(ts,br)
- u_32 ts, br;
- {
- extern void draw_windows();
- extern void show_odds();
- extern void blank_seg();
- extern char outbuf[];
-
- initscr();
- draw_windows();
- show_odds();
- if (!ts)
- {
- blank_seg(TOTAL_R,TOTAL_C,78);
- sprintf(outbuf,"Starting bankroll: %ld",br);
- str_out(TOTAL_R,TOTAL_C);
- }
- else
- {
- blank_seg(TOTAL_R,TOTAL_C,78);
- sprintf(outbuf,"New total (after %ld %s) is %ld.",
- ts,((ts != 1) ? "plays" : "play"),br);
- str_out(TOTAL_R,TOTAL_C);
- }
- }
-
- void play_game()
- {
- extern s_16 range();
- extern u_16 payoff();
- extern void draw_windows();
- extern void show_odds();
- extern void flash_win();
- extern void refresh_screen();
- extern void blank_seg();
- extern wheel w1, w2, w3;
- extern char symnames[NUMSYMS][NAMELEN+1];
- extern char replybuf[];
- extern char outbuf[];
-
- u_8 r1, s1, r2, s2, r3, s3, offset;
- u_8 this_bet, maxbet;
- u_16 c1, c2, c3, counter;
- u_32 bankroll, times_spun, payoffs;
-
- bankroll = START_MONEY;
- this_bet = 0;
- payoffs = times_spun = 0;
- s1 = s2 = s3 = 0;
- initscr();
- draw_windows();
- show_odds();
- while (bankroll)
- {
- if (!times_spun)
- {
- blank_seg(TOTAL_R,TOTAL_C,78);
- sprintf(outbuf,"Starting bankroll: %ld",bankroll);
- str_out(TOTAL_R,TOTAL_C);
- }
- maxbet = MIN(5,bankroll);
- sprintf(outbuf,"How much do you wish to bet (0-%d)? ",maxbet);
- blank_seg(QUERY_R,QUERY_C,78);
- str_out(QUERY_R,QUERY_C);
- if (gets(replybuf) == NULL) continue;
- if (replybuf[0] == 'q' || replybuf[0] == 'Q')
- break;
- else if (replybuf[0] == 'r' || replybuf[0] == 'R')
- refresh_screen(times_spun,bankroll);
- else
- {
- if ((this_bet = atoi(replybuf)) > maxbet)
- {
- sprintf(outbuf,"You can't bet that much!");
- str_out(INVALID_R,INVALID_C);
- continue;
- }
- else
- blank_seg(INVALID_R,INVALID_C,30);
- if (this_bet)
- times_spun++;
- r1 = range(5,8);
- r2 = r1 + range(2,4);
- r3 = r2 + range(2,4);
- s1 = (s1 + range(0,ON_WHEEL-1)) % ON_WHEEL;
- s2 = (s2 + range(0,ON_WHEEL-1)) % ON_WHEEL;
- s3 = (s3 + range(0,ON_WHEEL-1)) % ON_WHEEL;
- c1 = ON_WHEEL * r1 + s1;
- c2 = ON_WHEEL * r2 + s2;
- c3 = ON_WHEEL * r3 + s3;
- bankroll -= this_bet;
- for (counter = 0; counter <= c3; counter++)
- {
- offset = counter % ON_WHEEL;
- if (counter <= c1)
- do_wheel1(offset);
- if (counter <= c2)
- do_wheel2(offset);
- do_wheel3(offset);
- }
- if (payoff(s1,s2,s3))
- {
- flash_win(payoff(s1,s2,s3));
- sprintf(outbuf,"The payoff for %d %s is %d.",this_bet,
- ((this_bet != 1) ? "dollars" : "dollar"),
- (int)(this_bet * payoff(s1,s2,s3)));
- bankroll += (this_bet * payoff(s1,s2,s3));
- if (this_bet)
- payoffs++;
- }
- else
- sprintf(outbuf,"No winner.");
- blank_seg(PAY_R,PAY_C,40);
- str_out(PAY_R,PAY_C);
- blank_seg(TOTAL_R,TOTAL_C,78);
- sprintf(outbuf,"New total (after %ld %s) is %ld.",
- times_spun,((times_spun != 1) ? "plays" : "play"),bankroll);
- str_out(TOTAL_R,TOTAL_C);
- }
- }
- blank_seg(QUERY_R,QUERY_C,78);
- endwin();
- if (!bankroll)
- {
- printf("\nYou are bankrupt after %ld %s, %ld %s.\n",
- times_spun,((times_spun != 1) ? "plays" : "play"),
- payoffs,((payoffs != 1) ? "payoffs" : "payoff"));
- printf("\nLuck does not seem to be with you. Unfortunately,\n");
- printf("Guido and Vito, the casino's bouncers, are. They grab\n");
- printf("you by the elbows and escort you to the sidewalk.\n\n");
- printf(" GAME OVER\n\n");
- }
- else
- printf("\nTotal of %ld after %ld %s, %ld %s.\n",bankroll,
- times_spun,((times_spun != 1) ? "plays" : "play"),
- payoffs,((payoffs != 1) ? "payoffs" : "payoff"));
- }
-
- void main()
- {
- extern void init_rand();
- extern void play_game();
- extern char replybuf[];
- extern void print_instructions();
-
- system("clr");
- printf("Would you like instructions, y/n [default is n] -> ");
- fflush(stdout);
- while (gets(replybuf) == NULL);
- print_instructions(replybuf[0]);
- init_rand();
- play_game();
- }
-