1
0
Fork 0
mirror of https://github.com/mfocko/blog.git synced 2025-05-11 22:02:59 +02:00

chore: transfer all KBs to single one

Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
Matej Focko 2022-11-05 15:24:54 +01:00
parent d207e870d4
commit 7427475022
Signed by: mfocko
GPG key ID: 7C47D46246790496
159 changed files with 28847 additions and 0 deletions

View file

@ -0,0 +1,24 @@
cmake_minimum_required(VERSION 3.0)
# Project configuration
project(seminar10-bonus)
set(SOURCES hangman.c main.c)
# Executable
add_executable(hangman hangman.c main.c)
add_executable(test_hangman test_hangman.c hangman.c)
# Configure compiler warnings
if (CMAKE_C_COMPILER_ID MATCHES Clang OR ${CMAKE_C_COMPILER_ID} STREQUAL GNU)
# using regular Clang, AppleClang or GCC
# Strongly suggested: neable -Werror
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu11 -Wall -Wextra -pedantic")
elseif (${CMAKE_C_COMPILER_ID} STREQUAL MSVC)
# using Visual Studio C++
target_compile_definitions(${EXECUTABLE} PRIVATE _CRT_SECURE_NO_DEPRECATE)
set(CMAKE_CXX_FLAGS "/permissive- /W4 /EHsc")
endif()
if(MINGW)
target_compile_definitions(${EXECUTABLE} PRIVATE __USE_MINGW_ANSI_STDIO=1)
endif()

View file

@ -0,0 +1,11 @@
check: check-unit check-functional
check-unit:
build/test_hangman
check-functional:
python3 test-bonus.py test hangman
python3 test-bonus.py test hangman --no-global-config
clean:
rm -rf test-*/*.out_produced

View file

@ -0,0 +1,233 @@
#include "hangman.h"
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#define MAX_LENGTH 50
#define ALPHABET_LENGTH 27
int get_word(const char *wordlist, char secret[])
{
FILE *fp = fopen(wordlist, "rb");
if (fp == NULL) {
fprintf(stderr, "No such file or directory: %s\n", wordlist);
return 1;
}
struct stat st;
stat(wordlist, &st);
long int size = st.st_size;
/* FIXME: Can fall into infinite loop... */
do {
long int random = (rand() % size) + 1;
fseek(fp, random, SEEK_SET);
int result = fscanf(fp, "%*s %20s", secret);
if (result != EOF)
break;
} while (1);
fclose(fp);
return 0;
}
static void print_word(const char *word)
{
for (size_t i = 0; word[i]; i++) {
printf(" %c", word[i]);
}
printf("\n");
}
bool word_guessed(const char secret[], const char letters_guessed[])
{
size_t l = strlen(secret), k=0;
for (size_t j = 0; letters_guessed[j]; j++) {
for (size_t i = 0; secret[i]; i++) {
if (secret[i] == letters_guessed[j]) {
k++;
}
}
}
return l <= k;
}
void censor_word(const char secret[], const char letters_guessed[], char guessed_word[])
{
size_t i;
for (i = 0; secret[i]; i++, guessed_word++) {
*guessed_word = secret[i];
bool guessed = false;
for (int j = 0; letters_guessed[j]; j++) {
if (secret[i] == letters_guessed[j]) {
guessed = true;
}
}
if (!guessed) {
*guessed_word = '_';
}
}
*guessed_word = '\0';
}
void get_available_letters(const char letters_guessed[],
char available_letters[])
{
size_t k = 0;
for (char letter = 'a'; letter <= 'z'; letter++) {
bool to_be_put = true;
for (size_t j = 0; letters_guessed[j]; j++) {
if (letters_guessed[j] == letter) {
to_be_put = false;
break;
}
}
if (to_be_put) {
available_letters[k++] = letter;
}
}
available_letters[k] = '\0';
}
static bool been_already_guessed(const char *guessed_letters,
const char letter)
{
for (size_t i = 0; guessed_letters[i]; i++) {
if (guessed_letters[i] == letter) {
return true;
}
}
return false;
}
static bool is_good_guess(const char secret[], char guessed_word[], const char letter)
{
bool result = false;
for (size_t i = 0; secret[i]; i++) {
if (secret[i] == letter) {
result = true;
break;
}
}
if (result) {
printf("Good guess:");
} else {
printf("Oops! That letter is not in my word:");
}
print_word(guessed_word);
return result;
}
static bool guessed_whole(const char *secret, const char *guess)
{
for (size_t i = 0; secret[i]; i++)
if (tolower(guess[i]) != secret[i]) {
return false;
}
return true;
}
static int get_guess(char *guess)
{
int result = scanf("%s", guess);
if (result == 1) {
*guess = tolower(*guess);
return result;
}
int ch = 0;
fprintf(stderr, "Input was not successful.\n");
while (ch != EOF && (ch = getchar()) != '\n')
;
return result;
}
void hangman(const char secret[])
{
printf("Welcome to the game, Hangman!\n");
size_t length_of_word = strlen(secret);
printf("I am thinking of a word that is %lu letters long.\n",
length_of_word);
int guesses = 8, no_of_guessed_letters = 0;
char available_letters[ALPHABET_LENGTH],
guessed_letters[ALPHABET_LENGTH] = { 0 };
char guess[MAX_LENGTH];
char guessed_word[MAX_LENGTH] = { 0 };
get_available_letters(guessed_letters, available_letters);
while (guesses > 0) {
printf("-------------\n");
if (word_guessed(secret, guessed_letters)) {
printf("Congratulations, you won!\n");
return;
}
printf("You have %d guesses left.\n", guesses);
printf("Available letters: %s\n", available_letters);
printf("Please guess a letter: ");
int read_status = get_guess(guess);
if (read_status == EOF) {
fprintf(stderr, "No more input to read.\n");
return;
} else if (read_status == 0) {
continue;
}
if (guess[1]) {
if (guessed_whole(secret, guess)) {
printf("Congratulations, you won!\n");
} else {
printf("Sorry, bad guess. The word was %s.\n", secret);
}
}
if (*guess < 'a' || *guess > 'z') {
printf("Oops! '%c' is not a valid letter:", *guess);
censor_word(secret, guessed_letters, guessed_word);
print_word(guessed_word);
continue;
}
if (been_already_guessed(guessed_letters, *guess)) {
printf("Oops! You've already guessed that letter:");
censor_word(secret, guessed_letters, guessed_word);
print_word(guessed_word);
continue;
}
guessed_letters[no_of_guessed_letters++] = *guess;
get_available_letters(guessed_letters, available_letters);
censor_word(secret, guessed_letters, guessed_word);
if (!is_good_guess(secret, guessed_word, *guess)) {
guesses--;
}
}
if (guesses == 0) {
printf("-------------\n");
printf("Sorry, you ran out of guesses. The word was %s.\n", secret);
}
}

