Path: csiph.com!eternal-september.org!feeder.eternal-september.org!aioe.org!.POSTED!not-for-mail From: "Rod Pemberton" Newsgroups: alt.os.development Subject: Re: cows and bulls game, was [Re: C parser ramblings, language design, etc] Date: Sun, 27 Dec 2015 21:19:09 -0500 Organization: Aioe.org NNTP Server Lines: 255 Message-ID: References: NNTP-Posting-Host: n4wpt9zq8xR26Ttf9mo2BA.user.speranza.aioe.org Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit X-Complaints-To: abuse@aioe.org User-Agent: Opera Mail/12.16 (Linux) X-Notice: Filtered by postfilter v. 0.8.2 Xref: csiph.com alt.os.development:9055 On Sun, 27 Dec 2015 08:51:24 -0500, James Harris wrote: > It reminds me, however, that when I was at school I tried to come up > with an algorithm for marking a game that some people call bulls-and-cows. Since you're reminiscing, here is a "bulls-and-cows" test harness in C I just whipped up after dinner. You should be able to modify it to add in an algorithm of your choice rather easily. You need to activate a define for either TEST or USER or RAND. USER is set. I don't have a preprocessor check for none of them set. TEST uses hardcoded values. RAND generates both the guess and secret. USER lets the user play. I left in most standard C functions for you, except memset() which I implemented as loops, although it's missing niceties like EXIT_SUCCESS, etc. I likely would've eliminated isdigit() otherwise. It'll warn on some unused variables depending on which define you choose. Ignore this. Although one can implement a division at the end using either floating point or integer arithmetic, I didn't bother. Some of the code may look rudimentary, e.g., condition to break exit while(1) loops, or aligned braces, but I assure you, that I can just as easily code it the other way around. If you want, you can rework cows() to call bulls(). Redundant. Or, rework bulls() to pass scs instead of using a file scope var. /* Bulls and Cows - test harness .RP */ /* Rod Pemberton - Dec 27 2015 */ #include #include /* isdigit */ #include /* rand srand */ #include /* time */ #define SC 4 #define DG 10 unsigned char secret[SC+1],guess[SC+1]; unsigned int sec_tab[DG],gue_tab[DG]; int scs; #if 0 #define TEST #endif #if 1 #define USER #endif #if 0 #define RAND #endif #if !defined(TEST) && !defined(USER) && !defined(RAND) #error "must define one" #endif #if defined(TEST) && defined(USER) #error "two defined" #endif #if defined(USER) && defined(RAND) #error "two defined" #endif #if defined(TEST) && defined(RAND) #error "two defined" #endif #ifdef TEST #define G1 #define S1 #endif #ifdef RAND #define G2 #define S2 #endif #ifdef USER #define G3 #define S2 #endif void do_secret() { int i,r; #ifdef S1 secret[0]='4'; secret[1]='0'; secret[2]='5'; secret[3]='1'; printf("Secret is %s.\n",secret); #endif #ifdef S2 for(i=0;i>3)%DG; if(!sec_tab[r]) { secret[i]=r+'0'; sec_tab[r]=1; i++; } if(i==SC) break; } #if 0 printf("Secret is %s.\n",secret); #endif #endif } void do_guess() { unsigned char c; int i,r; printf("Enter guess.\n"); #ifdef G1 guess[0]='1'; guess[1]='0'; guess[2]='3'; guess[3]='4'; #endif #ifdef G2 for(i=0;i>3)%DG; if(!gue_tab[r]) { guess[i]=r+'0'; gue_tab[r]=1; i++; } if(i==SC) break; } #endif #ifdef G3 i=0; while(1) { c=getchar(); if(isdigit((int)c)) { guess[i]=c; i++; } if(i==SC) break; } #endif printf("Guess is %s.\n",guess); } void bulls(void) { int i,sts; sts=0; for(i=0;i