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