View file

@ -0,0 +1,55 @@
#include <stdbool.h>
#define WORDLIST_FILENAME "words.txt"
/**
* Function detects, whether player guessed the secret word
* Based on the letters player used for guessing, this function detects,
* if it is possible to construct (and guess) the secret word from this set.
* If it is possible, function returns true. If not, returns false.
* @param secret the secret word lowercase
* @param letters_guessed the lowercase letters player already used in his guessing
* @return true, if word is guess; false otherwise.
*/
bool word_guessed(const char secret[], const char letters_guessed[]);
/**
* Function returns string representing the guessed word
* This string contains visible letters, which were guessed successfuly
* by player at their correct positions. If there are still some hidden
* letters, the character '_' will be used for their representation.
* @param secret the secret word lowercase
* @param letters_guessed the lowercase letters player already used in his guessing
* @param guessed_word the constructed string as result of this function (output parameter)
*/
void censor_word(const char secret[], const char letters_guessed[], char guessed_word[]);
/**
* Returns all letters, which were not used for guessing
* Function returns set of lowercase letters sorted in alphabetical order. This
* set will contain all letters from the alphabet, but it ommits those, which
* were already guessed.
* @param letters_guessed the lowercase letters player already used in his guessing
* @param available_letters set of lowercase not yet used letters
*/
void get_available_letters(const char letters_guessed[], char available_letters[]);
/**
* Starts interactive hangman game
*
* @param secret the secret word lowercase
*/
void hangman(const char secret[]);
/**
* Returns the random word
* Function opens the file with all the words and reads randomly one of them
* into the buffer pointed by secret. Word consists of lowercase letters.
* If there is some error with reading the file, 1 is returned.
* Don't forget to initialize the random numbers in your main() function will srand() call!
* Otherwise (everything is ok), 0 is returned.
* @param wordlist path to the file with words
* @param secret buffer, where random word will be read
* @return status code
*/
int get_word(const char *wordlist, char secret[]);

