home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / SIMTEL / CPMUG / CPMUG048.ARK / MM.C < prev    next >
C/C++ Source or Header  |  1984-04-29  |  5KB  |  181 lines

  1. /*
  2.    Mastermind game, written by:    Stephen A. Ward,
  3.                 January, 1980
  4.  
  5.    Modified for BDS C by:    Leor Zolman,
  6.                 February, 1980
  7.  
  8.  
  9.    Usage:  mm [ -b ] [ -k ] [ -c# ] [ -p# ]
  10.  
  11.    where:  -b  tells # of possible solutions before each guess
  12.        -c# sets number of different characters (e.g., "-c4" means A-D)
  13.         (defaults to 6)
  14.        -p# sets number of positions in solution string
  15.         (defaults to 4)
  16.        -k  disables kibitzing (enabled by default.). 
  17.         
  18.     Thus, for example, the invokation
  19.        mm -c10 -p3
  20.     would simulate the game of "Bagels", where the layout is ten different
  21.     characters in three positions. I don't think "Bagels" allows repetitions,
  22.     though, so it isn't QUITE the same...
  23.  
  24. */
  25.  
  26. #define    NPEGS    10        /* Max NPeg        */
  27. #define    MCOLORS    26        /* Max NColors        */
  28. #define NHIST 100
  29.  
  30. char    Secret[NPEGS+2];    /* was CHAR */
  31. char    History[NHIST*NPEGS];    /* was CHAR */
  32. int    Jots[NHIST];
  33. int    guesses;
  34. int    NColors,        /* Number of colors    */
  35.     NPeg;            /* Number of pegs    */
  36.  
  37. char    KFlag,            /* Kibitz flag        */
  38.     BFlag;        /* Debug flag        */
  39.  
  40.  
  41.  
  42. main(argc, argv)
  43.  char **argv;
  44.  {
  45.     register int i,j;
  46.     int ngames,ntries;
  47.     ngames = ntries = 0;
  48.     char *trial, *arg;
  49.     NColors = 6;        /* Number of colors    */
  50.     NPeg = 4;        /* Number of pegs    */
  51.     KFlag = 1;        /* Kibitz flag        */
  52.     BFlag = 0;        /* Debug flag        */
  53.  
  54.     for (i=1; i<argc; i++)
  55.      { if (*(arg = argv[i]) == '-') switch (*++arg) {
  56.         case 'B':    BFlag++; continue;
  57.         case 'K':    KFlag = !KFlag; continue;
  58.         case 'C':    NColors = atoi(++arg);
  59.                 if (NColors > MCOLORS) NColors = MCOLORS;
  60.                 continue;
  61.         case 'P':    NPeg = atoi(++arg);
  62.                 if (NPeg > NPEGS) NPeg = NPEGS;
  63.                 continue;
  64.         default:    printf("Illegal option %s\n",
  65.                     argv[i]); exit(-1); }
  66.        else
  67.         { printf("Usage: mm [ -b ] [ -k ] [ -c# ] [ -p# ]\n");
  68.           exit(-1); }}
  69.  
  70.     printf("Mastermind game:\n");
  71.     printf("  I have a secret string of %d letters ",NPeg);
  72.     printf("between A and %c.\n", 'A' + NColors - 1);
  73.     printf("  Object: find it in as few guesses as possible.\n");
  74.     printf("  For each guess, I will tell you how many\n");
  75.     printf("    Hits (right letter in the right place) and\n");
  76.     printf("    Misses (right letter in the wrong place)\n");    
  77.     printf("  you had for that guess.\n");
  78.     printf("  Note: letters may appear more than once in my strings.\n");
  79.  
  80.     srand1("\nType any character to begin: ");
  81.     getchar();
  82.  
  83. Game:
  84.     for (i=0; i<NPeg; i++) Secret[i] = rand() % NColors;
  85.     printf("\n\nNew game!\n");
  86.     for (guesses=0;;guesses++)
  87.      { if (BFlag)
  88.          printf("\n   (%d possible secret symbols)\n", Check());
  89.        else if (KFlag && guesses && Check() == 1)
  90.          printf("\nYou should be able to figure it out now!\n");
  91.        if (!rguess("Your test symbol", trial = &History[NPeg*guesses]))
  92.         break;
  93.  
  94.        j = match(trial, Secret);
  95.        Jots[guesses] = j;
  96.  
  97.        printf( (j>>4 ? "\t\t\t%d hit" : "\t\t\tno hit"), j>>4);
  98.        if ((j>>4) - 1) putchar('s');
  99.  
  100.        printf ( (j & 0xf ? ", %d miss" : ", no miss"), j & 0xf);
  101.        if ((j & 0xf) - 1) printf("es");
  102.  
  103.        putchar('\n');
  104.  
  105.        if (j == (NPeg << 4))
  106.         { printf("You got it in %d guesses!\n", ++guesses); 
  107.           ntries += guesses;
  108.           ngames++;
  109.           i = ntries/ngames;
  110.           printf("Average for %d game%c is %1d.%1d\n",
  111.             ngames,    (ngames != 1) ? 's' : 0x80,
  112.             i , ntries*100 /ngames %100);
  113.           goto Game; }}
  114.     Secret[NPeg] = 0;
  115.     printf("My secret symbol was ");
  116.     for (i=0; i<NPeg; i++) putchar('A' + Secret[i]);
  117.     printf("\n");
  118.     goto Game;
  119.  }
  120.  
  121. int match(aa, bb)
  122.  char *aa;
  123.  char *bb;
  124.  {    register int i, score;
  125.     char j;
  126.     int temp[MCOLORS];
  127.     score = 0;
  128.     for (i=0; i<NColors; i++) temp[i] = 0;
  129.     for (i=0; i<NPeg; i++)
  130.        if ((j = aa[i]) != bb[i]) temp[j]++;
  131.     for (i=0; i<NPeg; i++)
  132.         { if ((j = bb[i]) == aa[i]) score += 16;
  133.           else if (temp[j]-- > 0) score++; }
  134.     return score; }
  135.  
  136. int incr(tt)
  137.  char *tt;
  138.  {    register int i;
  139.     i = 0;
  140.     while (i < NPeg)
  141.      { if (++tt[i] < NColors) return 1;
  142.        tt[i] = 0; i++; }
  143.     return 0; }
  144.  
  145.  
  146. int Check()
  147.  {    char tt[NPEGS];
  148.     char *hh;
  149.     register int i, j;
  150.     int count;
  151.     count = 0;
  152.     for (i=0; i<NPeg; i++) tt[i] = 0;
  153.     do {
  154.         hh = &(History[0]);
  155.         for (j=0; j<guesses; j++, hh += NPeg)
  156.             if (match(hh, tt) != Jots[j]) goto nope;
  157.         count++;
  158. nope:        i = i;
  159.        } while (incr(tt));
  160.     return count; }
  161.  
  162.  
  163. rguess(prompt, where)
  164.  char *where;
  165.  {    register int i, c;
  166. again:    printf("%s:  ", prompt);
  167.     i = strlen(gets(where));
  168.     if (i == 0) return 0;
  169.     if (i > NPeg && !isspace(where[i])) {
  170.              printf("Too many letters\n"); goto again;
  171.      }
  172.     if (i < NPeg) {  printf("Too few letters\n"); goto again; }
  173.     for (i=0; i<NPeg; i++) {
  174.       c = where[i] = toupper(where[i]) - 'A';
  175.        if (c < 0 || c >= NColors)
  176.         { printf("Bad letter -- use A thru %c\n", 'A'+NColors-1);
  177.           goto again; }
  178.      }
  179.     return 1;
  180. }
  181.