home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
games
/
volume6
/
bandit
/
bandit.c
next >
Wrap
C/C++ Source or Header
|
1989-03-15
|
19KB
|
681 lines
/*
* 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 1
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();
#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("clear");
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("clear");
}
/*
* 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;
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[5]);
str_out(j+2,W1COL-1);
}
}
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: %d",br);
str_out(TOTAL_R,TOTAL_C);
}
else
{
blank_seg(TOTAL_R,TOTAL_C,78);
sprintf(outbuf,"New total (after %d %s) is %d.",
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: %d",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"),
(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 %d %s) is %d.",
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 %d %s, %d %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 %d after %d %s, %d %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("clear");
printf("Would you like instructions, y/n [default is n] -> ");
fflush(stdout);
while (gets(replybuf) == NULL);
print_instructions(replybuf[0]);
init_rand();
play_game();
}