View file

@ -0,0 +1,5 @@
{
"args": ["{test_case}.words"],
"has_stdin": true,
"capture_stdout": true
}

View file

@ -0,0 +1,23 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "hangman.h"
int main(int argc, char *argv[])
{
if (argc != 2) {
printf("Usage: %s path-to-wordlist\n", argv[0]);
return 1;
}
char secret[50];
srand(time(NULL));
if (get_word(argv[1], secret) != 0) {
return 1;
}
hangman(secret);
return 0;
}

Binary file not shown.

After

(image error) Size: 235 KiB

View file

@ -0,0 +1 @@
../../test-bonus.py

View file

@ -0,0 +1 @@
!*.words

View file

@ -0,0 +1,2 @@
o
word

View file

@ -0,0 +1,10 @@
Welcome to the game, Hangman!
I am thinking of a word that is 4 letters long.
-------------
You have 8 guesses left.
Available letters: abcdefghijklmnopqrstuvwxyz
Please guess a letter: Good guess: _ o _ _
-------------
You have 8 guesses left.
Available letters: abcdefghijklmnpqrstuvwxyz
Please guess a letter: Sorry, bad guess. The word was goal.

View file

@ -0,0 +1,3 @@
goal
goal
goal

View file

@ -0,0 +1,2 @@
e
ball

View file

@ -0,0 +1,10 @@
Welcome to the game, Hangman!
I am thinking of a word that is 4 letters long.
-------------
You have 8 guesses left.
Available letters: abcdefghijklmnopqrstuvwxyz
Please guess a letter: Oops! That letter is not in my word: _ _ _ _
-------------
You have 7 guesses left.
Available letters: abcdfghijklmnopqrstuvwxyz
Please guess a letter: Congratulations, you won!

View file

@ -0,0 +1,3 @@
ball
ball
ball

View file

@ -0,0 +1,16 @@
l
e
d
a
U
u
s
p
r

View file

@ -0,0 +1,40 @@
Welcome to the game, Hangman!
I am thinking of a word that is 7 letters long.
-------------
You have 8 guesses left.
Available letters: abcdefghijklmnopqrstuvwxyz
Please guess a letter: Good guess: _ _ _ _ l _ _
-------------
You have 8 guesses left.
Available letters: abcdefghijkmnopqrstuvwxyz
Please guess a letter: Good guess: _ _ _ _ l e _
-------------
You have 8 guesses left.
Available letters: abcdfghijkmnopqrstuvwxyz
Please guess a letter: Oops! That letter is not in my word: _ _ _ _ l e _
-------------
You have 7 guesses left.
Available letters: abcfghijkmnopqrstuvwxyz
Please guess a letter: Oops! That letter is not in my word: _ _ _ _ l e _
-------------
You have 6 guesses left.
Available letters: bcfghijkmnopqrstuvwxyz
Please guess a letter: Good guess: _ u _ _ l e _
-------------
You have 6 guesses left.
Available letters: bcfghijkmnopqrstvwxyz
Please guess a letter: Oops! You've already guessed that letter: _ u _ _ l e _
-------------
You have 6 guesses left.
Available letters: bcfghijkmnopqrstvwxyz
Please guess a letter: Good guess: _ u _ _ l e s
-------------
You have 6 guesses left.
Available letters: bcfghijkmnopqrtvwxyz
Please guess a letter: Good guess: p u _ p l e s
-------------
You have 6 guesses left.
Available letters: bcfghijkmnoqrtvwxyz
Please guess a letter: Good guess: p u r p l e s
-------------
Congratulations, you won!

View file

@ -0,0 +1,3 @@
purples
purples
purples

View file

@ -0,0 +1,11 @@
a
e
@
h
N
hangman

View file

