Refine Dogs and Bunny puzzle
Improve edge label spacing and add varied conditions.
This commit is contained in:
parent
f33b2bfa4f
commit
5e095857fe
1 changed files with 74 additions and 14 deletions
|
|
@ -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>
|
||||
);
|
||||
})}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue