Converted everything to orgmode

converted everything to orgmode and added solution to the README files
This commit is contained in:
2025-03-31 08:40:43 +02:00
parent 8719f4c140
commit 88e0b5ed69
88 changed files with 1942 additions and 2989 deletions

View File

@@ -0,0 +1,127 @@
#+TITLE: Project 1: Guess A Number (Task 1)
#+AUTHOR: JirR02
* About this task
** Project overview
The goal of the first project is to program a simple number guessing game: the player needs to correctly guess a number, chosen from an interval \([1,N]\), with at most \{K\} guesses.
In the lecture, a first version of the game was presented, in which the player had only one chance of guessing the correct number. In order to implement the full game, you will have to extend this version by allowing the player to guess up to \(K\) times.
The first project consists of two tasks: *task 1* /(this task)/ is to reimplement the first version of the game that was presented in the lecture, *task 2* is to implement the full game.
** General development advice
Develop your program step-by-step, and save, run and compile it often. I.e. implement a single feature, such as inputting the guess, or comparing the guess and the correct number, and then compile and run the program to see if your code (still) works as intended. Small changes and repeated testing make it easier for you to observe problems, to work out what causes them, and to finally solve them.
** Fulfilling requirements and testing programs
A particular goal of this task is to make you understand how strongly connected requirements and testing (and thus grading submissions) are. E.g. if the task description requires output of the shape "I␣saw␣\(n\)␣cat(s).", where $n$ is a number and ␣ represents blanks/whitespaces, your program will not be considered correct if it outputs a text that is "basically the same", but does not precisely match the requirements. E.g. the following outputs, while very close to the expected output, do not match the shape specified above: "i␣saw␣3␣cat(s).", "I␣saw␣3␣cats.", "I␣saw␣1␣cat.", "I␣saw␣2␣cat(s)" and "i␣saw␣2␣␣cat(s)␣.".
Meeting such requirements precisely is necessary for testing: we automatically (at least to some extent) test correctness of your programs by comparing the expected output to the output produced by your program. Since these comparisons are performed by a computer, it is much much easier to do them syntactically, i.e. letter-by-letter.
However, being able to precisely fulfil requirements is more generally important, in particular when working with customers: imagine you order a black smartphone, but then get delivered a dark blue one (same make and model). Although "basically the same", it's just not what you ordered. The same holds for software — it's the details that matter.
** Your task
To solve this task, proceed as follows:
1. Look at the template program, in particular main.cpp, and see what's already there (e.g. variable declarations) and what's still missing. The latter is hinted at by TODO comments.
1. The template already contains code for picking the number to guess. By default, the number is randomly choosen from the interval \([1,3]\):
#+begin_src cpp
number_to_guess = choose_a_number(3);
#+end_src
/During development/, you might want to change this line: e.g. read the number from the keyboard:
#+begin_src cpp
std::cin >> number_to_guess;
#+end_src
or even hard-code (i.e. fix) a specific number, e.g.
#+begin_src cpp
number_to_guess = 3;
#+end_src
However, in order to run the automatic tests, and /when submitting your final version/, your program /must/ either read the word from the keyboard or use the ~choose_a_number~ function.
1. Now address the first TODO comment: by outputting the text "Your␣guess:␣" (as before, ␣ denotes a blank/whitespace character), followed by inputting the guess from the keyboard into variable guess.
2. Now address the second TODO comment: by comparing the two numbers for equality. If they are, output the line
#+begin_src shell
Congratulations,␣you␣correctly␣guessed␣X!
#+end_src
where X is the correctly guessed number. Since the output is expected to be a /line/, don't forget to end it with either ~\n~ or ~std::endl~.
If the guess was wrong, however, output the line
#+begin_src shell
Sorry,␣but␣Y␣is␣wrong,␣X␣was␣the␣number␣to␣guess.
#+end_src
where Y is the incorrectly guessed number.
** Examples
As an illustration, consider the following example in- and outputs of two games (in which the number to guess was randomly chosen). A successfully completed game:
#+begin_src shell
Number to guess: ?
Your guess: 3
Congratulations, you correctly guessed 3!
#+end_src
And a lost game:
#+begin_src shell
Number to guess: ?
Your guess: 2
Sorry, but 2 is wrong, 1 was the number to guess.
#+end_src
** Testing your program
You can always test your program manually: click the "play" button in the bottom panel, run your program and see if it behaves as expected.
Relevant for your final submission, however, is if it passes the automated tests: to run those, click the "chemistry flask" button in the bottom panel and wait for the output to appear. If your program passes all tests — everything is green and your score is 100% — then your program is ready to be submitted.
Otherwise, /carefully/ compare the expected output to the actual output to find out what went wrong.
*Reminder*: The devil is in the detail! Pay attention to whitespace and newline characters, and in general check that your output fulfils all requirements, even the "boring" ones.
** Submitting your solution
Finally, submit your solution (your program) by clicking the corresponding button in the top right corner of the Code Expert IDE (open Task/History first). Your program will be tested automatically, and your score will be shown in the "History" view, which can be opened by clicking on the corresponding tab on the right of the Code Expert IDE. Note that you can submit arbitrarily often (before the exercise deadline, of course), and your last submission will be considered for grading.
For this task, all tests need to pass in order to successfully solve this task. This should be rather easy, though, since there isn't much that can go wrong.
You can also see the results for your submission on the "Enrolled Courses" tab of Code Expert, as green or red percentage values to the left of the task's name.
* Solution
#+begin_src cpp
#include <iostream>
#include "guess_a_number.h"
int main() {
int number_to_guess; // The number to guess
int guess; // The guessed number
std::cout << "Number to guess: ";
number_to_guess = choose_a_number(3);
std::cin >> guess;
std::cout << "Your guess: ";
if (guess == number_to_guess) {
std::cout << "Congratulations, you correctly guessed " << number_to_guess << "!";
} else {
std::cout << "Sorry, but " << guess << " is wrong, " << number_to_guess << " was the number to guess.";
}
}
#+end_src