@ -0,0 +1,26 @@
Welcome to the game, Hangman!
I am thinking of a word that is 7 letters long.
-------------
You have 8 guesses left.
Available letters: abcdefghijklmnopqrstuvwxyz
Please guess a letter: Good guess: _ a _ _ _ a _
-------------
You have 8 guesses left.
Available letters: bcdefghijklmnopqrstuvwxyz
Please guess a letter: Oops! That letter is not in my word: _ a _ _ _ a _
-------------
You have 7 guesses left.
Available letters: bcdfghijklmnopqrstuvwxyz
Please guess a letter: Oops! '@' is not a valid letter: _ a _ _ _ a _
-------------
You have 7 guesses left.
Available letters: bcdfghijklmnopqrstuvwxyz
Please guess a letter: Good guess: h a _ _ _ a _
-------------
You have 7 guesses left.
Available letters: bcdfgijklmnopqrstuvwxyz
Please guess a letter: Good guess: h a n _ _ a n
-------------
You have 7 guesses left.
Available letters: bcdfgijklmopqrstuvwxyz
Please guess a letter: Congratulations, you won!

View file

@ -0,0 +1,3 @@
hangman
hangman
hangman

View file

@ -0,0 +1,11 @@
a
e
b
c
q
w
p
l
m
x
z

View file

@ -0,0 +1,40 @@
Welcome to the game, Hangman!
I am thinking of a word that is 10 letters long.
-------------
You have 8 guesses left.
Available letters: abcdefghijklmnopqrstuvwxyz
Please guess a letter: Oops! That letter is not in my word: _ _ _ _ _ _ _ _ _ _
-------------
You have 7 guesses left.
Available letters: bcdefghijklmnopqrstuvwxyz
Please guess a letter: Good guess: _ _ _ e _ e _ _ e _
-------------
You have 7 guesses left.
Available letters: bcdfghijklmnopqrstuvwxyz
Please guess a letter: Oops! That letter is not in my word: _ _ _ e _ e _ _ e _
-------------
You have 6 guesses left.
Available letters: cdfghijklmnopqrstuvwxyz
Please guess a letter: Oops! That letter is not in my word: _ _ _ e _ e _ _ e _
-------------
You have 5 guesses left.
Available letters: dfghijklmnopqrstuvwxyz
Please guess a letter: Oops! That letter is not in my word: _ _ _ e _ e _ _ e _
-------------
You have 4 guesses left.
Available letters: dfghijklmnoprstuvwxyz
Please guess a letter: Oops! That letter is not in my word: _ _ _ e _ e _ _ e _
-------------
You have 3 guesses left.
Available letters: dfghijklmnoprstuvxyz
Please guess a letter: Oops! That letter is not in my word: _ _ _ e _ e _ _ e _
-------------
You have 2 guesses left.
Available letters: dfghijklmnorstuvxyz
Please guess a letter: Oops! That letter is not in my word: _ _ _ e _ e _ _ e _
-------------
You have 1 guesses left.
Available letters: dfghijkmnorstuvxyz
Please guess a letter: Oops! That letter is not in my word: _ _ _ e _ e _ _ e _
-------------
Sorry, you ran out of guesses. The word was undeserved.

View file

@ -0,0 +1,3 @@
undeserved
undeserved
undeserved

View file

@ -0,0 +1,4 @@
{
"args": [],
"capture_stdout": true
}

View file

@ -0,0 +1 @@
Usage: build/hangman path-to-wordlist

View file

@ -0,0 +1,64 @@
#include "hangman.h"
#include <stdbool.h>
#include <string.h>
#define CUT_MAIN
#include "cut.h"
TEST(word_guessed)
{
SUBTEST(example_not_guessed)
{
CHECK(!word_guessed("secret", "aeiou"));
}
SUBTEST(example_guessed)
{
CHECK(word_guessed("hi", "aeihoul"));
}
SUBTEST(multiple_letters)
{
CHECK(word_guessed("baba", "ba"));
}
}
TEST(censor_word)
{
SUBTEST(example)
{
char result[30];
censor_word("container", "arpstxgoieyu", result);
CHECK(strcmp(result, "_o_tai_er") == 0);
}
SUBTEST(bigger_example)
{
char result[30];
censor_word("underserved", "arpstxgoieyu", result);
CHECK(strcmp(result, "u__erser_e_") == 0);
}
}
TEST(get_available_letters)
{
SUBTEST(example)
{
char result[30];
get_available_letters("arpstxgoieyu", result);
CHECK(strcmp(result, "bcdfhjklmnqvwz") == 0);
}
SUBTEST(all) {
char result[30];
get_available_letters("", result);
CHECK(strcmp(result, "abcdefghijklmnopqrstuvwxyz") == 0);
}
SUBTEST(none) {
char result[30];
get_available_letters("abcdefghijklmnopqrstuvwxyz", result);
CHECK(strcmp(result, "") == 0);
}
}