Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- main.cpp
- /*
- * COMP.CS.110 Ohjelmointi 2
- * Osio 4, projekti: Mastermind
- *
- * Ohjelman kuvaus:
- * Ohjelma toteuttaa Mastermind-pelin. Pelissä annetaan tai arvotaan
- * ensin salainen neljän värin sarja. Sama väri voi esiintyä sarjassa
- * useita kertoja, mutta mikään neljästä positiosta ei voi olla tyhjä.
- * Käyttäjä yrittää arvata, mitkä värit esiintyvät sarjassa ja missä
- * järjestyksessä. Tätä varten käyttäjä antaa oman neljän värin sarjansa,
- * ja ohjelma ilmoittaa, kuinka monta väriarvausta meni täysin oikein
- * (oikea väri oikeassa positiossa) sekä kuinka monta arvausta meni
- * pelkästään värin osalta oikein (oikea väri väärässä positiossa).
- * Tämän jälkeen käyttäjä voi tehdä uuden arvauksen jne.
- * Aluksi käyttäjältä kysytään, täytetäänkö peliruudukko satunnaisesti
- * arvottavilla väreillä vai käyttäjän luettelemilla väreillä.
- * (Jälkimmäinen tapa ei ole kovin järkevä, mutta se on hyödyllinen
- * testauksen kannalta.) Ensimmäisessä vaihtoehdossa käyttäjältä kysytään
- * satunnaislukugeneraattorin siemenlukua ja jälkimmäisessä häntä
- * pyydetään syöttämään neljä väriä (värien alkukirjaimet eli neljän
- * merkin mittainen merkkijono).
- * Joka kierroksella käyttäjältä kysytään uutta arvausta. Peli päättyy
- * pelaajan voittoon, jos arvaus menee jokaisen värin kohdalta täysin
- * oikein. Peli päättyy pelaajan häviöön, jos hän ei ole arvannut oikein
- * maksimimäärällä (10) arvauskertoja.
- * Ohjelma tarkistaa, että annetut värit kuuluvat sallittujen värien
- * joukkoon. Pelin päättyessä kerrotaan, voittiko vai hävisikö pelaaja.
- *
- */
- #include "mastermind.hh"
- int main()
- {
- Board mastermind;
- mastermind.play_game();
- return EXIT_SUCCESS;
- }
- MASTERMIND.CPP
- /*
- * COMP.CS.110 Ohjelmointi 2
- * Osio 4, projekti: Mastermind
- */
- #include "mastermind.hh"
- #include <iostream>
- #include <vector>
- #include <string>
- #include <algorithm>
- using namespace std;
- // converts string to lowercase
- string to_lower(string str) {
- transform(str.begin(), str.end(), str.begin(), ::tolower);
- return str;
- }
- // converts string to uppercase
- string to_upper(string str) {
- transform(str.begin(), str.end(), str.begin(), ::toupper);
- return str;
- }
- Board::Board() {
- }
- Board::~Board() {
- }
- void Board::play_game() {
- ask_game_type();
- generate_colors();
- // MAIN GAME LOOP
- while (turn < MAX_TURNS) {
- ask_for_colors();
- // QUIT GAME
- if(user_guess == QUIT_CMD) {
- return;
- }
- grade_a_guess();
- print_board();
- if (is_game_won) {
- cout << MSG_GAME_WON << endl;
- break;
- }
- turn++;
- }
- // if main loop ends, it means turns are used up and the player lost
- if (not is_game_won) {
- cout << MSG_GAME_LOST << endl;
- }
- }
- void Board::ask_game_type() {
- string user_input;
- string seed_value;
- // print colors used in the game for user
- cout << COLOR_INFO << endl;
- cout << std::string(COLOR_INFO.size(), '*') << endl;
- // user must choose a random or predef game type
- while (true) {
- cout << INPUT_WAY_QUESTION;
- cin >> user_input;
- // RANDOM game
- if (to_lower(user_input) == "r") {
- cout << SEED_QUESTION << endl;
- get_valid_seed();
- is_random_game = true;
- break;
- }
- // PREDEFINED game
- else if (to_lower(user_input) == "l") {
- is_random_game = false;
- break;
- }
- // WRONG INPUT
- else {
- cout << BAD_INPUT << endl;
- }
- }
- }
- void Board::generate_colors()
- {
- // fill solution vector with 4 random letters
- if (is_random_game) {
- srand(seed);
- for(int i = 0; i < MAX_COLORS; i++) {
- char color = COLORS[rand() % DIFFERENT_COLORS];
- solution.push_back(color);
- }
- }
- else {
- ask_for_colors(COLOR_QUESTION);
- solution = user_guess;
- }
- }
- int Board::ask_for_colors(string question) {
- string user_input;
- bool valid = false;
- // demand correct input from user
- while(true) {
- if (question != "") {
- cout << question;
- } else {
- cout << ROW;
- }
- cin >> user_input;
- // q = QUIT GAME
- if (to_lower(user_input) == QUIT_CMD and question == "") {
- user_guess = QUIT_CMD;
- return 0;
- }
- // check user input for size and allowed colors
- else if(user_input.size() == MAX_COLORS) {
- user_guess = user_input;
- valid = is_input_valid();
- if (valid) {
- return 0;
- } else {
- cout << UNKNOWN_COLOR << endl;
- }
- } else {
- cout << MSG_WRONG_SIZE << endl;
- }
- }
- }
- void Board::grade_a_guess() {
- int fully_correct = 0;
- int partially_correct = 0;
- string potentially_partially_correct_colors = "";
- string leftover_colors_from_solution = "";
- // count fully correct colors
- for (unsigned long int i = 0; i < user_guess.size(); i++) {
- if (user_guess.at(i) == solution.at(i)) {
- fully_correct++;
- } else {
- potentially_partially_correct_colors += user_guess.at(i);
- leftover_colors_from_solution += solution.at(i);
- }
- }
- // count partially correct colors
- for (char pot : potentially_partially_correct_colors) {
- unsigned long int index;
- index = leftover_colors_from_solution.find(pot);
- if (index < MAX_COLORS) {
- partially_correct += 1;
- leftover_colors_from_solution.erase(index, 1);
- }
- }
- // save results and check if the game is won
- all_grades.push_back({user_guess, fully_correct, partially_correct});
- if (fully_correct == MAX_COLORS) {
- is_game_won = true;
- }
- }
- void Board::print_board() {
- cout << std::string(GAME_BOARD_WIDTH, '=') << endl;
- for (auto &guess : all_grades) {
- cout << "| ";
- for(char &color : guess.guess) {
- cout << (char) toupper(color) << " ";
- }
- cout << "| " << guess.fully_correct
- << " | " << guess.partially_correct << " |" << endl;
- }
- cout << std::string(GAME_BOARD_WIDTH, '=') << endl;
- }
- bool Board::is_input_valid()
- {
- bool valid = true;
- // convert char array to string since char doesn't seem to have find()
- string tmp = "";
- tmp += COLORS;
- // search for invalid colors in user input
- for(unsigned long int i = 0; i < user_guess.size(); i++) {
- string letter = "";
- letter += user_guess.at(i);
- // find returns a big number if it doesn't find the letter
- if (tmp.find(letter) > DIFFERENT_COLORS) {
- valid = false;
- break;
- }
- }
- return valid;
- }
- void Board::get_valid_seed() {
- string user_input;
- string temp_seed = "";
- while (true) {
- cin >> user_input;
- // check for anything else than digits in seed
- for (char ch : user_input) {
- if(isdigit(ch)) {
- temp_seed += ch;
- } else {
- cout << BAD_INPUT << endl;
- break;
- }
- }
- // accept a seed consisting only of digits
- if(temp_seed != "" and temp_seed.size() == user_input.size()) {
- seed = stoi(temp_seed);
- break;
- }
- }
- }
- /*
- * COMP.CS.110 Ohjelmointi 2
- * Osio 4, projekti: Mastermind
- */
- #ifndef MASTERMIND_HH
- #define MASTERMIND_HH
- #include <vector>
- #include <iostream>
- using namespace std;
- const char COLORS[] = "brygov";
- const int MAX_COLORS = 4;
- const int DIFFERENT_COLORS = 6;
- const int MAX_TURNS = 10;
- const int GAME_BOARD_WIDTH = 19;
- class Board
- {
- const string QUIT_CMD = "q";
- const string COLOR_INFO = "Colors in use: B = Blue, R = Red, "
- "Y = Yellow, G = Green, O = Orange, V = Violet";
- const string INPUT_WAY_QUESTION = "Enter an input way (R = random, L = list): ";
- const string COLOR_QUESTION = "Enter four colors (four letters without spaces): ";
- const string SEED_QUESTION = "Enter a seed value: ";
- const string ROW = "ROW> ";
- const string BAD_INPUT = "Bad input";
- const string UNKNOWN_COLOR = "Unknown color";
- const string MSG_WRONG_SIZE = "Wrong size";
- const string MSG_GAME_WON = "You won: Congratulations!";
- const string MSG_GAME_LOST = "You lost: Maximum number of guesses done";
- public:
- // constructor and destructor (no idea how to use these, sorry!)
- Board();
- ~Board();
- // starts the game and runs the main gameplay loop
- // until user quits, wins or loses the game
- void play_game();
- private:
- struct Correct {
- string guess;
- int fully_correct;
- int partially_correct;
- };
- vector<Correct> all_grades;
- string solution;
- string user_guess;
- bool is_random_game;
- bool is_game_won = false;
- int seed;
- int turn = 0;
- // user mandates if gametype is random or predefined
- void ask_game_type();
- // generates random colors or asks user for colors, depending
- // on gametype chosen earlier
- void generate_colors();
- /* asks user for correct letters (colors) listed in const COLORS
- * return: 0 (basically just returns to main program when
- * user inputs correct letters)
- */
- int ask_for_colors(string question = "");
- // grades user's guess and saves it to vector all_grades
- void grade_a_guess();
- // prints the game board using data from vector all_grades
- /* Example:
- * ===================
- * | B B R R | 1 | 0 |
- * | B B O O | 1 | 1 |
- * ===================
- */
- void print_board();
- // checks that the colors user provided are listed in COLORS
- bool is_input_valid();
- // gets a seed consisting of only digits from user
- void get_valid_seed();
- };
- #endif // MASTERMIND_HH
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement