Refine Dogs and Bunny puzzle

Improve edge label spacing and add varied conditions.
This commit is contained in:
gpt-engineer-app[bot] 2025-08-10 05:53:01 +00:00
parent f33b2bfa4f
commit 5e095857fe

View file

@ -73,6 +73,7 @@ const DogsBunnyPuzzle: React.FC<DogsBunnyPuzzleProps> = ({
// Generate edges with conditions based on difficulty
const edges: Edge[] = [];
const locationTypes = ['carrot', 'bone', 'flower', 'well', 'bunny', 'dog'];
const conditionPrefixes = ['SOMEBODY AT', 'NOBODY AT'];
// Connect all locations with conditional edges
for (let i = 0; i < locations.length; i++) {
@ -82,7 +83,8 @@ const DogsBunnyPuzzle: React.FC<DogsBunnyPuzzleProps> = ({
for (let k = 0; k < numConditions; k++) {
const conditionType = locationTypes[Math.floor(rng() * locationTypes.length)];
conditions.push(`SOMEBODY AT ${conditionType.toUpperCase()}`);
const prefix = conditionPrefixes[Math.floor(rng() * conditionPrefixes.length)];
conditions.push(`${prefix} ${conditionType.toUpperCase()}`);
}
edges.push({
@ -137,16 +139,18 @@ const DogsBunnyPuzzle: React.FC<DogsBunnyPuzzleProps> = ({
const parts = condition.split(' AT ');
if (parts.length !== 2) return false;
const isNobody = parts[0] === 'NOBODY';
const targetType = parts[1].toLowerCase();
// Check if somebody is at the specified location type
return puzzleState.characters.some(char => {
const hasCharacterAtType = puzzleState.characters.some(char => {
const location = puzzleState.locations.find(loc => loc.id === char.locationId);
return location && (
location.type === targetType ||
char.type === targetType
);
});
return isNobody ? !hasCharacterAtType : hasCharacterAtType;
});
};
@ -290,6 +294,27 @@ const DogsBunnyPuzzle: React.FC<DogsBunnyPuzzleProps> = ({
}
};
// Get condition icon
const getConditionIcon = (condition: string) => {
if (condition.includes('CARROT')) return '🥕';
if (condition.includes('BONE')) return '🦴';
if (condition.includes('FLOWER')) return '🌸';
if (condition.includes('WELL')) return '🪣';
if (condition.includes('BUNNY')) return '🐰';
if (condition.includes('DOG')) return '🐕';
return '❓';
};
// Format condition text for tooltip
const formatCondition = (condition: string) => {
const parts = condition.split(' AT ');
if (parts.length !== 2) return condition;
const prefix = parts[0] === 'NOBODY' ? 'Nobody at' : 'Someone at';
const target = parts[1].toLowerCase();
return `${prefix} ${target}`;
};
if (!puzzleState) return <div>Loading...</div>;
return (
@ -344,17 +369,52 @@ const DogsBunnyPuzzle: React.FC<DogsBunnyPuzzleProps> = ({
strokeWidth={isValid ? "3" : "1"}
strokeDasharray={isValid ? "none" : "5,5"}
/>
{/* Condition labels */}
{/* Condition icons */}
{edge.conditions.slice(0, 2).map((condition, condIndex) => (
<g key={condIndex}>
<circle
cx={(fromLoc.x + toLoc.x) / 2 + 20 + (condIndex - 0.5) * 16}
cy={(fromLoc.y + toLoc.y) / 2 + 20}
r="8"
fill="hsl(var(--background))"
stroke="hsl(var(--border))"
strokeWidth="1"
/>
<text
x={(fromLoc.x + toLoc.x) / 2 + 20}
y={(fromLoc.y + toLoc.y) / 2 + 15}
x={(fromLoc.x + toLoc.x) / 2 + 20 + (condIndex - 0.5) * 16}
y={(fromLoc.y + toLoc.y) / 2 + 25}
fontSize="10"
fill="hsl(var(--foreground))"
textAnchor="middle"
className="pointer-events-none"
>
{edge.conditions.length > 0 && edge.conditions[0].replace('SOMEBODY AT ', '')}
{condition.includes('NOBODY') ? '❌' : ''}
{getConditionIcon(condition)}
</text>
<title>{formatCondition(condition)}</title>
</g>
))}
{edge.conditions.length > 2 && (
<g>
<circle
cx={(fromLoc.x + toLoc.x) / 2 + 20 + 16}
cy={(fromLoc.y + toLoc.y) / 2 + 20}
r="6"
fill="hsl(var(--muted))"
stroke="hsl(var(--border))"
strokeWidth="1"
/>
<text
x={(fromLoc.x + toLoc.x) / 2 + 20 + 16}
y={(fromLoc.y + toLoc.y) / 2 + 24}
fontSize="8"
textAnchor="middle"
className="pointer-events-none"
>
+{edge.conditions.length - 2}
</text>
<title>{edge.conditions.slice(2).map(formatCondition).join(', ')}</title>
</g>
)}
</g>
);
})}