Prolog实现Wordle游戏:循环校验有效词长与随机选词问题
Let's tackle your two Wordle implementation issues in Prolog one by one, with clear fixes and explanations:
1. Fixing the Loop for Valid Word Length Check
Your original check_length predicate has two key issues that break the loop logic:
- You're calling
read(WordLength)again insidecheck_length, even though you already read the input in theplaypredicate—this causes unexpected duplicate input prompts. - Using
available_length(WordLength) = trueis incorrect in Prolog: predicates succeed or fail natively; you don't need to compare them totrue.
Additionally, your current available_length doesn't account for the selected category (it checks all categories), which would lead to invalid lengths being accepted if they exist in another category. Let's fix all of this:
Step 1: Update the Length Validation to Respect the Category
First, redefine available_length to take the selected category as a parameter, so it only checks words in that category:
% Check if there exists a word of length Len in the given Category available_length(Category, Len) :- word(W, Category), atom_chars(W, Chars), length(Chars, Len).
Step 2: Rewrite the Loop Predicate
Modify check_length to accept the category and initial length as parameters. It will either succeed immediately (if valid) or prompt for a new input and recurse:
% Case 1: The entered length is valid—success check_length(Category, WordLength) :- available_length(Category, WordLength), !. % Cut avoids unnecessary backtracking % Case 2: Invalid length—prompt and recurse check_length(Category, _) :- write('There are no words with this length in the chosen category.'), nl, write('Choose a length: '), nl, read(NewWordLength), check_length(Category, NewWordLength).
Step 3: Update the play Predicate
Pass the selected category and initial length to check_length:
play:- write('The available categories are: animals, greetings, fruits, collections'), nl, write('Choose a category: '), nl, read(Category), nl, write('Choose a length: '), nl, read(WordLength), check_length(Category, WordLength), Guesses is WordLength + 1, write('Game started. You have '), write(Guesses), write(' guesses.'), % Add random word selection here (see next section) random_word(Category, TargetWord), nl, write('(For testing: Target word is '), write(TargetWord), write(')').
2. Implementing Random Word Selection
To pick a random word from the selected category, we'll first collect all words in that category into a list, then use Prolog's random library to select a member. This works in SWI-Prolog (the most common implementation):
Step 1: Import the Random Library
Add this at the top of your file to access random utilities:
:- use_module(library(random)).
Step 2: Collect Words by Category
Write a predicate to gather all unique words in the target category:
% Get a sorted list of all words in the given Category (sorted to avoid duplicates) category_words(Category, Words) :- findall(W, word(W, Category), RawWords), sort(RawWords, Words).
Step 3: Randomly Select a Word
Create a predicate that uses random_member/2 to pick a random word from the category list:
% Select a random word from the given Category random_word(Category, TargetWord) :- category_words(Category, Words), random_member(TargetWord, Words).
Now when you run play, after validating the length, it will select a random target word from the chosen category—perfect for Wordle!
内容的提问来源于stack exchange,提问作者User2000

