Triton Posted November 20, 2006 at 11:39 PM Report #65627 Posted November 20, 2006 at 11:39 PM /* ========================================================================== mastermind.c - a simple text-based C program to play the game "mastermind" Copyright (c) 2003 by Jeffrey S. Rosenthal (jeff@math.toronto.edu). Available from http://probability.ca/jeff/comp/ Licensed for general copying, distribution and modification according to the GNU General Public License (http://www.gnu.org/copyleft/gpl.html). Compile with "cc mastermind.c -lm -o mastermind". ========================================================================== */ #include <stdio.h> #include <sys/time.h> #include <math.h> #define WIDTH 4 #define NUMCOLS 6 #define MAXGUESSES 100 char colour[NUMCOLS+1]; int invalid; char inputline[161]; char inputstring[WIDTH+1]; int numexact; int nummissed; int i,j; int MAXNUMTRIES; double drand48(); main() { int true[WIDTH]; int guess[WIDTH]; int guessnum; char c; seedrand(); colour[0] = 'R'; colour[1] = 'G'; colour[2] = 'B'; colour[3] = 'Y'; colour[4] = 'O'; colour[5] = 'P'; MAXNUMTRIES = 1000*pow(NUMCOLS, WIDTH); printf("\n\nWelcome to mastermind, by Jeffrey Rosenthal.\n"); while (1) { printf("\nChoose [p]layer or [c]omputer to guess: "); fgets(inputline, 160, stdin); if ( (sscanf(inputline, "%c", &c)) > 0 ) { if ( (c=='p') || (c=='P') ) playerguess(); else if ( (c=='c') || (c=='C') ) computerguess(); else printf("Invalid response!\n"); } } exit(0); } playerguess() { int true[WIDTH]; int guess[WIDTH]; int guessnum = 0; /* Make up random true. */ randnorep(true); /* output(true); REMOVE THIS LATER! */ printf("\nOkay, I've made up a secret length-%d code. ", WIDTH); showcolours(); numexact=-1; while (numexact<WIDTH) { guessnum++; invalid = 1; while (invalid==1) { fflush(stdin); printf("\nYour guess #%d: ", guessnum); fgets(inputline, 160, stdin); strncpy(inputstring, inputline, WIDTH+1); convert(inputstring, guess); } printf("\nYour guess #%d is: ", guessnum); output(guess); countmatches(true, guess); printf(". numexact = %d; numwrongplace = %d.\n", numexact, nummissed); } printf("\nYou win in %d guesses!\n\n", guessnum); } computerguess() { int guesses[MAXGUESSES][WIDTH]; int guessnum = 0; int compnum; int matchhistory[MAXGUESSES][2]; int possible; int numtries; char inputchar; int giveup = 0; fflush(stdin); printf("\nMake up a string of %d colours (without repetition), and write it down\n", WIDTH); printf("somewhere [DO NOT TYPE IT IN!]. "); showcolours(); printf("Then press return [AND ONLY RETURN!]: "); fgets(inputline, 160, stdin); numexact=-1; while ( (numexact<WIDTH) && (giveup==0) ) { guessnum++; possible = numtries = 0; while (possible==0) { numtries++; if (numtries >= MAXNUMTRIES) { printf("\nHm ... I think you're lying ... I give up!\n\n"); giveup = 1; break; } randnorep(guesses[guessnum]); possible = 1; if (guessnum>1) { for(compnum=1; compnum<guessnum; compnum++) { countmatches(guesses[guessnum], guesses[compnum]); if ( (numexact!=matchhistory[compnum][0]) || (nummissed!=matchhistory[compnum][1]) ) { possible = 0; break; } } } } if (giveup==0) { printf("\nMy guess #%d is: ", guessnum); output(guesses[guessnum]); printf("\n"); numexact = nummissed = -1; while ( (numexact<0) || (numexact>WIDTH) ) { printf("Input number matching exactly (followed by return): "); fgets(inputline, 160, stdin); if ( (sscanf(inputline, "%d", &numexact) == 0) || (numexact<0) || (numexact>WIDTH) ) printf("\nInvalid response!\n\n"); } while ( (numexact<WIDTH) && ((nummissed<0) || (nummissed>WIDTH)) ) { printf("Input number matching colour but not position (followed by return): "); fgets(inputline, 160, stdin); if ( (sscanf(inputline, "%d", &nummissed) == 0) || (nummissed<0) || (nummissed>WIDTH) ) printf("\nInvalid response!\n\n"); } printf("Thank you.\n"); matchhistory[guessnum][0] = numexact; matchhistory[guessnum][1] = nummissed; } } if (giveup==0) printf("\nI win, in %d guesses!\n\n", guessnum); } convert(char string[WIDTH+1], int result[WIDTH]) { invalid = 0; for (i=0; i<WIDTH; i++) { result[i] = -1; if ( (string[i] >= '0') && (string[i] < '0'+NUMCOLS) ) { result[i] = string[i] - '0'; } else { for (j=0; j<NUMCOLS; j++) { if ( (string[i] == colour[j]) || (string[i] == colour[j] + 'a' - 'A') ) { result[i] = j; } } } if (result[i]==-1) { invalid = 1; } } if (invalid==1) { printf("\nInvalid guess! "); showcolours(); } } countmatches(int data1[WIDTH], int data2[WIDTH]) { int counts1[NUMCOLS]; int counts2[NUMCOLS]; for (i=0; i<NUMCOLS; i++) { counts1[i] = counts2[i] = 0; } for (i=0; i<WIDTH; i++) { counts1[data1[i]]++; counts2[data2[i]]++; } numexact = nummissed = 0; for (i=0; i<WIDTH; i++) { if (data1[i] == data2[i]) numexact++; } for (j=0; j<NUMCOLS; j++) { nummissed = nummissed + min(counts1[j], counts2[j]); } nummissed = nummissed - numexact; } randnorep(int result[WIDTH]) { int match; for (i=0; i<WIDTH; i++) { match = 1; while (match==1) { result[i] = ifloor( NUMCOLS * drand48() ); match = 0; if (i>0) { for (j=0; j<i; j++) { if (result[j]==result[i]) { match=1; } } } } } } output(int therow[WIDTH]) { for (i=0; i<WIDTH; i++) { printf("%c", colour[therow[i]]); } /* printf("\n"); */ } showcolours() { printf("Colours are: "); for (j=0; j<NUMCOLS; j++) printf("%c ", colour[j]); printf("\n"); } int min(int aa, int bb) { if (aa<bb) return(aa); return(bb); } /* IFLOOR */ ifloor(double x) /* returns floor(x) as an integer */ { return((int)floor(x)); } /* SEEDRAND: SEED RANDOM NUMBER GENERATOR. */ seedrand() { int i, seed; struct timeval tmptv; gettimeofday (&tmptv, (struct timezone *)NULL); /* seed = (int) (tmptv.tv_usec - 1000000 * (int) ( ((double)tmptv.tv_usec) / 1000000.0 ) ); */ seed = (int) tmptv.tv_usec; srand48(seed); (void)drand48(); /* Spin it once. */ return(0); } Download: link. <3 life
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now