View File

@@ -0,0 +1,161 @@
#+TITLE: Project 1: Guess the Number (Task 2)
#+AUTHOR: JirR02
* Project overview
The goal of the first project is to program a simple number guessing game: the player needs to correctly guess a number, chosen from an interval\([1,N]\), with at most \(K\)guesses.
In the lecture, a first version of the game was presented, in which the player had only one chance of guessing the correct number. In order to implement the full game, you will have to extend this version by allowing the player to guess up to \(K\) times.
The first project consists of two tasks: *task 1* was to reimplement the first version of the game that was presented in the lecture, *task 2* /(this task)/ is to implement the full game.
* Stepwise development
The program template of task 2 differs from that of task 1 in two important ways:
1. A goal of task 1 was to show you how important — and potentially cumbersome — it is to precisely fulfil output requirements and to pass the automated tests. This is no longer the focus of task 2, and you are therefore given functions such as =print_you_won(...)= that generate the expected output for you.
1. The final program consists of three major parts, and the template has three corresponding "holes" where you have to fill in code: inputting the next guess, checking the guess, and finishing the current round (we refer to each guess as one round of the game).
To make it easier for you to develop your solution step by step, you are given a "master implementation" for these steps, e.g =PART1_read_next_guess(...)=, which you must replace with your own code. Use the following workflow:
1. Run the tests: everything should be fine (thanks to the master implementations)
1. Comment the first master implementation; now all tests should fail
1. Write your own code that replaces the commented master implementation
1. Once all tests pass again, continue by commenting and replacing the next master implementation
1. Once you have replaced all master implementations with your own code (and all tests pass), your solution is ready to be submitted. *Read the remarks at the end of this text!*
* Your task
As mentioned above, you can develop the final solution step by step, by iteratively replacing each call to a =STEP...= master implementation by your own code.
** Step 1: input the next guess
1. Find the code line
#+begin_src cpp
PART1_read_next_guess(guess);
#+end_src
and comment it, i.e. change it to
#+begin_src cpp
// PART1_read_next_guess(guess);
#+end_src
1. As a replacement for the commented master implementation, write code that outputs "Your␣guess:␣" (as before, ␣ denotes a blank/whitespace character), and then inputs the next guess from the keyboard into variable guess.
1. Run the tests, they should all pass again
** Step 2: handle the guess the user made
1. Find and comment the code line
#+begin_src cpp
PART2_handle_guess(guess, number_to_guess, play);
#+end_src
1. Write code that compares the user-made guess with the number to guess: if the two are equal, call =print_you_won(guess)= to generate a you-won message, and set variable =play= to =false= to end the game. Otherwise, call =print_wrong_guess(guess)= to generate a wrong-guess message (and let the game continue).
** Step 3: handle the guess the user made
1. Find and comment the code line
#+begin_src cpp
PART3_finish_round(number_to_guess, max_attempts, attempts, play);
#+end_src
1. Write code that increments the number of attempts the user made by 1. Furthermore, write code that 1. checks if the maximum number of attempts has been reached, and if so, 2. call print_you_lost(number_to_guess, attempts) and set play to false.
* Examples
As an illustration, consider the following example in- and outputs of two games (in which the number to guess was randomly chosen). A successfully completed game:
#+begin_src shell
Number to guess: ?
Number of attempts: 3
You have 3 attempt(s) left.
Your guess: 7
Sorry, but 7 is wrong.
You have 2 attempt(s) left.
Your guess: 3
Congratulations, you correctly guessed 3!
#+end_src
And a lost game:
#+begin_src shell
Number to guess: ?
Number of attempts: 2
You have 2 attempt(s) left.
Your guess: 123
Sorry, but 123 is wrong.
You have 1 attempt(s) left.
Your guess: 321
Sorry, but 321 is wrong.
You lost after 2 attempt(s) :-( The number to guess was 2.
#+end_src
* Submitting your solution
*Important*: you /must/ replace all three master implementations (calls to functions =PART1/2/3=) with your own code! Your submission /will not be accepted/ if it still uses the master implementations, regardless of how many tests pass when /you/ run them.
-----
* Solutions
#+begin_src cpp
#include <iostream>
#include "guess_a_number.h"
int main() {
int number_to_guess;
int max_attempts;
std::cout << "Number to guess: ";
number_to_guess = choose_a_number(10);
std::cout << "Number of attempts: ";
if (max_attempts < 1) max_attempts = 1;
int attempts = 0; // Attempts made so far
bool play = true; // false once the game is over
while (play) {
print_attempts_left(max_attempts - attempts);
// *** Part 1: input the next guess ****************************************
int guess; // The user's guess
//PART1_read_next_guess(guess);
std::cout << "Your guess: ";
std::cin >> guess;
// *** Part 2: handle the guess the user made *****************************
//PART2_handle_guess(guess, number_to_guess, play);
if (guess == number_to_guess) {
print_you_won(guess);
play = false;
} else {
print_wrong_guess(guess);
}
// *** Part 3: finish up the round ****************************************
if (play) {
//PART3_finish_round(number_to_guess, max_attempts, attempts, play);
attempts += 1;
if (attempts == max_attempts) {
print_you_lost(number_to_guess, attempts);
play = false;
}
}
}
}
#+end_src
-----
Made by JirR02 in Switzerland 🇨🇭

View File

@@ -0,0 +1,258 @@
#+TITLE: Project 2: Hangman
#+AUTHOR: JirR02
* Project Overview
The goal of this project is to implement a version of the popular guessing game known as Hangman (German: Galgenmännchen). The rules of the game are simple: the first player picks a word which the second player has to guess character by character — with a limited amount of guesses.
When played on paper, a snapshot of the game typically looks as follows:
[[./game.png]]
or your version, we focus on the essence of the game:
1. Choosing a word and initialising the game
1. Repeatedly guessing characters, and uncovering them if they occur in the chosen word
1. Eventually announcing that the player won ... or lost
** A primer on strings and chars
In =C++= (and in most other programming languages), sequences of characters, such as the word the player needs to guess, can be represented as strings. Strings will be introduced properly in your later, regular computer science course; for now, you only need to know the following about strings in order to implement Hangman:
1. Strings and operations thereon are provided by the *string* library:
#+begin_src cpp
#include <string>
using std::string;
#+end_src
The first line allows us to use the =c++= *string* library, the second line allows us to directly use =string= as a data type, instead of having to write =std::string= everywhere.
1. A variable named 'word' of type string can be declared as follows:
#+begin_src cpp
string word;
#+end_src
1. String-typed variables can be set as follows:
- By using string literals, which are enclosed in quotation marks:
#+begin_src cpp
word = "potato";
#+end_src
- By reading a string from the keyboard:
#+begin_src cpp
std::cin >> word;
#+end_src
- By assigning it another string
#+begin_src cpp
word = chooseWord();
#+end_src
The function chooseWord() returns a string value which is then assigned to the variable word.
1. The length (type unsigned int) of a string can be determined by using the length function, which returns the number of characters in the string:
#+begin_src cpp
string word = "hangman";
std::cout << word.length(); // outputs: 7
#+end_src
1. The nth character (type char) of a string can be accessed using the at function:
#+begin_src cpp
string word = "hangman";
std::cout << word.at(0); // Output: h (the first character)
std::cout << word.at(6); // Output: n (the last character)
#+end_src
Note that the first character is at position 0 and the last character at position length() - 1!
The nth character can also be replaced by using the at function, e.g.
#+begin_src cpp
string workingCopy = "_______";
workingCopy.at(3) = 'n';
std::cout << workingCopy; // Output: __n____
#+end_src
where '_' denotes a single character (of type char).
1. Similar to whole strings, you can also declare variables for single characters (type char) and read them from the keyboard:
#+begin_src cpp
char guess;
std::cin >> guess;
#+end_src
** Stepwise development
The program template that you start with has been developed using the /stepwise refinement/ technique, and just like for project 1, task 2, contains master implementations (functions =PART1=... etc.) that you must replace with your own code.
We also provide you with output-generating functions (e.g. =printYouWon()=) that make it easier for you to please the tests (and thus the autograder).
As before, we suggest that you develop your program step-by-step, and run or test it often. I.e. implement a single part, such as reading the next guess from the keyboard or updating the working copy, and then run and test the program to see if it (still) works as intended.
** Implementing the game
Your job is to implement three major parts of the actual algorithm to play the game. As before, each part can be implemented separately.
The following variables are already declared in the template given to you:
- =string= word: This variable contains the word that must be guessed
- =string= workingCopy: This variable is initialized with a string that has the same size as the string word. Each character in this string is initialized with an underscore (_).
- =bool= done: If this variable is set to true the program will not play another round of the game (both in the case of winning and losing).
- =int= wrongGuesses: This variable is initialized with 0 and must be incremented by one every time a guessed character doesn't occur in the word to guess.
- =int= maxWrongGuesses: This variable is initialized with constant 6. Don't change it.
- =bool= found: This variable indicates whether (true) or not (false) the guessed character occurs in the word to guess.
*Note:* Each of the following parts is already implemented in a master implementation function (=PART=...), which you need to replace with your own code. The corresponding places in the code are marked by TODO comments.
*** Part 1
This part is about reading the next guess from the keyboard.
Comment out the call to =PART1_readCharacter= and replace it by an implementation that performs the following steps:
1. Output the text " =Your guess:= "
1. Read a single character from the keyboard into variable guess.
You already know how to output text; see the string primer above (point 6) for how to input a single character.
*** Part 2
This part involves checking if the guessed character occurs in the word, and updating the =workingCopy= accordingly: by replacing the underlines at the respective position(s) by the guessed character. Variable found indicates if the guessed character was found in the word.
Comment out the call to =PART2_updateWorkingCopy= and replace it by an implementation that performs the requested operation.
*Example (found):* If variable word is set to "success", variable =workingCopy= still contains the initial underlines ("=_______=") and the current guess is '=c=', then two actions must be performed:
1. Variable found must be set to =true=, because '=c=' occurs in the word "success"
1. All occurrences of the letter '=c=' must be uncovered in the working copy, thus variable =workingCopy= must be changed to have the content "=__cc___="
*Example (not found):* If variable word is set to "success", variable =workingCopy= still contains the initial underlines ("=_______=") and the current guess is '=x=', then the following is important:
1. Variable found must remain =false= (because '=x=' does not occur in "success"
1. Variable =workingCopy= must not be changed.
*** Part 3
This part is about determining if the game continues, or if it is already won or lost.
Comment out the call to =PART3_updateGameState= and replace it by an equivalent implementation of your own, as described next.
If the player made a correct guess and we uncovered at least one further character in the working copy (in which case variable found has value =true=), and if variable =workingCopy= now equals variable word, then the game has been won. Two things must happen in this case:
1. Set variable done to true, to indicate that the game must not continue.
1. Call =printYouWon(word)=, which will output the result of the game (in a format required by the autograder).
Otherwise, if the player guessed incorrectly (in which case variable found is =false=), variable =wrongGuesses= must be incremented by one. If this variable is afterwards equal to =maxWrongGuesses= then the game is lost, in which case the following two things must happen:
1. Set variable done to =true=, to indicate that the game must not continue.
1. Call =printYouLost(word)=, which will output the result of the game (in a format required by the autograder).
In all other situations, just make sure that variable done remains =false=. This ensures that the game continues.
** Submitting your solution
*Important:* you must replace all three master implementations (calls to functions =PART1/2/3=) with your own code! Your submission /will not be accepted/ if it still uses the master implementations, regardless of how many tests pass when you run them.
To successfully complete this project, your solution needs to pass 12 out of 17 tests, i.e. you don't need to score 100%.
** Hints
- Checking for equality of strings can be done using the ==== operator, the same way you would check equality of numbers or booleans.
- Pimp your implementation by calling =showHangman(i)= to draw the gallows after =i= incorrect guesses (for i between 0 and 6)
- You don't need to account for German umlauts, French accents etc. (such as ö or é)
- You do not need to handle duplicated guesses in any special way. E.g. if the player guesses X twice, then either nothing happens the second time around (if X occurs in the word) or the player loses a point each time (if X does not occur in the word).
- If you're interested (and brave enough), you can find more information about strings at https://en.cppreference.com/w/cpp/string
* Solution
#+begin_src cpp
#include <iostream>
#include <string>
#include "hangman.h"
using std::string;
int main() {
// Word the player needs to guess (randomly selected)
string word = chooseWord();
//string word = "success";
// Initialise the "uncovered" word that is shown to the player: the uncovered
// word is obtained by replacing each letter from the original word (variable
// word) with an underscore (i.e. _).
string workingCopy = createWorkingCopy(word);
// This variable indicates whether or not the game is over
bool done = false;
int wrongGuesses = 0; // Number of wrong guesses
int maxWrongGuesses = 6; // Maximum number of wrong guesses (don't change)
// Draw the empty gallow
showHangman(0);
// Game loop (each iteration is a round of the game)
while (!done) {
printGameState(maxWrongGuesses, wrongGuesses);
printWorkingCopy(workingCopy);
/** Part 1: input next guess **********************************************/
char guess = '\0';
// TODO: replace the following line with your implementation
//PART1_readCharacter(guess);
std::cout << "Your guess: ";
std::cin >> guess;
/** Part 2: update working copy *******************************************/
bool found = false;
// TODO: replace the following line with your implementation
//PART2_updateWorkingCopy(word, guess, workingCopy, found);
for (int i = 0; i != word.length(); i++) {
if (guess == word.at(i)) {
found = true;
workingCopy.at(i) = guess;
}
}
/** Part 3: update game state *********************************************/
// TODO: replace the following line with your implementation
//PART3_updateGameState(word, workingCopy, found, maxWrongGuesses, done, wrongGuesses);
if (workingCopy == word) {
done = true;
printYouWon(word);
} else if (found == false) {
wrongGuesses += 1;
}
if (wrongGuesses == maxWrongGuesses) {
done = true;
printYouLost(word);
}
}
return 0;
}
#+end_src
-----
Made by JirR02 in Switzerland 🇨🇭

BIN
Vorkurs/Projekt_2/game.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB