You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

字母拼词游戏开发:如何利用ofstream防止重复输入正确单词?

Fixing Duplicate Word Submissions in Your Word Seeker Game

Hey there! Let's sort out that duplicate word problem you're facing. Right now, you're writing valid words to trial.txt but not verifying if the player has already used that word before accepting it. Here's a straightforward, efficient way to fix this:

Step 1: Track Used Words in Memory

Instead of relying on the file to check duplicates (which is slow and clunky), use an in-memory container like std::unordered_set<std::string>—it lets you check if a word exists in O(1) time. Add this declaration at the top of your start() function:

#include <unordered_set> // Don't forget to include this header!
#include <string>        // For std::string

void start() {
    std::unordered_set<std::string> usedWords; // Tracks words the player has already submitted
    char ch;
    // ... rest of your code
}

Step 2: Add Duplicate Check Before Validating the Word

When the player enters a word, first check if it's already in usedWords. If it is, prompt them to enter a new word. If not, proceed to validate it against your word list, then add it to the set and your output file.

Here's how to modify your input handling block:

cout << "\tEnter word: ";
cin >> a;
std::string inputWord(a); // Convert char array to std::string for easier handling

// Check if word is already used
if (usedWords.find(inputWord) != usedWords.end()) {
    cout << "You've already used this word! Try another one.\n";
    delay(1000);
    continue; // Skip the rest of the loop and ask for a new word
}

// Now validate the word against your lvl1.txt
ifstream fin("lvl1.txt");
if (fin.fail()) {
    cout << "File doesn't exist!";
    exit(1);
}

bool isValid = false;
int wordScore = 0;
std::string dictWord;
int dictScore;

while (fin >> dictWord >> dictScore) {
    if (dictWord == inputWord) {
        isValid = true;
        wordScore = dictScore;
        break;
    }
}

fin.close();

if (!isValid) {
    cout << "Incorrect! Try Again!";
    delay(1000);
    continue;
}

// If we get here, the word is valid and new
usedWords.insert(inputWord); // Add to used set
sum += wordScore;

// Append to trial.txt (use ios::app to avoid overwriting the file)
ofstream fout("trial.txt", ios::app);
if (fout.fail()) {
    cout << "Output file opening failed.\n";
} else {
    fout << inputWord << "\n"; // Write each word on a new line for readability
    fout.close();
}

Step 3: Bonus Optimizations

  • Preload the Dictionary: Instead of opening lvl1.txt every time the player enters a word, load all valid words and their scores into a std::unordered_map<std::string, int> at the start of the game. This will make validation much faster.
  • Fix the File Overwrite Issue: Your original code opens trial.txt without ios::app, which erases the file every time. Using ios::app ensures valid words are appended instead of overwritten.
  • Case Insensitivity: If you want to treat "Bast" and "bast" as the same word, convert the input to lowercase (or uppercase) before checking against the dictionary and used set.

Modified Full Code Snippet (Key Sections)

Here's how the updated start() function would look with these changes:

#include <iostream>
#include <fstream>
#include <cstring>
#include <ctime>
#include <unordered_set>
#include <string>
#include <conio.h> // Assuming you're using clrscr() and delay() from conio.h

using namespace std;

void start() {
    char ch;
    do {
        clrscr();
        time_t start = time(nullptr);
        char arr[10][50] = {" B A N S E T ", " R E D G A E ", " S A H L E S ", " P R G N I S ", " A L E R L Y ", " L A C S A U ", " A C Q U K Y ", " M B L U E J ", " Z E D Z U B ", " L E A Z D Z "};
        int i = 0, sum = 0, x;
        unordered_set<string> usedWords;

        while (i != 2) {
            clrscr();
            sum = 0;
            do {
                clrscr();
                cout << "\t**********************************************\n";
                cout << "\t* W O R D S E E K E R *\n";
                cout << "\t**********************************************\n";
                cout << "\n\t\t\t\t\t SCORE: " << sum << " /50 pts" << "\n ******************************\n";
                cout << " * " << arr[i] << " *\n";
                cout << " ******************************\n\n";
                cout << " 6 letter=10pts, 5 letter=8pts, 4 letters=6pts, 3 letter=4pts\n\n";

                char a[20];
                cout << "\tEnter word: ";
                cin >> a;
                string inputWord(a);

                // Check for duplicate
                if (usedWords.count(inputWord)) {
                    cout << "Duplicate word! Try another.\n";
                    delay(1000);
                    continue;
                }

                // Validate word
                ifstream fin("lvl1.txt");
                if (fin.fail()) {
                    cout << "File doesn't exist!";
                    exit(1);
                }

                bool isValid = false;
                int wordScore = 0;
                string dictWord;
                int dictScore;

                while (fin >> dictWord >> dictScore) {
                    if (dictWord == inputWord) {
                        isValid = true;
                        wordScore = dictScore;
                        break;
                    }
                }
                fin.close();

                if (!isValid) {
                    cout << "Incorrect! Try Again!";
                    delay(1000);
                    continue;
                }

                // Update score and used words
                sum += wordScore;
                usedWords.insert(inputWord);

                // Write to trial.txt
                ofstream fout("trial.txt", ios::app);
                if (!fout.fail()) {
                    fout << inputWord << "\n";
                    fout.close();
                }

            } while (sum < 50);
            i++;
        }

        x = time(nullptr) - start;
        cout << "\n\tGood Job! Your time is " << x << " seconds\n";
        cout << "\tDo you want to continue?(Y/N): ";
        cin >> ch;

    } while (ch != 'n' && ch != 'N'); // Fixed the condition here! Original was using || which would loop forever
}

A quick note: I fixed the loop condition at the end (ch != 'n' && ch != 'N')—your original code used ||, which would make the loop run forever no matter what input the user gave.

内容的提问来源于stack exchange,提问作者SmashMyKeyboard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 06:36:48