יום שני, 13 בפברואר 2017

שפת C - משחק בול פגיעה

עוד תרגילים וחזרות על חומר ישן

ננסה ליצור את המשחק "בול פגיעה" (Bulls and Cows)

למי שלא מכיר כך עובד המשחק:
*המחשב בוחר רצף של 4 ספרות שונות בסדר אקראי.
*השחקו מנסה לנחש מה הספרות (בסדר הנכון)

אחרי ה"קלט" מהשחקן, המחשב מדפיס:
"בול"    - עבור כל ספרה שקיימת ברצף וגם נמצאת באותו מיקום.
"פגיעה" - עבור כל ספרה שקיימת ברצף אבל לא  נמצאת במיקום הנכון.

~משחק חשיבה נחמד ומומלץ לכולם~
ראו גם: וויקיפדיה





לדוגמה:
נניח שהמחשב בחר באופן אקראי את המספר 1256
ננחש 3489
המחשב ידפיס:
 -טעית, נסה שוב!

ננחש 1234
המחשב ידפיס:
 -בול
 -בול

ננחש 5678
המחשב ידפיס:
 -פגיעה
 -פגיעה

ננחש 2156
המחשב ידפיס:
 -בול
 -בול
 -פגיעה
 -פגיעה

ננחש 1265
המחשב ידפיס:
 -בול
 -בול
 -פגיעה
 -פגיעה

ננחש 1256
המחשב ידפיס:
 -ניצחת!


*בנוסף המחשב יפעיל מונה לכמות הניסיונות עד להצלחה.

*המשחק מתנהל בין האדם לבין המספר האקראי של המחשב. אם תרצו תוכלו לשחק עם חברים באופן הבא:
-אחד מכם יקליד את הניחוש הראשון למחשב
-אחר כך החבר השני יקליד ניחוש
-הראשון שגילה את הרצף של המחשב - ניצח!
(כל אחד יכול לראות את כל הניסיונות שהיו עד עכשיו - של שני הצדדים. כך לכולם יש הזדמנות שווה. אפשר גם יותר משני שחקנים)



.....................................................

נעשה שימוש בפונקציה rand.
בתוכנית שלנו הרצף של המחשב יכול להכיל רק 4 ספרות.
במקום הראשון לא יכול להיות 0.


התוכנית שנביא כאן היא תוכנית מורחבת
יש לה 3 תכונות נוספות:
1. בדיקה שבקלט הספרות בתחום הנכון.
2. אפשרות "ידנית" - אדם יבחר את הרצף שצריך לנחש ואדם אחר ינחש (ולא בחירה אקראית של המחשב)
3. אפשרות להגדיל את רמת הקושי (שיהיו יותר מ4 ספרות ברצף. עד 10 ספרות (יותר מזה הספרות יחזרו יותר מפעם אחת))



#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#define M 10  // מספר הספרות המקסימלי במערך
enum TypeFlag {success,faild};
 
void main(){
 char ARR[M+1],ABB[M+1],annoying,p;  // מאכסן את המערך של המחשב
 int i, q, Bool, Pgia,count=0,N=4;
 enum TypeFlag flag;
 
 printf("The game is called 'Bool Pgia'\n'Pgia' means: the sum of the digits that
               exist, BUT NOT in the same position.\n'Bool Pgia' means: the sum of the digits
               that exist AND in the same position.\n");
 printf("       -The first digit can't be 0-\n\n
               Press M for Manual Game, R for Rndom Game: ");
 flushall();
 
 annoying = getchar();
 while(annoying != 'm'&& annoying != 'M' && annoying != 'r' && annoying != 'R'){
  printf("Please enter a legal input: ");
  flushall();
  annoying = getchar();
 }
 
 printf("0 mean 4 digits, Add more digits if you wont (up to %d): ",M-4);
 while(1){
 scanf("%d",&i);
 if (i >= -1 && i <= M-4) break;
 printf("Please enter number between -1 and %d:  ",M-4);
 }
 N+=i;
 
 if(annoying == 'm' || annoying == 'M'){ // ידני
  printf("Enter %d numbers and press ENTER: ",N);
  scanf ("%s",ARR); // להוסיף N למגבלה   ///
 
  do// בדיקה שהקלט הידני של הרצף תקין
   flag = success;
 
   i = strlen(ARR);
    
 
   if (i<N|| i>N) flag = faild;  // בדיקה שהקלט הידני באורך הנכון
 
   if(ARR[0]=='0') flag = faild;   // הראשון אסור שיהיה 0
   for(i=0;i<N && flag == success;i++){
   
    if(ARR[i]>'9'|| ARR[i]<'0') {flag = faildbreak; };
    for(q=i+1;q<N;q++){
     if(ARR[i]==ARR[q]) flag = faild; 
    }
   }
   if(flag == faild){
    printf("Please enter legal numbers: ");
    flushall();  // לפעמים נצטרך
    gets(ARR);
   }
   else break;
  } while(1);
 } // עד כאן קיבלנו רצף תקין בצורה ידנית
 
 else{  // כאן המחשב ימלא את הרצף בצורה אקראית בספרות 1-9 שלא חוזרות על עצמן
  srand(time(0));
  ARR[0] = (rand()%9)+1+'0'// עבור המקום הראשון.  לא יכול להיות 0
 
  for (i=1;i<N;i++){
   do{   // רק בודק שאין את המספר הרנדומלי בשום מקום במערך
    p=(rand()%10)+'0';
 
    for(q=i;q>0 && ARR[q-1]!=p;q--);
   } while(q);
   ARR[i] = p;
  }
  ARR[N] = NULL;
 }
 
 while(1){  // מכאן מתחילים הניחושים
  count++;
  Bool=0;
  Pgia=0;
  printf("\n%d. Guess the %d numbers:  ",count,N);
  flushall();
  gets(ABB);
 
  //  :נבדוק שהניחוש חוקי
  do{
   flag = success;
 
   i = strlen(ABB);
   if (i<N|| i>N) flag = faild//  קטן או גדול ממספר הספרות הרצוי
 
   if(ABB[0]=='0') flag = faild;
   for(i=0;i<N && flag == success;i++){
    if(ABB[i]>'9'|| ABB[i]<'0') {flag = faild;  break; }; // התווים בתחום הרצוי
    for(q=i+1;q<N;q++){  // לא חוזרים על עצמם
     if(ABB[i]==ABB[q]) flag = faild;
    }
   }
 
   if(flag == faild){
    printf("Please enter legal numbers: ");
    flushall();  // לפעמים לא נצטרך
    gets(ABB);
   }
   else break;
  } while(1);
  //  עד כאן הניחוש תקין
 
 
  flag = success;
  for (i=0;i<N;i++){
   for(q=0;q<N;q++){
    if (ABB[i]==ARR[q]&&q!=i) { Pgia++; break;}
    if (ABB[i]==ARR[q]&&q==i) { Bool++; break;}
   }
   if(q==N || q != i) flag = faild// אם הגענו לסוף המערך בלי התאמה או אם ההתאמה היא לא באותו מקום
  }
 
  if (flag == success){printf("\nYou Won The Match!\n"); break;}
  for(i=0;i<Pgia;i++) printf("Pgia!\n");
  for(i=0;i<Bool;i++) printf("Bool Pgia!\n");
 
  if (Bool==0 && Pgia == 0) printf("You wrong, try again...\n");
 }
 scanf("%s",ARR);
}






תיהנו!


אין תגובות:

הוסף רשומת תגובה