0

I am trying to make my own WORDLE game with C++. I have gotten to the point where I can check if a character is in the right spot but I do not know how to check if a letter is in the word but in a different place. This is what I have so far:

#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#include <cstdlib>

using namespace std;

string pickword();
string checkword(string ans, string word);

int main() {
  string guess;
  cout << "Hi welcome to WORDLE\n\n*Hit enter to start*";
  cin.ignore();
  string word = pickword();
  cout << endl << word;
  cout << "\nEnter a 5-letter word: ";
  cin >> guess;
  checkword(guess, word);
}

string pickword() {
  srand((unsigned) time(NULL));
  int random = 1 + (rand() %  1999);
  string string;
  ifstream ReadFile;
  ReadFile.open("words.txt");
  for (int i = 1; i <= random; i++) {
        getline(ReadFile, string);
    }
  ReadFile.close();
  return string;
}

string checkword(string ans, string word) {
  char anslst[5];
  char wrdlst[5];
  for (int i = 0; i <= 4; i++) {
    anslst[i] = ans[i];
    wrdlst[i] = word[i];
  }
  //Green = \033[32m
  //Red = \033[31m
  //Yellow = \033[33m
  for (int i = 0; i <= 4; i++) {
    if (anslst[i] == wrdlst[i]) {
      cout << "\033[32m" << anslst[i];
    }
    else if (anslst[i] != wrdlst[i]) {
      cout << "\033[31m" << anslst[i];
    }
  }
  
  return word;
}

the part relevent to the question is the bottom of checkword(). how can I see if the letters in the player's guess are in the the list containing the letters of the answer?

Person
  • 21
  • 1
  • Tip: Use `std::string`. Remember `char[5]` holds *only* 4 characters. – tadman Dec 01 '22 at 00:57
  • could you elaborate? I am relatively new to c++ and don't really understand – Person Dec 01 '22 at 01:05
  • 1
    When representing a string with an array of characters it is mandatory to mark the end of the string with a null terminator. That's why you can only put 4 characters in 5 character array: One of the characters in the array will be used up by the terminator. – user4581301 Dec 01 '22 at 01:10
  • 1
    C strings are *extraordinarily fussy* because you must often be hyper aware of their internals. In this case `char[5]` has space for 4 characters, plus 1 byte reserved for the terminating NUL (0) byte. Every C string *must* be properly terminated, or many functions will just keep reading until they eventually hit a 0 by chance, creating buffer overflow bugs. C++ can avoid all of this by simply using `std::string` which has no such issues. As a bonus you can do all kinds of stuff like add them together, compare them with `==` and more. – tadman Dec 01 '22 at 01:12
  • Probably the coolest thing about `std::string` is you can `std::string c = a+b;` to glue `a` and `b` together. This is an adventure when using C-style strings, and it reaps the souls of an uncommonly large number of new C++ adventurers. – user4581301 Dec 01 '22 at 01:32

1 Answers1

0

This main problem you're faced with isn't so much a question about C++, but instead an algorithmic question of "what to do with repeated letters?" For example, my understanding of the rules of Wordle are that a guess of "APPLE" when the answer was "PASTE", your first "P" should be yellow, but your second "P" should be grey. But if the answer had been "SPIPE", then "APPLE"'s second "P" should be yellow (because its first "P" is now green).

If we were to extend your C++ example with some of the programming choices you've already made, the central part of your checkword() might be written something like this:

EResult result[5];
for (int i = 0; i <= 4; i++) {
    if (anslst[i] == wrdlst[i]) {
        result[i] = GREEN;
    }
    else {
        result[i] = GREY;
    }
}
for (int i = 0; i <= 4; i++) {
    if (result[i] != GREEN) {
        bool searchingForYellow = true;
        for (int j = 0; j <= 4 && searchingForYellow; j++) {
            if (result[j] == GREY && anslst[i] == wrdlst[j]) {
                result[j] = YELLOW;
                searchingForYellow = false;
            }
        }
    }
}
for (int i = 0; i <= 4; i++) {
    if (result[i] == GREEN) {
        cout << "\033[32m" << wrdlst[i];
    }
    else if (result[i] == YELLOW) {
        cout << "\033[33m" << wrdlst[i];
    }
    else { // GREY
        cout << "\033[31m" << wrdlst[i];
    }
}
    

Notice that I've assumed you have an enumeration type named EResult with values GREEN or YELLOW or GREY (I haven't defined that type in my example code). You might need to study a bit about C++ enumerations if that is a new concept for you. Also consider using a "switch" statement instead of the condition at the end (but I'm not sure if you're familiar with "switch", so I wrote it this way for you instead). Also, consider using a "break" statement instead of the boolean variable (but again, I'm not sure how familiar you are with that programming element).

Cow Corporation
  • 399
  • 2
  • 7
  • I watched a video about enumeration types but I am still a little confused. I put enum EResult { GREEN, YELLOW, GREY }; at the top of checkword() (underneath string wrdlst[5]) it seems to run smoothly until it outputs back the results. the word was sieve and I typed tieev to test all the scenarios and it output this "sievh�tieev�ᳫ�V�`2T�`@�'�d��`@��LN�`@�Ӕ%{�f��r+f���䳫`@�*`@����K��9�g�~��ҥ�꥙��"�-�@���9�s����� ��c�u�����볙���5������Ĵ� ���蹙��$�>�R�Y�n��signal: segmentation fault (core dumped)" – Person Dec 01 '22 at 02:32