games-request@tekred.TEK.COM (09/18/87)
Submitted by: granger@cg-atla.UUCP (Peter Granger )
Comp.sources.games: Volume 2, Issue 52
Archive-name: mastrm
[Compiled and ran OK on our 4.3bsd Vax. No other gaurantees.
-br]
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of shell archive."
# Contents: README mastrm.c
# Wrapped by billr@tekred on Thu Sep 17 17:03:50 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f README -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"README\"
else
echo shar: Extracting \"README\" \(679 characters\)
sed "s/^X//" >README <<'END_OF_README'
X This game, Master Mind, was written by Peter E. Granger and released to
X the public domain via Usenet on Sept. 1, 1987. Master Mind is based on
X the game by the same name which is marketed by Invicta Plastics. This
X game has not been licensed or recognized in anyway by Invicta Plastics.
X Master Mind, as presented here, is intended solely for the enjoyment of
X the public, and is not to be used for profit. Recipients are permitted
X to redistribute this code as long as they do not attempt to gain any
X profit from it, and may edit this code as they see fit.
X
X - Pete Granger
X granger@cg-atla.UUCP
END_OF_README
if test 679 -ne `wc -c <README`; then
echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f mastrm.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"mastrm.c\"
else
echo shar: Extracting \"mastrm.c\" \(18986 characters\)
sed "s/^X//" >mastrm.c <<'END_OF_mastrm.c'
X/*****************************************************************************
X
X This game, Master Mind, was written by Peter E. Granger and released to
X the public domain via Usenet on Sept. 1, 1987. Master Mind is based on
X the game by the same name which is marketed by Invicta Plastics. This
X game has not been licensed or recognized in anyway by Invicta Plastics.
X Master Mind, as presented here, is intended solely for the enjoyment of
X the public, and is not to be used for profit. Recipients are permitted
X to redistribute this code as long as they do not attempt to gain any
X profit from it, and may edit this code as they see fit.
X
X - Pete Granger
X
X ***************************************************************************/
X
X#include <stdio.h>
X
X#define FALSE 0
X#define TRUE 1
X#define NONE 0
X#define WHITE 1
X#define BLACK 2
X#define BAD_COLOR -1
X
X struct peg { int color;
X int used };
X
X struct guess { struct peg pegs[4];
X int blacks, whites };
X
X static char *col[6] = { "white",
X "black",
X "red",
X "green",
X "yellow",
X "blue" };
X int dig[6];
X int cur;
X struct guess guesses[18];
X struct guess dummy[18];
X struct guess code;
X int game_won, player, check, cons;
X
Xsetcolors()
X{
X extern int dig[];
X int x, val, y;
X int digit_found, place_found;
X
X for (x = 0; x < 6; x++)
X dig[x] = BAD_COLOR;
X for (x = 6; x > 1; x--)
X {
X val = rand() % x;
X place_found = FALSE;
X while (!place_found)
X {
X digit_found = FALSE;
X for (y = 0; y < (6 - x); y++)
X if (val == dig[y])
X digit_found = TRUE;
X if (!digit_found)
X {
X dig[y] = val;
X place_found = TRUE;
X }
X else
X val = (val + 5) % 6;
X }
X }
X dig[5] = 15 - dig[4] - dig[3] - dig[2] - dig[1] - dig[0];
X}
X
Xset_dummy()
X{
X extern struct guess guesses[];
X extern struct guess dummy[];
X extern int cur;
X
X int x;
X
X dummy[cur].blacks = dummy[cur].whites = 0;
X for (x = 0; x < 4; x++)
X {
X dummy[cur].pegs[x].used = NONE;
X dummy[cur].pegs[x].color = guesses[cur].pegs[x].color;
X }
X}
X
Xmake_code(ges)
X
Xstruct guess *ges;
X{
X int x, temp;
X
X for (x = 0; x < 4; x++)
X {
X temp = ges->pegs[x].color = rand() % 6;
X ges->blacks = 0;
X ges->whites = 0;
X }
X}
X
Xfind_digit(col_name)
X
Xchar col_name[7];
X{
X extern int dig[];
X
X int s;
X
X for (s = 0; s < 6; s++)
X if (strlen(col_name) == strlen(col[dig[s]]) &&
X !(strncmp(col[dig[s]],col_name,strlen(col_name))))
X return(s);
X return(BAD_COLOR);
X}
X
Xget_code(kode)
X
Xstruct guess *kode;
X
X{
X extern int cur;
X
X char c[4][7];
X int bad_in, code_valid;
X int x;
X
X code_valid = bad_in = FALSE;
X kode->blacks = kode->whites = 0;
X while (!code_valid)
X {
X code_valid = TRUE;
X if (bad_in)
X printf("Previous code contained invalid color.\n");
X if (player)
X printf("\nPlease enter guess #%d -> ",cur + 1);
X else
X printf("Please enter the correct code -> ");
X scanf("%s %s %s %s",c[0],c[1],c[2],c[3]);
X while (getchar() != '\n');
X if (!player)
X printf("\n");
X for (x = 0; x < 4; x++)
X {
X kode->pegs[x].used = NONE;
X kode->pegs[x].color = find_digit(c[x]);
X if (kode->pegs[x].color == BAD_COLOR)
X {
X code_valid = FALSE;
X bad_in = TRUE;
X }
X }
X }
X}
X
Xscore()
X{
X extern struct guess code;
X extern struct guess guesses[];
X extern int game_won;
X
X int x, y;
X
X for (x = 0; x < 4; x++)
X guesses[cur].pegs[x].used = code.pegs[x].used = NONE;
X for (x = 0; x < 4; x++)
X if (guesses[cur].pegs[x].color == code.pegs[x].color)
X {
X code.pegs[x].used = guesses[cur].pegs[x].used = BLACK;
X guesses[cur].blacks++;
X if (player)
X printf("b");
X }
X if (guesses[cur].blacks != 4)
X {
X for (x = 0; x < 4; x++)
X for (y = 0; y < 4; y++)
X if (guesses[cur].pegs[x].color == code.pegs[y].color &&
X !code.pegs[y].used && !guesses[cur].pegs[x].used)
X {
X code.pegs[y].used = guesses[cur].pegs[x].used = WHITE;
X guesses[cur].whites++;
X if (player)
X printf("w");
X }
X }
X else
X game_won = TRUE;
X if (player)
X if (guesses[cur].blacks != 0 || guesses[cur].whites != 0)
X printf("\n\n");
X else
X printf("No score.\n\n");
X}
X
Xrest()
X{
X printf("\n-- More -- ");
X while (getchar() != '\n');
X}
X
Xprint_instructions()
X{
Xprintf ("\n\n Instructions for Master Mind\n");
Xprintf (" by\n");
Xprintf (" Pete Granger\n\n");
Xprintf ("OBJECT: To match the four color code set by your opponent, using\n");
Xprintf (" clues from previous guesses.\n\n");
Xprintf ("METHOD: Begin by telling the computer whether you wish to guess,\n");
Xprintf (" or to create the code which it will guess. It is usually\n");
Xprintf (" more interesting to be the guesser, but I wanted you to \n");
Xprintf (" have the option.\n\n");
Xprintf (" First, we will cover how to play if you are guessing:\n\n");
Xprintf (" You will be asked to specify whether you want 'coaching'.\n");
Xprintf (" This means, the computer will tell you whether your guess\n");
Xprintf (" is inconsistent with information from previous guesses (it\n");
Xprintf (" is considered inconsistent if it cannot be the correct\n");
Xprintf (" code, and you could deduce this).\n\n");
Xrest();
Xprintf (" You will then be asked for your first guess. A guess is\n");
Xprintf (" a set of four colors, separated by at least one space. \n");
Xprintf (" The valid colors are:\n\n");
Xprintf (" black blue green red white yellow\n\n");
Xprintf (" Note that these spellings must be used exactly. If you\n");
Xprintf (" make a mistake the machine will let you know, and give\n");
Xprintf (" another chance.\n\n");
Xprintf (" The machine will then return your score for that guess.\n");
Xprintf (" Score is given in black and white pegs (b and w). A black\n");
Xprintf (" score peg means that one of your guessed colors is in the\n");
Xprintf (" correct place. A white score peg means that one of your\n");
Xprintf (" guessed colors appears in the correct code, but not in\n");
Xprintf (" the same location. (If you have selected coaching, that\n");
Xprintf (" will occur at this time also.)\n\n");
Xprintf (" You will now be given a choice of 'guess, refresh, hint\n");
Xprintf (" or quit'. Enter your choice. Either first letter or the\n");
Xprintf (" entire word is okay, case is ignored. If you just hit\n");
Xprintf (" return, this is taken as meaning 'guess'.\n");
Xrest();
Xprintf (" GUESS: Make another guess, same as before, using the\n");
Xprintf (" score from previous guesses to make deductions.\n");
Xprintf (" You have 18 chances to find the right code.\n\n");
Xprintf (" REFRESH: Shows all your previous guesses and scores.\n\n");
Xprintf (" HINT: By entering the number of a previous guess, and one\n");
Xprintf (" of the pegs in that guess, you may find out what \n");
Xprintf (" score that particular peg received. Note: If you\n");
Xprintf (" have a color in your guess twice, and it is only in\n");
Xprintf (" the code once, or vice-versa, it will only receive\n");
Xprintf (" one scoring peg, black taking precedence over white.\n");
Xprintf (" Hence, it may sometimes be in your best interest to\n");
Xprintf (" ask for the hint on the first instance of the color\n");
Xprintf (" in your guess.\n\n");
Xprintf (" QUIT: You don't want to play anymore. Remember, the code\n");
Xprintf (" will not be revealed if you quit.\n\n");
Xprintf (" When you find the correct sequence, the computer will let\n");
Xprintf (" you know, and ask if you wish to begin another game. The\n");
Xprintf (" default value for this is 'no'.\n");
Xrest();
Xprintf (" Now we will consider how to play if you wish to make up\n");
Xprintf (" the code and have the computer guess:\n\n");
Xprintf (" You will be asked whether you want the computer to double\n");
Xprintf (" your scoring of its guesses. If you desire this, each \n");
Xprintf (" time you give the computer a score, it score the guess\n");
Xprintf (" itself. If the two scores are different, it will inform\n");
Xprintf (" you of your mistake, and the score it generates will re-\n");
Xprintf (" place the one you gave. If you wish your scores checked,\n");
Xprintf (" you must enter the correct code, so that the computer has\n");
Xprintf (" data to check the scores you give. Don't worry, I haven't\n");
Xprintf (" designed this game to cheat. The code you enter will be\n");
Xprintf (" ignored when the computer makes its guess.\n\n");
Xprintf (" If you do not want double checking, you can refuse it.\n");
Xprintf (" In this case, any valid score you give will be accepted.\n");
Xprintf (" The default value for checking is 'yes'.\n");
Xprintf (" The computer will now make its first guess. You will be\n");
Xprintf (" asked for the number of black pegs the guess receives (for\n");
Xprintf (" each instance of the right color in the right position),\n");
Xprintf (" up to four. If you do not give a valid answer (0-4), you\n");
Xprintf (" will be queried until you do.\n");
Xrest();
Xprintf ("\n\n");
Xprintf (" If you give three or four black pegs, it is not possible\n");
Xprintf (" for any white pegs to be given. Otherwise, you will be\n");
Xprintf (" asked for the number of white pegs until you give a valid\n");
Xprintf (" valid answer, zero to (4 - blacks).\n\n");
Xprintf (" At this point, if you requested it, your scoring will be\n");
Xprintf (" checked by the computer.\n\n");
Xprintf (" The computer will continue to guess in this manner, making\n");
Xprintf (" certain that each guess is consistent with all previous\n");
Xprintf (" information, until it receives a score of four black pegs.\n");
Xprintf (" This will generally take from four to seven guesses, but\n");
Xprintf (" the machine has been known to get lucky, and break the \n");
Xprintf (" code on the second guess. If at any point the computer\n");
Xprintf (" has exhausted all possible guesses, and found none to be\n");
Xprintf (" consistent with the information you have given, it will \n");
Xprintf (" report this error and end the game.\n\n");
Xprintf (" Good luck, and enjoy Master Mind!\n\n");
Xrest();
Xsystem("clear");
X}
X
Xconsistent()
X{
X extern int player, cons;
X extern int cur;
X extern struct guess dummy[];
X extern struct guess guesses[];
X
X int x, y, z;
X
X for (z = 0; z < cur; z++)
X {
X dummy[z].blacks = dummy[z].whites = 0;
X for (x = 0; x < 4; x++)
X guesses[cur].pegs[x].used = dummy[z].pegs[x].used = NONE;
X for (x = 0; x < 4; x++)
X if (guesses[cur].pegs[x].color == dummy[z].pegs[x].color)
X {
X dummy[z].pegs[x].used = guesses[cur].pegs[x].used = BLACK;
X dummy[z].blacks++;
X }
X if (dummy[z].blacks != 4)
X {
X for (x = 0; x < 4; x++)
X for (y = 0; y < 4; y++)
X if (guesses[cur].pegs[x].color == dummy[z].pegs[y].color &&
X !dummy[z].pegs[y].used && !guesses[cur].pegs[x].used)
X {
X dummy[z].pegs[y].used = guesses[cur].pegs[x].used =
X WHITE;
X dummy[z].whites++;
X }
X }
X }
X cons = TRUE;
X for (z = 0; z < cur; z++)
X {
X if (dummy[z].blacks != guesses[z].blacks ||
X dummy[z].whites != guesses[z].whites)
X {
X if (cons)
X {
X cons = FALSE;
X if (player)
X printf("Inconsistent guess. If this were correct:\n");
X }
X if (player)
X {
X printf(" guess #%d would have gotten ",z + 1);
X printf("%d black and %d white.\n",dummy[z].blacks,dummy[z].whites);
X }
X }
X }
X if (cons && player)
X printf("This guess is consistent with all previous clues.\n");
X}
X
Xrefresh()
X{
X extern struct guess guesses[];
X int x, y;
X
X system("clear");
X if (!player && check)
X {
X printf("Your correct sequence: ");
X for (y = 0; y < 4; y++)
X printf("%-8s",col[dig[code.pegs[y].color]]);
X printf("\n\n");
X }
X for (x = 0; x < cur; x++)
X {
X printf("%2d. ",x + 1);
X for (y = 0; y < 4; y++)
X printf("%-8s",col[dig[guesses[x].pegs[y].color]]);
X for (y = 0; y < guesses[x].blacks; y++)
X printf("b");
X for (y = 0; y < guesses[x].whites; y++)
X printf("w");
X printf("\n");
X }
X printf("\n");
X}
X
Xplayer_plays()
X{
X extern int game_won;
X extern struct guess code;
X extern struct guess guesses[];
X extern int dig[];
X extern int cur;
X
X char inst, action;
X int coach, quit;
X int t, w, x, y, z;
X
X coach = quit = FALSE;
X printf("Do you want coaching, y/n [default is n] -> ");
X if ((inst = getchar()) != '\n')
X while (getchar() != '\n');
X if (inst == 'y' || inst == 'Y')
X coach = TRUE;
X printf("\nChoosing a code for you to guess.\n");
X t = rand() % 3 + 2;
X sleep(t);
X make_code(&code);
X for (cur = 0; cur < 18 && !game_won;)
X {
X if (cur)
X {
X printf("guess, refresh, hint, or quit [default is guess] -> ");
X if ((action = getchar()) != '\n')
X while (getchar() != '\n');
X }
X else
X action = 'g';
X switch (action)
X {
X case 'q':
X case 'Q':
X cur = 18;
X quit = TRUE;
X break;
X case 'r':
X case 'R':
X refresh();
X break;
X case 'h':
X case 'H':
X printf("\n");
X z = 0;
X while (z < 1 || z > cur)
X {
X z = 0;
X printf("Enter the guess you need the hint for -> ");
X while((t = getchar()) != '\n')
X z = z * 10 + t - '0';
X }
X w = 0;
X while (w < 1 || w > 4)
X {
X w = 0;
X printf("Which peg of guess #%d -> ",z);
X while((t = getchar()) != '\n')
X w = w * 10 + t - '0';
X }
X printf("In guess #%d, peg #%d received ",z,w);
X if (guesses[z - 1].pegs[w - 1].used == BLACK)
X printf("a black peg.\n");
X if (guesses[z - 1].pegs[w - 1].used == WHITE)
X printf("a white peg.\n");
X if (guesses[z - 1].pegs[w - 1].used == NONE)
X printf("no peg.\n");
X printf("\n");
X break;
X default:
X get_code(&guesses[cur]);
X set_dummy();
X if (coach && cur)
X consistent();
X score();
X cur++;
X break;
X }
X }
X if (game_won)
X {
X printf(" Congratulations, human! You broke the code in %d",cur);
X if (cur != 1)
X printf(" guesses.\n");
X else
X printf(" guess. What luck!\n");
X }
X else if (!quit)
X {
X printf(" Sorry. You've run out of guesses.\n");
X printf(" The correct code was: %-8s %-8s %-8s %-8s\n",
X col[dig[code.pegs[0].color]],
X col[dig[code.pegs[1].color]],
X col[dig[code.pegs[2].color]],
X col[dig[code.pegs[3].color]]);
X }
X else
X printf("Was that too tough for you? I'll be nicer next time.\n");
X}
X
Xtell_guess()
X{
X extern int cur;
X extern struct guess guesses[];
X extern int dig[];
X
X if (!check)
X printf("\n");
X if (cur < 10)
X printf(" ");
X printf(" Guess #%d: %-8s %-8s %-8s %-8s\n\n",cur + 1,
X col[dig[guesses[cur].pegs[0].color]],
X col[dig[guesses[cur].pegs[1].color]],
X col[dig[guesses[cur].pegs[2].color]],
X col[dig[guesses[cur].pegs[3].color]]);
X}
X
Xget_score()
X{
X extern struct guess guesses[];
X extern int cur;
X extern int check;
X
X int t, w, x;
X
X w = -1;
X while (w < 0 || w > 4)
X {
X w = 0;
X printf("How many black pegs do I get -> ");
X while((t = getchar()) != '\n')
X w = w * 10 + t - '0';
X }
X if (w == 4 || w == 3)
X x = 0;
X else
X x = -1;
X while (x < 0 || x > 4 - w)
X {
X x = 0;
X printf("How many white pegs do I get -> ");
X while((t = getchar()) != '\n')
X x = x * 10 + t - '0';
X }
X if (check)
X {
X score();
X if (guesses[cur].blacks != w || guesses[cur].whites != x)
X {
X printf("You seem to have made a mistake. ");
X printf("My correct score is %d black",guesses[cur].blacks);
X if (guesses[cur].blacks != 1)
X printf("s");
X printf(" and %d white",guesses[cur].whites);
X if (guesses[cur].whites != 1)
X printf("s");
X printf(".\n\n");
X }
X else
X printf("\n");
X }
X else
X {
X guesses[cur].blacks = w;
X guesses[cur].whites = x;
X if (guesses[cur].blacks == 4)
X game_won = TRUE;
X }
X}
X
Xmachine_plays()
X{
X extern struct guess code;
X extern struct guess guesses[];
X extern int cur;
X extern int check, game_won;
X
X int w, x, y, z;
X int randomizing = TRUE;
X int quit = FALSE;
X int refreshed;
X char ans;
X
X check = TRUE;
X printf("Do you want me to double check you, y/n [default is y] -> ");
X if ((ans = getchar()) != '\n')
X while (getchar() != '\n');
X if (ans == 'n' || ans == 'N')
X check = FALSE;
X if (check)
X get_code(&code);
X cur = 0;
X make_code(&guesses[cur]);
X set_dummy();
X tell_guess();
X get_score();
X for (++cur; cur < 6 && !game_won && randomizing && !quit;)
X {
X refreshed = FALSE;
X if (!(cur % 2) && cur > 3)
X {
X refresh();
X refreshed = TRUE;
X }
X x = 0;
X cons = FALSE;
X while (!cons && x < 1200)
X {
X x++;
X make_code(&guesses[cur]);
X consistent();
X }
X if (cons)
X {
X set_dummy();
X tell_guess();
X get_score();
X cur++;
X }
X else
X randomizing = FALSE;
X }
X if (!game_won)
X for (cur; cur < 18 && !game_won && !quit; cur++)
X {
X if (!(cur % 2) && cur > 3 && !refreshed)
X refresh();
X cons = FALSE;
X for (w = 0; w < 6 && !cons; w++)
X for (x = 0; x < 6 && !cons; x++)
X for (y = 0; y < 6 && !cons; y++)
X for (z = 0; z < 6 && !cons; z++)
X {
X guesses[cur].pegs[0].color = w;
X guesses[cur].pegs[1].color = x;
X guesses[cur].pegs[2].color = y;
X guesses[cur].pegs[3].color = z;
X guesses[cur].blacks = guesses[cur].whites = 0;
X consistent();
X }
X if (cons)
X {
X set_dummy();
X tell_guess();
X get_score();
X }
X else
X {
X printf("No guess is consistent. You must have cheated!\n");
X printf("Can't recover from this. Goodbye!\n");
X quit = TRUE;
X }
X }
X if (game_won)
X {
X printf("I broke your code in %d ",cur);
X if (cur != 1)
X printf("guesses.\n");
X else
X printf("guess. Machines can get lucky, too!\n");
X }
X else if (!quit)
X printf("I didn't break your code. You win this time!\n");
X}
X
Xmain()
X{
X extern int cur, game_won, player;
X extern int dig[];
X extern struct guess code;
X extern struct guess guesses[];
X
X char more, inst;
X int play_game = TRUE;
X int z;
X
X system("clear");
X z=time();
X srand(z);
X printf("Would you like instructions, y/n [default is n] -> ");
X if ((inst = getchar()) != '\n')
X while (getchar() != '\n');
X if (inst == 'y' || inst == 'Y')
X print_instructions();
X while (play_game)
X {
X player = TRUE;
X game_won = FALSE;
X printf("Do you want to guess, or make the code,");
X printf(" g/m [default is g] -> ");
X if ((inst = getchar()) != '\n')
X while (getchar() != '\n');
X if (inst == 'm' || inst == 'M')
X player = FALSE;
X setcolors();
X if (player)
X player_plays();
X else
X machine_plays();
X printf("\nWould you like to play again, y/n [default is n] -> ");
X if ((more = getchar()) != '\n')
X while (getchar() != '\n');
X if (more != 'y' && more != 'Y')
X play_game = FALSE;
X system("clear");
X }
X}
END_OF_mastrm.c
if test 18986 -ne `wc -c <mastrm.c`; then
echo shar: \"mastrm.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0