/* -*-c,save-*- */ /* * stone.c - stone game * Robert Heller. Created: Sun Mar 9, 1986 14:09:25.84 * Last Mod: * * (c) Copyright 1986 by Robert Heller * All Rights Reserved * * */ #include #undef max #include "phrase.h" #define LOCAL static /* #define DEBUG /* debugging */ #ifdef DEBUG #define LOCAL /* static */ #endif int *malloc(); #define flatindx(NS,P) ((NS*2)+P) main() { register int status; register int k,him,me,ns,maxa,*a; int max,nstones,p,temp,*sda(); static char messbuff[1024]; static char qbuff[256]; que_init(); if (quest("Do you want the rules/(no)0|(NO)0|(yes)1|(YES)1") == 1) instr(); a = NULL; srand(gettime()); newg: quest("Number of stones (odd)/0(1...1000)",&nstones); if ((nstones & 1) == 0) goto newg; quest("Winner's Parity (0...1)/0(0...1)",&p); quest("Maximum Take/0(2...1000)",&max); if (a != NULL) free(a); a = sda(nstones,p,max); oldg: ns = nstones; maxa = max; him = 0; me = 0; while (ns > 0) { printf("There are %d stones in the pile.\n",ns); if (maxa > ns) maxa = ns; sprintf(qbuff,"How many do you want/0(1...%d)",maxa); quest(qbuff,&temp); k = temp; ns -= k; him += k; if (ns == 0) break; k = a[flatindx(ns,(me & 1))]; if (k <= 0) k = 1; ns -= k; me += k; letmesee(messbuff); prblk(messbuff); if (k == 1) printf("I think I'll take just one.\n"); else printf("I think I'll take %d stones.\n",k); } printf("You have %d stones and I have %d stones.\n",him,me); if ((him & 1) != p) { insult(messbuff); printf("That means I win!\n"); prblk(messbuff); } else { praise(messbuff); printf("That means you win!\n"); prblk(messbuff); } if (quest("Would you like to play again/(no)1|(NO)1|(yes)0|(YES)0") == 1) exit(1); if (quest("Would you like to change the game/(yes)0|(YES)0|(no)1|(NO)1")== 0) goto newg; else goto oldg; } LOCAL int *sda(nstones,parity,max) register int nstones,parity,max; { register int *a; register int t,j,p,opar,i; a = malloc((nstones+1)*2*sizeof(int)); fillint(a,(nstones+1)*2,-1); a[flatindx(0,parity)] = 9999; for (i=1;i<=nstones;i++) { for (p=0;p<2;p++) { opar = (nstones - i - p) & 1; for (j=1;j<=max;j++) { t = i-j; t = a[flatindx(t,opar)]; if (t == -1) { a[flatindx(i,p)] = j; break; } } } } return(a); } LOCAL fillint(a,num,fill) register int *a,num,fill; { while (num-- > 0) *a++ = fill; } LOCAL instr() { printf("\n Stone\n\n"); printf(" To play this game you need to remove stones from a pile\n"); printf("of stones. When all of the stones are taken the game is over.\n"); printf("The winner is the person with either an odd or even number of\n"); printf("stones wins. The starting number of stones in the pile, the\n"); printf("maximum number that can be taken at a time and the winning\n"); printf("`parity' (odd=1, even=0) can all be set for each game.\n\n"); } LOCAL prblk(s) register char *s; { register int len; len = 0; while (*s != '\0') { if (*s <= ' ' && len > 60) { putchar('\n'); while (*s > '\0' && *s <= ' ') s++; len = 0; } if (*s != '\0') { putchar(*s); len++; s++; } } if (len > 0) putchar('\n'); }