Advertisement
Yonka2019

Untitled

Jan 18th, 2021 (edited)
208
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.54 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdbool.h>
  4. #include <math.h>
  5. #include <time.h>
  6. #include <conio.h>
  7. #define ROUNDS_EASY 20
  8. #define ROUNDS_MODERATE 15
  9. #define ROUNDS_HARD 10
  10.  
  11. enum Difficulty
  12. {
  13.     Easy = 1,
  14.         Moderate,
  15.         Hard,
  16.         Crazy
  17. };
  18. void printInfo();
  19. int selectDifficulty();
  20. int getInput(int guessesLeft);
  21. bool containsDigit(int number, int digit);
  22. bool checkValid(int number);
  23. bool hasDistinctDigits(int number);
  24. int guessInfo(int inputNumber, int genNumber, char ret);
  25.  
  26. //global variables
  27.  
  28. bool isCrazy = false;
  29.  
  30. int main()
  31. {
  32.     srand(time(NULL));
  33.  
  34.     int inputNumber = 0, genNumber = 0, miss = 0, hit = 0, rounds = 0, guessesLeft = 0;
  35.     char replayInput = ' ';
  36.  
  37.     while (1)
  38.     {
  39.         printInfo();
  40.  
  41.         rounds = selectDifficulty();
  42.         guessesLeft = rounds;
  43.  
  44.         genNumber = generateNumber();
  45.         printf("[INFO] Generated Number: %d\n", genNumber);
  46.  
  47.         while (guessesLeft > 0)
  48.         {
  49.             inputNumber = getInput(guessesLeft);
  50.             guessesLeft--;
  51.  
  52.             hit = guessInfo(inputNumber, genNumber, 'h');
  53.             miss = guessInfo(inputNumber, genNumber, 'm');
  54.  
  55.             if (hit == 4)
  56.             {
  57.                 printf("   4 HITS YOU WON!!!\n\n"
  58.                     "It took you only %d guesses, you are a professional code breaker!\n", rounds - guessesLeft);
  59.                 guessesLeft = -1;
  60.             }
  61.             else
  62.             {
  63.                 printf("You got    %d HITS    %d MISSES.\n", hit, miss);
  64.                 if (guessesLeft == 0)
  65.                 {
  66.                     printf("\nOOOOHHHH!!! Pancratius won and bought all of Hanukkah's gifts.\n"
  67.                         "Nothing left for you...\n"
  68.                         "The secret password was %d\n", genNumber);
  69.                 }
  70.             }
  71.         }
  72.         do {    
  73.             printf("\nWould you like to play again? (y/n): ");
  74.  
  75.             replayInput = getch();
  76.             printf("%c\n", replayInput);
  77.  
  78.             if (replayInput == 'n' || replayInput == 'N')
  79.             {
  80.                 printf("\nBye Bye!\n");
  81.                 system("pause");
  82.                 return 0;
  83.             }
  84.         } while (replayInput != 'y' && replayInput != 'Y');
  85.     }
  86. }
  87. /*
  88. Returns the misses/hits according the two given numbers
  89. input: first number, seconds number, info setting
  90. output: (if<info> equals to 'h' this function will return HITS, otherwise, if<info> equals to 'm' this function will return MISSES)
  91. */
  92. int guessInfo(int inputNumber, int genNumber, char info)
  93. {
  94.     int miss = 0, hit = 0, i = 0;
  95.  
  96.     for (i = 1; i < 5; i++)
  97.     {
  98.         if (containsDigit(genNumber, digitFromNumber(inputNumber, i)))
  99.         {
  100.             if (digitFromNumber(genNumber, i) == digitFromNumber(inputNumber, i))
  101.             {
  102.                 hit++;
  103.             }
  104.             else
  105.             {
  106.                 miss++;
  107.             }
  108.         }
  109.     }
  110.     switch (info)
  111.     {
  112.         case 'm':
  113.             return miss;
  114.         case 'h':
  115.             return hit;
  116.         default:
  117.             return -1;
  118.     }
  119. }
  120. /*
  121. Checks if the given digit contains in the given number
  122. input: number and one digit
  123. output: true if the given digit contains in the given number, otherwise, false
  124. */
  125. bool containsDigit(int number, int digit)
  126. {
  127.     int curr_digit = 0;
  128.     while (number != 0)
  129.     {
  130.         curr_digit = number % 10;
  131.         if (curr_digit == digit)
  132.         {
  133.             return true;
  134.         }
  135.         number /= 10;
  136.     }
  137.  
  138.     return false;
  139. }
  140. /*
  141. Printing difficulty selection, and return the rounds number according the selection
  142. input: -
  143. output: number of rounds
  144. */
  145. int selectDifficulty()
  146. {
  147.     int diff = 0;
  148.  
  149.     printf("Please choose the game level:\n"
  150.         "1 - Easy (20 rounds)\n"
  151.         "2 - Moderate (15 rounds)\n"
  152.         "3 - Hard (10 rounds)\n"
  153.         "4 - Crazy (random number of rounds 5-25)\n");
  154.     do {
  155.         printf("Make a choice: ");
  156.         scanf("%d", &diff);
  157.  
  158.         switch (diff)
  159.         {
  160.             case Easy:
  161.                 return ROUNDS_EASY;
  162.  
  163.             case Moderate:
  164.                 return ROUNDS_MODERATE;
  165.  
  166.             case Hard:
  167.                 return ROUNDS_HARD;
  168.  
  169.             case Crazy:
  170.                 isCrazy = true;
  171.                 return rand() % (25 - 5 + 1) + 5;
  172.  
  173.             default:
  174.                 diff = -1;
  175.                 break;
  176.         }
  177.     } while (diff == -1);
  178. }
  179. /*
  180. Asking for input from the user (input to guess the generated number)
  181. input: guesses left number (to print them before the input)
  182. output: number which user inputed
  183. */
  184. int getInput(int guessesLeft)
  185. {
  186.     int i = 0, numInput = 0, digit = 0;
  187.     bool validNum = false;
  188.  
  189.     do {
  190.         numInput = 0;
  191.  
  192.         printf("Write your guess (only 1-6, no ENTER is needed)\n");
  193.  
  194.         if (isCrazy)
  195.         {
  196.             printf("CRAZY MODE!!!\n");
  197.         }
  198.         else
  199.         {
  200.             printf("%d guesses left\n", guessesLeft);
  201.         }
  202.  
  203.         for (i = 0; i < 4; i++)
  204.         {
  205.             digit = getch();
  206.             printf("%d", digit - '0');
  207.             numInput = combine(numInput, digit - '0');
  208.         }
  209.         printf("\n");
  210.  
  211.         validNum = checkValid(numInput);
  212.         if (!validNum)
  213.         {
  214.             printf("Only 1-6 and distinct digits are allowed, try again!\n");
  215.         }
  216.     } while (!validNum);
  217.  
  218.     return numInput;
  219. }
  220. /*
  221. Returns selected digit from the given number
  222. input: number and digitNumber (place of digit, for example: 5314 - (digitNumber 3 = digit 1))
  223. 5 3 1 4 - Digits
  224. 1 2 3 4 - Digits Number (place)
  225. */
  226. int digitFromNumber(int number, int digitNum)
  227. {
  228.     int i = 0;
  229.  
  230.     for (i = 0; i < 4 - digitNum; i++)
  231.     {
  232.         number /= 10;
  233.     }
  234.     return number % 10;
  235. }
  236. /*
  237. Checks if in the given number each digit between 1-6 and doesn't repeating her self
  238. input: number
  239. output: true if all is ok, false, if something wrong
  240. */
  241. bool checkValid(int number)
  242. {
  243.     bool rangeOK = false;
  244.     bool distinctDigits = hasDistinctDigits(number);
  245.  
  246.     //extract number into digits
  247.     int digit1 = digitFromNumber(number, 1);
  248.     int digit2 = digitFromNumber(number, 2);
  249.     int digit3 = digitFromNumber(number, 3);
  250.     int digit4 = digitFromNumber(number, 4);
  251.  
  252.     //check if one of the digits doesn't between the allowed range (1-6)
  253.     rangeOK = ((digit1 >= 1 && digit1 <= 6) && (digit2 >= 1 && digit2 <= 6) && (digit3 >= 1 && digit3 <= 6) && (digit4 >= 1 && digit4 <= 6));
  254.  
  255.     return rangeOK && distinctDigits;
  256. }
  257. /*
  258. Checks if the digits in the given number are distinct
  259. input: number
  260. output: true if disticnt, false if not
  261. */
  262. bool hasDistinctDigits(int number)
  263. {
  264.     int numMask = 0, digitIdx = 0, curDigit = 0, digitMask = 0;
  265.     int numDigits = (int) ceil(log10(number + 1));
  266.  
  267.     for (digitIdx = 0; digitIdx < numDigits; digitIdx++)
  268.     {
  269.         curDigit = (int)(number / pow(10, digitIdx)) % 10;
  270.         digitMask = (int) pow(2, curDigit);
  271.         if ((numMask & digitMask) > 0)
  272.         {
  273.             return false;
  274.         }
  275.         numMask = numMask | digitMask;
  276.     }
  277.     return true;
  278. }
  279. /*
  280. Generates random number according the rules (each digit is between 1 -> 6, each digit must be distinct)
  281. input: -
  282. output: randomized number
  283. */
  284. int generateNumber()
  285. {
  286.     int fullNum = 0;
  287.  
  288.     do {
  289.         fullNum = combine(combine(rand() % (6 - 1 + 1) + 1, rand() % (6 - 1 + 1) + 1), combine(rand() % (6 - 1 + 1) + 1, rand() % (6 - 1 + 1) + 1));
  290.     } while (!hasDistinctDigits(fullNum));
  291.  
  292.     return fullNum;
  293. }
  294. /*
  295. Combines two numbers into one (12 &41 -> 1241)
  296. input: two numbers
  297. output: these two numbers together (as one number)
  298. */
  299. int combine(int a, int b)
  300. {
  301.     int times = 1;
  302.  
  303.     while (times <= b)
  304.     {
  305.         times *= 10;
  306.     }
  307.     return a *times + b;
  308. }
  309. /*
  310. Prints program info, such as rules and tutorial
  311. input: -
  312. output: -
  313. */
  314. void printInfo()
  315. {
  316.     printf("Welcome to \"MAGSHIMIM CODE-BREAKER\"!!!\n\n"
  317.         "A secret password was chosen to protect the credit card of Pancratius,\n"
  318.         "the descendant of Antiochus.\n"
  319.         "Your mission is to stop Pancratius by revealing his secret password.\n\n"
  320.         "The rules are as follows:\n"
  321.         "1. In each round you try to guess the secret password (4 distinct digits)\n"
  322.         "2. After every guess you'll receive two hints about the password\n"
  323.         "   HITS:   The number of digits in your guess which were exactly right.\n"
  324.         "   MISSES: The number of digits in your guess which belongs to\n"
  325.         "           the password but were miss-placed.\n"
  326.         "3. If you'll fail to guess the password after a certain number of rounds\n"
  327.         "   Pancratius will buy all the gifts for Hanukkah!!!\n\n");
  328. }
  329.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement