Beispiel #1
0
void Dictionary::recursiveInteractive(Words const& active_words) const
{
	if (active_words.empty()) {
		puts("No choices remain.\n");
	} else if (active_words.size() == 1) {
		fputs("Only choice remaining is: ", stdout);
		describeWord(stdout, active_words.front());
		puts("\n");
	} else {
		printf("%u choices remain", static_cast<unsigned>(active_words.size()));
		if (active_words.size() <= 5) {
			// If we're near the end, print a list
			fputs(": ", stdout);
			auto it = active_words.cbegin();
			describeWord(stdout, *it);
			do {
				fputs(", ", stdout);
				describeWord(stdout, *it);
			} while (++it != active_words.cend());
			putchar('\n');
		} else {
			puts(".");
		}
		putchar('\n');

		string cmd;
		for (;;) {
			printInteractiveSuggestions(active_words);
			fputs("Give your move in form \"<word> <result>\" like \"TAXI 2\"\n\n"
			      "> ", stdout);
			fflush(stdout);
			if (!read_uppercase_word(stdin, &cmd))
				break;	// EOF
			Word tried;
			unsigned matched;
			if (parse_move(cmd, wordLength(), &tried, &matched)) {
				DividedWordList dl(wordLength());
				dl.build(*this, active_words, tried);
				recursiveInteractive(dl[matched].choices());
				break;
			}
			puts("Invalid move.\n");
		}
	}
}
Beispiel #2
0
void Dictionary::recursiveSolve(AbstractSolutionAcceptor * const acceptor, Words const& active_words, AnswerSequence * const runningAnswersp) const
{
	assert(!active_words.empty());
	if (active_words.size() == 1) {	// We found an end node
		acceptor->acceptSolution(*runningAnswersp, active_words.front());
	} else {
		DividedWordList dl(wordLength());
		double best_entropy = -1.0;
		Word best_word = 0;
		// Of all of the words in active_words, find the one that
		// will gives us the most even split (and thus the highest entropy)
		{
			auto it = keys_.cbegin();
			do {
				dl.build(*this, active_words, *it);
				double const entropy = dl.entropy();
				if (entropy > best_entropy) {
					best_entropy = entropy;
					best_word = *it;
				}
			} while (++it != keys_.cend());
		}
		assert(popcount32(best_word) == wordLength());
		// Now that we have found our best word, recompute the split
		dl.build(*this, active_words, best_word);
		assert(dl.entropy() == best_entropy);
		acceptor->acceptBranch(*runningAnswersp, best_word, best_entropy, dl);
		// Now recursively descend
		for (unsigned i = 0; i < wordLength() + 1; i++) {
			const WordsWithTotalChoices& wwtc = dl[i];
			if (wwtc.count() > 0) {
				runningAnswersp->push_back(i);
				recursiveSolve(acceptor, wwtc.choices(), runningAnswersp);
				runningAnswersp->pop_back();
			}
		}
	}
}