Refine question guessing mode
Update the question guessing mode to not reveal the number directly. Instead, it should grey out numbers that are eliminated by the user's answer.
This commit is contained in:
parent
ec168be51d
commit
b0595d1cc7
2 changed files with 86 additions and 16 deletions
|
|
@ -482,6 +482,7 @@ const GuessingGame: React.FC<GuessingGameProps> = ({ showSocialShare = true }) =
|
||||||
userGuess={userGuess}
|
userGuess={userGuess}
|
||||||
setUserGuess={setUserGuess}
|
setUserGuess={setUserGuess}
|
||||||
onGuess={handleGuess}
|
onGuess={handleGuess}
|
||||||
|
onUpdateValidNumbers={setValidNumbers}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ interface QuestionGuessingModeProps {
|
||||||
userGuess: string;
|
userGuess: string;
|
||||||
setUserGuess: (value: string) => void;
|
setUserGuess: (value: string) => void;
|
||||||
onGuess: (guessValue?: number) => void;
|
onGuess: (guessValue?: number) => void;
|
||||||
|
onUpdateValidNumbers: (newValidNumbers: Set<number>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QuestionGuessingMode: React.FC<QuestionGuessingModeProps> = ({
|
const QuestionGuessingMode: React.FC<QuestionGuessingModeProps> = ({
|
||||||
|
|
@ -24,14 +25,15 @@ const QuestionGuessingMode: React.FC<QuestionGuessingModeProps> = ({
|
||||||
validNumbers,
|
validNumbers,
|
||||||
userGuess,
|
userGuess,
|
||||||
setUserGuess,
|
setUserGuess,
|
||||||
onGuess
|
onGuess,
|
||||||
|
onUpdateValidNumbers
|
||||||
}) => {
|
}) => {
|
||||||
const [question, setQuestion] = useState('');
|
const [question, setQuestion] = useState('');
|
||||||
const [questionHistory, setQuestionHistory] = useState<{question: string, answer: string, understood: boolean}[]>([]);
|
const [questionHistory, setQuestionHistory] = useState<{question: string, answer: string, understood: boolean}[]>([]);
|
||||||
const [questionFeedback, setQuestionFeedback] = useState('');
|
const [questionFeedback, setQuestionFeedback] = useState('');
|
||||||
|
|
||||||
// Function to interpret and answer yes/no questions
|
// Function to interpret and answer yes/no questions without revealing the secret number
|
||||||
const interpretQuestion = (question: string, secretNumber: number): { understood: boolean, answer: boolean, explanation?: string } => {
|
const interpretQuestion = (question: string, secretNumber: number): { understood: boolean, answer: boolean, questionType?: string, value?: number } => {
|
||||||
const q = question.toLowerCase().trim();
|
const q = question.toLowerCase().trim();
|
||||||
|
|
||||||
// Remove question marks and normalize
|
// Remove question marks and normalize
|
||||||
|
|
@ -41,10 +43,10 @@ const QuestionGuessingMode: React.FC<QuestionGuessingModeProps> = ({
|
||||||
if (normalizedQ.includes('is') && normalizedQ.includes('number')) {
|
if (normalizedQ.includes('is') && normalizedQ.includes('number')) {
|
||||||
// Is the number...
|
// Is the number...
|
||||||
if (normalizedQ.includes('even')) {
|
if (normalizedQ.includes('even')) {
|
||||||
return { understood: true, answer: secretNumber % 2 === 0, explanation: `${secretNumber} is ${secretNumber % 2 === 0 ? 'even' : 'odd'}` };
|
return { understood: true, answer: secretNumber % 2 === 0, questionType: 'even' };
|
||||||
}
|
}
|
||||||
if (normalizedQ.includes('odd')) {
|
if (normalizedQ.includes('odd')) {
|
||||||
return { understood: true, answer: secretNumber % 2 !== 0, explanation: `${secretNumber} is ${secretNumber % 2 !== 0 ? 'odd' : 'even'}` };
|
return { understood: true, answer: secretNumber % 2 !== 0, questionType: 'odd' };
|
||||||
}
|
}
|
||||||
if (normalizedQ.includes('prime')) {
|
if (normalizedQ.includes('prime')) {
|
||||||
const isPrime = (num: number): boolean => {
|
const isPrime = (num: number): boolean => {
|
||||||
|
|
@ -55,11 +57,11 @@ const QuestionGuessingMode: React.FC<QuestionGuessingModeProps> = ({
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
const prime = isPrime(secretNumber);
|
const prime = isPrime(secretNumber);
|
||||||
return { understood: true, answer: prime, explanation: `${secretNumber} is ${prime ? 'prime' : 'not prime'}` };
|
return { understood: true, answer: prime, questionType: 'prime' };
|
||||||
}
|
}
|
||||||
if (normalizedQ.includes('perfect square')) {
|
if (normalizedQ.includes('perfect square')) {
|
||||||
const isPerfectSquare = Math.sqrt(secretNumber) % 1 === 0;
|
const isPerfectSquare = Math.sqrt(secretNumber) % 1 === 0;
|
||||||
return { understood: true, answer: isPerfectSquare, explanation: `${secretNumber} is ${isPerfectSquare ? 'a perfect square' : 'not a perfect square'}` };
|
return { understood: true, answer: isPerfectSquare, questionType: 'perfectSquare' };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,7 +71,7 @@ const QuestionGuessingMode: React.FC<QuestionGuessingModeProps> = ({
|
||||||
if (matches) {
|
if (matches) {
|
||||||
const divisor = parseInt(matches[1]);
|
const divisor = parseInt(matches[1]);
|
||||||
const isDivisible = secretNumber % divisor === 0;
|
const isDivisible = secretNumber % divisor === 0;
|
||||||
return { understood: true, answer: isDivisible, explanation: `${secretNumber} is ${isDivisible ? '' : 'not '}divisible by ${divisor}` };
|
return { understood: true, answer: isDivisible, questionType: 'divisible', value: divisor };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,7 +81,7 @@ const QuestionGuessingMode: React.FC<QuestionGuessingModeProps> = ({
|
||||||
if (matches) {
|
if (matches) {
|
||||||
const threshold = parseInt(matches[1]);
|
const threshold = parseInt(matches[1]);
|
||||||
const isGreater = secretNumber > threshold;
|
const isGreater = secretNumber > threshold;
|
||||||
return { understood: true, answer: isGreater, explanation: `${secretNumber} is ${isGreater ? 'greater than' : 'not greater than'} ${threshold}` };
|
return { understood: true, answer: isGreater, questionType: 'greaterThan', value: threshold };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,7 +90,7 @@ const QuestionGuessingMode: React.FC<QuestionGuessingModeProps> = ({
|
||||||
if (matches) {
|
if (matches) {
|
||||||
const threshold = parseInt(matches[1]);
|
const threshold = parseInt(matches[1]);
|
||||||
const isLess = secretNumber < threshold;
|
const isLess = secretNumber < threshold;
|
||||||
return { understood: true, answer: isLess, explanation: `${secretNumber} is ${isLess ? 'less than' : 'not less than'} ${threshold}` };
|
return { understood: true, answer: isLess, questionType: 'lessThan', value: threshold };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -98,7 +100,7 @@ const QuestionGuessingMode: React.FC<QuestionGuessingModeProps> = ({
|
||||||
if (matches) {
|
if (matches) {
|
||||||
const digit = matches[1];
|
const digit = matches[1];
|
||||||
const contains = secretNumber.toString().includes(digit);
|
const contains = secretNumber.toString().includes(digit);
|
||||||
return { understood: true, answer: contains, explanation: `${secretNumber} ${contains ? 'contains' : 'does not contain'} the digit ${digit}` };
|
return { understood: true, answer: contains, questionType: 'containsDigit', value: parseInt(digit) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -108,29 +110,96 @@ const QuestionGuessingMode: React.FC<QuestionGuessingModeProps> = ({
|
||||||
if (matches) {
|
if (matches) {
|
||||||
const num = parseInt(matches[1]);
|
const num = parseInt(matches[1]);
|
||||||
const isEqual = secretNumber === num;
|
const isEqual = secretNumber === num;
|
||||||
return { understood: true, answer: isEqual, explanation: `The number is ${secretNumber}, ${isEqual ? 'which is' : 'which is not'} ${num}` };
|
return { understood: true, answer: isEqual, questionType: 'equals', value: num };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { understood: false, answer: false };
|
return { understood: false, answer: false };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Function to update valid numbers based on question and answer
|
||||||
|
const updateValidNumbersFromQuestion = (questionType: string, answer: boolean, value?: number) => {
|
||||||
|
const newValidNumbers = new Set<number>();
|
||||||
|
|
||||||
|
for (let num = 1; num <= maxRange; num++) {
|
||||||
|
if (!validNumbers.has(num)) continue; // Skip already invalid numbers
|
||||||
|
|
||||||
|
let shouldKeep = false;
|
||||||
|
|
||||||
|
switch (questionType) {
|
||||||
|
case 'even':
|
||||||
|
shouldKeep = answer ? (num % 2 === 0) : (num % 2 !== 0);
|
||||||
|
break;
|
||||||
|
case 'odd':
|
||||||
|
shouldKeep = answer ? (num % 2 !== 0) : (num % 2 === 0);
|
||||||
|
break;
|
||||||
|
case 'prime':
|
||||||
|
const isPrimeNum = (n: number): boolean => {
|
||||||
|
if (n < 2) return false;
|
||||||
|
for (let i = 2; i <= Math.sqrt(n); i++) {
|
||||||
|
if (n % i === 0) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
shouldKeep = answer ? isPrimeNum(num) : !isPrimeNum(num);
|
||||||
|
break;
|
||||||
|
case 'perfectSquare':
|
||||||
|
const isPerfectSquareNum = Math.sqrt(num) % 1 === 0;
|
||||||
|
shouldKeep = answer ? isPerfectSquareNum : !isPerfectSquareNum;
|
||||||
|
break;
|
||||||
|
case 'divisible':
|
||||||
|
if (value !== undefined) {
|
||||||
|
shouldKeep = answer ? (num % value === 0) : (num % value !== 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'greaterThan':
|
||||||
|
if (value !== undefined) {
|
||||||
|
shouldKeep = answer ? (num > value) : (num <= value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'lessThan':
|
||||||
|
if (value !== undefined) {
|
||||||
|
shouldKeep = answer ? (num < value) : (num >= value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'containsDigit':
|
||||||
|
if (value !== undefined) {
|
||||||
|
shouldKeep = answer ? num.toString().includes(value.toString()) : !num.toString().includes(value.toString());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'equals':
|
||||||
|
if (value !== undefined) {
|
||||||
|
shouldKeep = answer ? (num === value) : (num !== value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
shouldKeep = true; // Keep all numbers if we don't understand the question type
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldKeep) {
|
||||||
|
newValidNumbers.add(num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onUpdateValidNumbers(newValidNumbers);
|
||||||
|
};
|
||||||
|
|
||||||
const handleQuestionSubmit = () => {
|
const handleQuestionSubmit = () => {
|
||||||
if (!question.trim()) return;
|
if (!question.trim()) return;
|
||||||
|
|
||||||
const result = interpretQuestion(question, secretNumber);
|
const result = interpretQuestion(question, secretNumber);
|
||||||
|
|
||||||
if (result.understood) {
|
if (result.understood && result.questionType) {
|
||||||
const answer = result.answer ? 'Yes' : 'No';
|
const answer = result.answer ? 'Yes' : 'No';
|
||||||
setQuestionHistory([...questionHistory, {
|
setQuestionHistory([...questionHistory, {
|
||||||
question: question,
|
question: question,
|
||||||
answer: answer + (result.explanation ? ` (${result.explanation})` : ''),
|
answer: answer,
|
||||||
understood: true
|
understood: true
|
||||||
}]);
|
}]);
|
||||||
setQuestionFeedback(`${answer}! ${result.explanation || ''}`);
|
setQuestionFeedback(answer);
|
||||||
|
|
||||||
// Update valid numbers based on the question and answer
|
// Update valid numbers based on the question and answer
|
||||||
// This is simplified - in a full implementation, you'd need to parse and apply the logic
|
updateValidNumbersFromQuestion(result.questionType, result.answer, result.value);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
setQuestionHistory([...questionHistory, {
|
setQuestionHistory([...questionHistory, {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue