Advertisement
Ihmemies

Untitled

Sep 30th, 2022
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.36 KB | Source Code | 0 0
  1. main.cpp
  2.  
  3. /*
  4.  * COMP.CS.110 Ohjelmointi 2
  5.  * Osio 4, projekti: Mastermind
  6.  *
  7.  * Ohjelman kuvaus:
  8.  *   Ohjelma toteuttaa Mastermind-pelin. Pelissä annetaan tai arvotaan
  9.  * ensin salainen neljän värin sarja. Sama väri voi esiintyä sarjassa
  10.  * useita kertoja, mutta mikään neljästä positiosta ei voi olla tyhjä.
  11.  * Käyttäjä yrittää arvata, mitkä värit esiintyvät sarjassa ja missä
  12.  * järjestyksessä. Tätä varten käyttäjä antaa oman neljän värin sarjansa,
  13.  * ja ohjelma ilmoittaa, kuinka monta väriarvausta meni täysin oikein
  14.  * (oikea väri oikeassa positiossa) sekä kuinka monta arvausta meni
  15.  * pelkästään värin osalta oikein (oikea väri väärässä positiossa).
  16.  * Tämän jälkeen käyttäjä voi tehdä uuden arvauksen jne.
  17.  *   Aluksi käyttäjältä kysytään, täytetäänkö peliruudukko satunnaisesti
  18.  * arvottavilla väreillä vai käyttäjän luettelemilla väreillä.
  19.  * (Jälkimmäinen tapa ei ole kovin järkevä, mutta se on hyödyllinen
  20.  * testauksen kannalta.) Ensimmäisessä vaihtoehdossa käyttäjältä kysytään
  21.  * satunnaislukugeneraattorin siemenlukua ja jälkimmäisessä häntä
  22.  * pyydetään syöttämään neljä väriä (värien alkukirjaimet eli neljän
  23.  * merkin mittainen merkkijono).
  24.  *   Joka kierroksella käyttäjältä kysytään uutta arvausta. Peli päättyy
  25.  * pelaajan voittoon, jos arvaus menee jokaisen värin kohdalta täysin
  26.  * oikein. Peli päättyy pelaajan häviöön, jos hän ei ole arvannut oikein
  27.  * maksimimäärällä (10) arvauskertoja.
  28.  *   Ohjelma tarkistaa, että annetut värit kuuluvat sallittujen värien
  29.  * joukkoon. Pelin päättyessä kerrotaan, voittiko vai hävisikö pelaaja.
  30.  *
  31.  */
  32.  
  33. #include "mastermind.hh"
  34.  
  35. int main()
  36. {
  37.     Board mastermind;
  38.     mastermind.play_game();
  39.  
  40.     return EXIT_SUCCESS;
  41. }
  42.  
  43. MASTERMIND.CPP
  44.  
  45. /*
  46.  * COMP.CS.110 Ohjelmointi 2
  47.  * Osio 4, projekti: Mastermind
  48.  */
  49.  
  50.  
  51. #include "mastermind.hh"
  52. #include <iostream>
  53. #include <vector>
  54. #include <string>
  55. #include <algorithm>
  56.  
  57. using namespace std;
  58.  
  59. // converts string to lowercase
  60. string to_lower(string str) {
  61.     transform(str.begin(), str.end(), str.begin(), ::tolower);
  62.     return str;
  63. }
  64.  
  65. // converts string to uppercase
  66. string to_upper(string str) {
  67.     transform(str.begin(), str.end(), str.begin(), ::toupper);
  68.     return str;
  69. }
  70.  
  71. Board::Board() {
  72.  
  73. }
  74. Board::~Board() {
  75.  
  76. }
  77.  
  78. void Board::play_game() {
  79.     ask_game_type();
  80.     generate_colors();
  81.  
  82.     // MAIN GAME LOOP
  83.     while (turn < MAX_TURNS) {
  84.         ask_for_colors();
  85.  
  86.         // QUIT GAME
  87.         if(user_guess == QUIT_CMD) {
  88.             return;
  89.         }
  90.         grade_a_guess();
  91.         print_board();
  92.         if (is_game_won) {
  93.             cout << MSG_GAME_WON << endl;
  94.             break;
  95.         }
  96.         turn++;
  97.     }
  98.  
  99.     // if main loop ends, it means turns are used up and the player lost
  100.     if (not is_game_won) {
  101.         cout << MSG_GAME_LOST << endl;
  102.     }
  103. }
  104.  
  105. void Board::ask_game_type() {
  106.     string user_input;
  107.     string seed_value;
  108.  
  109.     // print colors used in the game for user
  110.     cout << COLOR_INFO << endl;
  111.     cout << std::string(COLOR_INFO.size(), '*') << endl;
  112.  
  113.     // user must choose a random or predef game type
  114.     while (true) {
  115.         cout << INPUT_WAY_QUESTION;
  116.         cin >> user_input;
  117.  
  118.         // RANDOM game
  119.         if (to_lower(user_input) == "r") {
  120.             cout << SEED_QUESTION << endl;
  121.             get_valid_seed();
  122.             is_random_game = true;
  123.             break;
  124.         }
  125.         // PREDEFINED game
  126.         else if (to_lower(user_input) == "l") {
  127.             is_random_game = false;
  128.             break;
  129.         }
  130.         // WRONG INPUT
  131.         else {
  132.             cout << BAD_INPUT << endl;
  133.         }
  134.     }
  135.  
  136. }
  137.  
  138. void Board::generate_colors()
  139. {
  140.     // fill solution vector with 4 random letters
  141.     if (is_random_game) {
  142.         srand(seed);
  143.         for(int i = 0; i < MAX_COLORS; i++) {
  144.             char color = COLORS[rand() % DIFFERENT_COLORS];
  145.             solution.push_back(color);
  146.         }
  147.     }
  148.     else {
  149.         ask_for_colors(COLOR_QUESTION);
  150.         solution = user_guess;
  151.     }
  152. }
  153.  
  154. int Board::ask_for_colors(string question) {
  155.     string user_input;
  156.     bool valid = false;
  157.  
  158.     // demand correct input from user
  159.     while(true) {
  160.         if (question != "") {
  161.             cout << question;
  162.         } else {
  163.             cout << ROW;
  164.         }
  165.         cin >> user_input;
  166.  
  167.         // q = QUIT GAME
  168.         if (to_lower(user_input) == QUIT_CMD and question == "") {
  169.             user_guess = QUIT_CMD;
  170.             return 0;
  171.         }
  172.         // check user input for size and allowed colors
  173.         else if(user_input.size() == MAX_COLORS) {
  174.             user_guess = user_input;
  175.             valid = is_input_valid();
  176.             if (valid) {
  177.                 return 0;
  178.             } else {
  179.                 cout << UNKNOWN_COLOR << endl;
  180.             }
  181.         } else {
  182.             cout << MSG_WRONG_SIZE << endl;
  183.         }
  184.  
  185.     }
  186. }
  187.  
  188. void Board::grade_a_guess() {
  189.  
  190.     int fully_correct = 0;
  191.     int partially_correct = 0;
  192.     string potentially_partially_correct_colors = "";
  193.     string leftover_colors_from_solution = "";
  194.  
  195.     // count fully correct colors
  196.     for (unsigned long int i = 0; i < user_guess.size(); i++) {
  197.         if (user_guess.at(i) == solution.at(i)) {
  198.             fully_correct++;
  199.         } else {
  200.             potentially_partially_correct_colors += user_guess.at(i);
  201.             leftover_colors_from_solution += solution.at(i);
  202.         }
  203.     }
  204.  
  205.     // count partially correct colors
  206.     for (char pot : potentially_partially_correct_colors) {
  207.         unsigned long int index;
  208.         index = leftover_colors_from_solution.find(pot);
  209.         if (index < MAX_COLORS) {
  210.             partially_correct += 1;
  211.             leftover_colors_from_solution.erase(index, 1);
  212.         }
  213.     }
  214.  
  215.     // save results and check if the game is won
  216.     all_grades.push_back({user_guess, fully_correct, partially_correct});
  217.     if (fully_correct == MAX_COLORS) {
  218.         is_game_won = true;
  219.     }
  220. }
  221.  
  222. void Board::print_board() {
  223.     cout << std::string(GAME_BOARD_WIDTH, '=') << endl;
  224.     for (auto &guess : all_grades) {
  225.         cout << "| ";
  226.         for(char &color : guess.guess) {
  227.             cout << (char) toupper(color) << " ";
  228.         }
  229.         cout << "| " << guess.fully_correct
  230.              << " | " << guess.partially_correct << " |" << endl;
  231.     }
  232.     cout << std::string(GAME_BOARD_WIDTH, '=') << endl;
  233. }
  234.  
  235. bool Board::is_input_valid()
  236. {
  237.     bool valid = true;
  238.     // convert char array to string since char doesn't seem to have find()
  239.     string tmp = "";
  240.     tmp += COLORS;
  241.  
  242.     // search for invalid colors in user input
  243.     for(unsigned long int i = 0; i < user_guess.size(); i++) {
  244.         string letter = "";
  245.         letter += user_guess.at(i);
  246.         // find returns a big number if it doesn't find the letter
  247.         if (tmp.find(letter) > DIFFERENT_COLORS) {
  248.             valid = false;
  249.             break;
  250.         }
  251.     }
  252.     return valid;
  253. }
  254.  
  255. void Board::get_valid_seed() {
  256.     string user_input;
  257.     string temp_seed = "";
  258.  
  259.     while (true) {
  260.         cin >> user_input;
  261.         // check for anything else than digits in seed
  262.         for (char ch : user_input) {
  263.            if(isdigit(ch)) {
  264.                temp_seed += ch;
  265.            } else {
  266.                cout << BAD_INPUT << endl;
  267.                break;
  268.            }
  269.         }
  270.         // accept a seed consisting only of digits
  271.         if(temp_seed != "" and temp_seed.size() == user_input.size()) {
  272.             seed = stoi(temp_seed);
  273.             break;
  274.         }
  275.     }
  276. }
  277.  
  278. /*
  279.  * COMP.CS.110 Ohjelmointi 2
  280.  * Osio 4, projekti: Mastermind
  281.  */
  282.  
  283. #ifndef MASTERMIND_HH
  284. #define MASTERMIND_HH
  285.  
  286. #include <vector>
  287. #include <iostream>
  288.  
  289. using namespace std;
  290.  
  291. const char COLORS[] = "brygov";
  292. const int MAX_COLORS = 4;
  293. const int DIFFERENT_COLORS = 6;
  294. const int MAX_TURNS = 10;
  295. const int GAME_BOARD_WIDTH = 19;
  296.  
  297. class Board
  298. {
  299.     const string QUIT_CMD = "q";
  300.     const string COLOR_INFO = "Colors in use: B = Blue, R = Red, "
  301.                               "Y = Yellow, G = Green, O = Orange, V = Violet";
  302.     const string INPUT_WAY_QUESTION = "Enter an input way (R = random, L = list): ";
  303.     const string COLOR_QUESTION = "Enter four colors (four letters without spaces): ";
  304.     const string SEED_QUESTION = "Enter a seed value: ";
  305.     const string ROW = "ROW> ";
  306.     const string BAD_INPUT = "Bad input";
  307.     const string UNKNOWN_COLOR = "Unknown color";
  308.     const string MSG_WRONG_SIZE = "Wrong size";
  309.     const string MSG_GAME_WON = "You won: Congratulations!";
  310.     const string MSG_GAME_LOST = "You lost: Maximum number of guesses done";
  311.  
  312.     public:
  313.         // constructor and destructor (no idea how to use these, sorry!)
  314.         Board();
  315.         ~Board();
  316.  
  317.         // starts the game and runs the main gameplay loop
  318.         // until user quits, wins or loses the game
  319.         void play_game();
  320.  
  321.     private:
  322.         struct Correct {
  323.             string guess;
  324.             int fully_correct;
  325.             int partially_correct;
  326.         };
  327.  
  328.         vector<Correct> all_grades;
  329.         string solution;
  330.         string user_guess;
  331.         bool is_random_game;
  332.         bool is_game_won = false;
  333.         int  seed;
  334.         int  turn = 0;
  335.  
  336.         // user mandates if gametype is random or predefined
  337.         void ask_game_type();
  338.  
  339.         // generates random colors or asks user for colors, depending
  340.         // on gametype chosen earlier
  341.         void generate_colors();
  342.  
  343.         /* asks user for correct letters (colors) listed in const COLORS
  344.          * return: 0 (basically just returns to main program when
  345.          *            user inputs correct letters)
  346.          */
  347.         int  ask_for_colors(string question = "");
  348.  
  349.         // grades user's guess and saves it to vector all_grades
  350.         void grade_a_guess();
  351.  
  352.         // prints the game board using data from vector all_grades
  353.         /* Example:
  354.          * ===================
  355.          * | B B R R | 1 | 0 |
  356.          * | B B O O | 1 | 1 |
  357.          * ===================
  358.          */
  359.         void print_board();
  360.  
  361.         // checks that the colors user provided are listed in COLORS
  362.         bool is_input_valid();
  363.  
  364.         // gets a seed consisting of only digits from user
  365.         void get_valid_seed();
  366. };
  367.  
  368. #endif // MASTERMIND_HH
  369.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement