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
|
// Generate edges with conditions based on difficulty
|
||||||
const edges: Edge[] = [];
|
const edges: Edge[] = [];
|
||||||
const locationTypes = ['carrot', 'bone', 'flower', 'well', 'bunny', 'dog'];
|
const locationTypes = ['carrot', 'bone', 'flower', 'well', 'bunny', 'dog'];
|
||||||
|
const conditionPrefixes = ['SOMEBODY AT', 'NOBODY AT'];
|
||||||
|
|
||||||
// Connect all locations with conditional edges
|
// Connect all locations with conditional edges
|
||||||
for (let i = 0; i < locations.length; i++) {
|
for (let i = 0; i < locations.length; i++) {
|
||||||
|
|
@ -82,7 +83,8 @@ const DogsBunnyPuzzle: React.FC<DogsBunnyPuzzleProps> = ({
|
||||||
|
|
||||||
for (let k = 0; k < numConditions; k++) {
|
for (let k = 0; k < numConditions; k++) {
|
||||||
const conditionType = locationTypes[Math.floor(rng() * locationTypes.length)];
|
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({
|
edges.push({
|
||||||
|
|
@ -137,16 +139,18 @@ const DogsBunnyPuzzle: React.FC<DogsBunnyPuzzleProps> = ({
|
||||||
const parts = condition.split(' AT ');
|
const parts = condition.split(' AT ');
|
||||||
if (parts.length !== 2) return false;
|
if (parts.length !== 2) return false;
|
||||||
|
|
||||||
|
const isNobody = parts[0] === 'NOBODY';
|
||||||
const targetType = parts[1].toLowerCase();
|
const targetType = parts[1].toLowerCase();
|
||||||
|
|
||||||
// Check if somebody is at the specified location type
|
const hasCharacterAtType = puzzleState.characters.some(char => {
|
||||||
return puzzleState.characters.some(char => {
|
|
||||||
const location = puzzleState.locations.find(loc => loc.id === char.locationId);
|
const location = puzzleState.locations.find(loc => loc.id === char.locationId);
|
||||||
return location && (
|
return location && (
|
||||||
location.type === targetType ||
|
location.type === targetType ||
|
||||||
char.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>;
|
if (!puzzleState) return <div>Loading...</div>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -344,17 +369,52 @@ const DogsBunnyPuzzle: React.FC<DogsBunnyPuzzleProps> = ({
|
||||||
strokeWidth={isValid ? "3" : "1"}
|
strokeWidth={isValid ? "3" : "1"}
|
||||||
strokeDasharray={isValid ? "none" : "5,5"}
|
strokeDasharray={isValid ? "none" : "5,5"}
|
||||||
/>
|
/>
|
||||||
{/* Condition labels */}
|
{/* Condition icons */}
|
||||||
<text
|
{edge.conditions.slice(0, 2).map((condition, condIndex) => (
|
||||||
x={(fromLoc.x + toLoc.x) / 2 + 20}
|
<g key={condIndex}>
|
||||||
y={(fromLoc.y + toLoc.y) / 2 + 15}
|
<circle
|
||||||
fontSize="10"
|
cx={(fromLoc.x + toLoc.x) / 2 + 20 + (condIndex - 0.5) * 16}
|
||||||
fill="hsl(var(--foreground))"
|
cy={(fromLoc.y + toLoc.y) / 2 + 20}
|
||||||
textAnchor="middle"
|
r="8"
|
||||||
className="pointer-events-none"
|
fill="hsl(var(--background))"
|
||||||
>
|
stroke="hsl(var(--border))"
|
||||||
{edge.conditions.length > 0 && edge.conditions[0].replace('SOMEBODY AT ', '')}
|
strokeWidth="1"
|
||||||
</text>
|
/>
|
||||||
|
<text
|
||||||
|
x={(fromLoc.x + toLoc.x) / 2 + 20 + (condIndex - 0.5) * 16}
|
||||||
|
y={(fromLoc.y + toLoc.y) / 2 + 25}
|
||||||
|
fontSize="10"
|
||||||
|
textAnchor="middle"
|
||||||
|
className="pointer-events-none"
|
||||||
|
>
|
||||||
|
{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>
|
</g>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue