summaryrefslogtreecommitdiff
path: root/wordle.c
diff options
context:
space:
mode:
Diffstat (limited to 'wordle.c')
-rw-r--r--wordle.c219
1 files changed, 219 insertions, 0 deletions
diff --git a/wordle.c b/wordle.c
new file mode 100644
index 0000000..c98ffde
--- /dev/null
+++ b/wordle.c
@@ -0,0 +1,219 @@
+//TODO: Quordle mode, multiple different length words
+/** Making my own version/clone of the popular "wordle" game. hello
+ * This is more of a way to help me solidfy my knowledge of
+ * programming and the C programming language than it is to
+ * actually play the game, but hopefully in the end this game
+ * pulls it weight in entertainment value.
+ */
+#include <stdio.h> //FILE,printf(),fopen(),fclose(),fgets()
+#include <assert.h> //assert()
+#include <stdlib.h> //rand(),srand(),system()
+#include <time.h> //time()
+#include <string.h> //strncpy()
+#include <inttypes.h> //strtoimax(), int8_t
+
+
+#define LARGEDICT 8939
+#define WORDLEN 5
+//#define DEBUG
+#ifdef DEBUG
+#define SMALLDICT 3
+static const char* SMALLFILE = "test_file";
+#endif
+#ifndef DEBUG
+#define SMALLDICT 3858
+static const char* SMALLFILE = "small_dict";
+#endif
+
+static const char* LARGEFILE = "large_dict";
+static const char* GAMESPLAYED = "games_played";
+static const char* TOTALWINS = "total_wins";
+static const char* WINSTREAK = "win_streak";
+
+int main(void)
+{
+ //Open file and make sure it exists
+ FILE* larger_dict_fptr = fopen(LARGEFILE, "r");
+ FILE* smaller_dict_fptr = fopen(SMALLFILE, "r");
+ assert(larger_dict_fptr != NULL && "File pointer returned NULL, make sure file exists and is spelled correctly");
+ assert(smaller_dict_fptr != NULL && "File pointer returned NULL, make sure file exists and is spelled correctly");
+
+
+ //Get words from both game (SMALL) and user (LARGE) dictionary and store them in two, two dimensional arrays,
+ //then strip the newline character, when done close the file
+ char larger_word_array[LARGEDICT][WORDLEN + 2]; //plus 2 to account for newline character and null character added by fgets
+ char smaller_word_array[SMALLDICT][WORDLEN + 2];
+
+ for (int i = 0; i < LARGEDICT; ++i) {
+ if (fgets(larger_word_array[i], WORDLEN + 2, larger_dict_fptr) != NULL) { // added 2 to WORDLEN because fgets starts where it left off before
+ assert(larger_word_array[i][WORDLEN+1] == '\0' && "word_array is not holding the characters that it is supposed to");
+ larger_word_array[i][WORDLEN] = '\0';
+ }
+ }
+ fclose(larger_dict_fptr);
+
+ for (int i = 0; i < SMALLDICT; ++i) {
+ if (fgets(smaller_word_array[i], WORDLEN + 2, smaller_dict_fptr) != NULL) { // added 2 to WORDLEN because fgets starts where it left off before
+ assert(smaller_word_array[i][WORDLEN+1] == '\0' && "word_array is not holding the characters that it is supposed to");
+ smaller_word_array[i][WORDLEN] = '\0';
+ }
+ }
+ fclose(smaller_dict_fptr);
+
+
+ //Get random number then store the word in that position in the array to be used for the game
+ char chosen_word[WORDLEN + 1];
+ srand(time(0));
+ int random_num = rand() % SMALLDICT;
+ strncpy(chosen_word, smaller_word_array[random_num], WORDLEN);
+
+ //Finds the number of duplicate letters in word and stores in corresponding array at same location
+ short int chosen_duplicates[5] = {0,0,0,0,0};
+ for (int i = WORDLEN - 1; i > 0; --i) {
+ for (int j = i - 1; j >= 0; --j) {
+ if (chosen_word[i] == chosen_word[j]) {
+ chosen_duplicates[i]++;
+ }
+ }
+ }
+
+ //Prepare for user input and let them know they can start playing
+ system("clear");
+ printf("You can now start making your guesses below.\n\n");
+
+#ifdef DEBUG
+ printf("\n\nword is: %s\n\n", chosen_word);
+#endif
+
+
+ //Play game until they win or lose
+ int8_t tries = 0, count = 0, is_a_word = 0, guess_duplicates[5] = {0,0,0,0,0}; //used int8_t intead of using char to store a very small # for clarity
+ int number_of_letters = 0;
+ char guess_word[WORDLEN+1];
+
+ while (count != 5 && tries != 6) {
+A:
+ count = 0;
+ is_a_word = 0;
+ number_of_letters = 0;
+
+ fflush(stdin); //Undefined behavior, but it fixed my problem (maybe while getchar or something later, when less lazy)
+ printf("%d: ", tries + 1);
+ scanf("%6s%n",guess_word, &number_of_letters);
+
+ //check length of input to make sure it is good
+ if (number_of_letters != (WORDLEN)) {
+ printf("Word is not five letters in length. Please try again.\n");
+ goto A;
+ }
+
+ for (int i = 0; i < LARGEDICT; ++i) {
+ if (!strcmp(guess_word, larger_word_array[i])) {
+ is_a_word = 1;
+ }
+ }
+
+ if (!is_a_word) {
+ printf("Not a valid word, try again.\n");
+ goto A;
+ }
+
+
+ //Finds the number of duplicate letters in word and stores in corresponding array at same location
+ for (int i = WORDLEN - 1; i > 0; --i) {
+ for (int j = i - 1; j >= 0; --j) {
+ if (guess_word[i] == guess_word[j]) {
+ guess_duplicates[i]++;
+ }
+ }
+ }
+
+ printf(" ");
+
+ //prints the corresponding symbol depending on if the letter is correct, in the wrong spot or neither
+ for (int i = 0; i < WORDLEN; i++) {
+ for (int j = 0; j < WORDLEN; j++) {
+ if ( guess_word[i] == chosen_word[i] ) {
+ printf("$");
+ ++count;
+ break;
+ } else if ( guess_word[i] == chosen_word[j] ) {
+ if ( !guess_duplicates[i] && guess_word[j] != chosen_word[j]) {
+ printf("*");
+ break;
+ } else {
+ --guess_duplicates[i];
+ }
+ } else if ( j == (WORDLEN - 1) ) {
+ printf("_");
+ }
+ }
+ }
+
+ ++tries;
+ printf("\n\n\n");
+ }
+
+ //open three files, that hold information about the total games played, the total wins, and the current win streak and make sure they opened correctly
+ FILE* win_streak_fptr = fopen(WINSTREAK, "r+");
+ FILE* total_wins_fptr = fopen(TOTALWINS, "r+");
+ FILE* total_games_fptr = fopen(GAMESPLAYED, "r+");
+ assert(win_streak_fptr != NULL && "File pointer returned NULL, make sure file exists and is spelled correctly");
+ assert(total_wins_fptr != NULL && "File pointer returned NULL, make sure file exists and is spelled correctly");
+ assert(total_games_fptr != NULL && "File pointer returned NULL, make sure file exists and is spelled correctly");
+
+
+ //increment total in total_games by one
+ //if you won, print so, add one to current win streak, and total games won
+ //if you lost, reset win streak total to 0
+ //calculate win percentage from total wins divided by total games times 100
+ //total games, total wins, win streak, win percentage (double)
+ char file_strings[3][11];
+ long int file_ints[3];
+ double win_percentage;
+ char* endptr;
+ enum whichFIle {winStreak = 0, totalWins = 1, totalGames = 2};
+
+ fscanf(win_streak_fptr, "%10s", file_strings[winStreak]);
+ fscanf(total_wins_fptr, "%10s", file_strings[totalWins]);
+ fscanf(total_games_fptr, "%10s", file_strings[totalGames]);
+
+ file_ints[winStreak] = strtoimax(file_strings[winStreak],&endptr,10);
+ file_ints[totalWins] = strtoimax(file_strings[totalWins],&endptr,10);
+ file_ints[totalGames] = strtoimax(file_strings[totalGames],&endptr,10);
+
+
+ file_ints[totalGames] += 1;
+
+ if (count == 5) {
+ file_ints[winStreak] += 1;
+ file_ints[totalWins] += 1;
+ printf("You won!\n");
+ } else {
+ printf("You Lost!\n");
+ printf("The word was: %s.\n",chosen_word);
+ file_ints[winStreak] = 0;
+ }
+
+ win_percentage = ( (double) file_ints[totalWins] / (double) file_ints[totalGames] ) * 100;
+
+ printf("Your winnning streak is: %ld\nYour winning percentage is: %.2lf\n", file_ints[winStreak], win_percentage);
+
+ //Return all the values back to their corresponding files and close up shop
+ fseek(win_streak_fptr, 0, SEEK_SET);
+ fseek(total_games_fptr, 0, SEEK_SET);
+ fseek(total_wins_fptr, 0, SEEK_SET);
+
+ fprintf(win_streak_fptr, "%ld\n", file_ints[winStreak]);
+ fprintf(total_games_fptr, "%ld\n", file_ints[totalGames]);
+ fprintf(total_wins_fptr, "%ld\n", file_ints[totalWins]);
+
+ fflush(win_streak_fptr);
+ fflush(total_games_fptr);
+ fflush(total_wins_fptr);
+
+ fclose(win_streak_fptr);
+ fclose(total_games_fptr);
+ fclose(total_wins_fptr);
+ return 0;
+}