feat: add gameInfo export with structured game instructions
- Export gameInfo object with complete game documentation - Includes controls (navigation, editing, deletion, hints, game) - Includes rules (cell types, modes, visual feedback) - Includes scoring (formula, penalties, multipliers, examples) - Includes game-over conditions - Includes hints system explanation - Structured for easy platform rendering - Fully typed with GameInfo type
This commit is contained in:
+158
@@ -0,0 +1,158 @@
|
||||
export const gameInfo = {
|
||||
name: 'VIM Sudoku',
|
||||
description: 'Classic Sudoku puzzle with VIM-style modal editing',
|
||||
|
||||
controls: {
|
||||
navigation: [
|
||||
{ keys: 'hjkl', description: 'Move cursor left/down/up/right' },
|
||||
{ keys: '5j, 10l', description: 'Move with count (5 down, 10 right)' },
|
||||
{ keys: '0 or ^', description: 'Jump to start of row' },
|
||||
{ keys: '$', description: 'Jump to end of row' },
|
||||
{ keys: 'gg', description: 'Jump to top of board' },
|
||||
{ keys: 'G', description: 'Jump to bottom of board' },
|
||||
{ keys: '.', description: 'Repeat last motion' },
|
||||
],
|
||||
|
||||
editing: [
|
||||
{ keys: 'i', description: 'Insert digit (works on empty cells only)' },
|
||||
{ keys: 'r', description: 'Replace digit (works on user-entered cells only)' },
|
||||
{ keys: 'c', description: 'Change digit (works on user-entered cells only)' },
|
||||
{ keys: '1-9', description: 'Enter digit (while in edit mode)' },
|
||||
{ keys: 'Escape', description: 'Exit edit mode to normal mode' },
|
||||
],
|
||||
|
||||
deletion: [
|
||||
{ keys: 'x', description: 'Delete digit from user-entered cell' },
|
||||
{ keys: 'd', description: 'Delete digit from user-entered cell' },
|
||||
{ keys: 'Delete', description: 'Delete digit from user-entered cell' },
|
||||
{ keys: 'Backspace', description: 'Delete digit (only in edit mode)' },
|
||||
],
|
||||
|
||||
hints: [
|
||||
{ keys: 'Shift+H', description: 'Request hint (costs 25/50/100 points by difficulty)' },
|
||||
],
|
||||
|
||||
game: [
|
||||
{ keys: 'Space', description: 'Start new game (when waiting)' },
|
||||
{ keys: 'q', description: 'Quit game' },
|
||||
{ keys: 'p', description: 'Pause/unpause game' },
|
||||
],
|
||||
},
|
||||
|
||||
rules: {
|
||||
cellTypes: [
|
||||
{ type: 'Empty', canEdit: 'i only', canReplace: 'no', canDelete: 'no', description: 'Empty cell ready for input' },
|
||||
{ type: 'User-entered', canEdit: 'r or c only', canReplace: 'yes', canDelete: 'yes', description: 'Digit you entered' },
|
||||
{ type: 'Given', canEdit: 'no', canReplace: 'no', canDelete: 'no', description: 'Original puzzle digit (locked)' },
|
||||
],
|
||||
|
||||
modes: [
|
||||
{
|
||||
name: 'Normal Mode',
|
||||
indicator: 'Blue outline on cursor',
|
||||
description: 'Navigate with hjkl, access all commands',
|
||||
},
|
||||
{
|
||||
name: 'Edit Mode (i)',
|
||||
indicator: 'Yellow pulsing glow on cursor',
|
||||
description: 'Type multiple digits, press Escape to exit',
|
||||
},
|
||||
{
|
||||
name: 'Edit Mode (r/c)',
|
||||
indicator: 'Yellow pulsing glow on cursor',
|
||||
description: 'Type one digit, auto-exits to normal mode',
|
||||
},
|
||||
],
|
||||
|
||||
visualFeedback: [
|
||||
{ indicator: 'Blue outline', meaning: 'Current cell in normal mode' },
|
||||
{ indicator: 'Yellow pulsing glow', meaning: 'Current cell in edit mode' },
|
||||
{ indicator: 'Red flash (500ms)', meaning: 'Invalid move or action' },
|
||||
{ indicator: 'Red flash + background (1s)', meaning: 'Hint: this cell is incorrect' },
|
||||
{ indicator: 'Green flash + background (1s)', meaning: 'Hint: showing correct digit' },
|
||||
],
|
||||
},
|
||||
|
||||
scoring: {
|
||||
formula: 'Base Score = 1000 - (time penalty) - (keystroke penalty) - (hint penalty)',
|
||||
multiplier: 'Final Score = min(1000, Base Score × difficulty multiplier)',
|
||||
range: '0 - 1000 points',
|
||||
|
||||
penalties: [
|
||||
{ factor: 'Time', formula: 'seconds / 10', example: '60 seconds = -6 points' },
|
||||
{ factor: 'Keystrokes', formula: 'total keys / 2', example: '100 keys = -50 points' },
|
||||
{ factor: 'Hints (Easy)', formula: 'hints × 25', example: '3 hints = -75 points' },
|
||||
{ factor: 'Hints (Medium)', formula: 'hints × 50', example: '3 hints = -150 points' },
|
||||
{ factor: 'Hints (Hard)', formula: 'hints × 100', example: '3 hints = -300 points' },
|
||||
],
|
||||
|
||||
multipliers: [
|
||||
{ difficulty: 'Easy', multiplier: '1.0x', description: 'No bonus' },
|
||||
{ difficulty: 'Medium', multiplier: '1.5x', description: 'Can exceed base 1000, capped at 1000' },
|
||||
{ difficulty: 'Hard', multiplier: '2.0x', description: 'Can exceed base 1000, capped at 1000' },
|
||||
],
|
||||
|
||||
examples: [
|
||||
{
|
||||
difficulty: 'Easy',
|
||||
time: '30 seconds',
|
||||
keystrokes: 50,
|
||||
hints: 0,
|
||||
calculation: '1000 - 3 - 25 - 0 = 972 × 1.0',
|
||||
score: '972 / 1000',
|
||||
},
|
||||
{
|
||||
difficulty: 'Hard',
|
||||
time: '120 seconds',
|
||||
keystrokes: 150,
|
||||
hints: 2,
|
||||
calculation: '1000 - 12 - 75 - 200 = 713 × 2.0',
|
||||
score: '1000 / 1000 (capped)',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
gameOver: {
|
||||
conditions: [
|
||||
{
|
||||
type: 'Time Limit',
|
||||
trigger: '10 minutes (600 seconds) by default',
|
||||
configurable: true,
|
||||
message: "Time's up!",
|
||||
},
|
||||
{
|
||||
type: 'Hint Limit',
|
||||
trigger: '500 points total hint penalty',
|
||||
breakdown: 'Easy: 20 hints | Medium: 10 hints | Hard: 5 hints',
|
||||
configurable: false,
|
||||
message: 'Too many hints!',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
hints: {
|
||||
description: 'Press Shift+H to get help when stuck',
|
||||
priority: [
|
||||
{
|
||||
level: 1,
|
||||
behavior: 'Show Incorrect Cell',
|
||||
description: 'Randomly select a user-entered cell with wrong value and flash it red for 1 second',
|
||||
reveals: 'Location of error (not the correct digit)',
|
||||
},
|
||||
{
|
||||
level: 2,
|
||||
behavior: 'Show Correct Digit',
|
||||
description: 'If no errors exist, show correct digit for a random empty cell with green flash for 1 second',
|
||||
reveals: 'Correct digit temporarily (you must remember it)',
|
||||
},
|
||||
],
|
||||
cost: 'Deducted from final score based on difficulty',
|
||||
limit: 'Game-over after 500 points of penalties',
|
||||
},
|
||||
|
||||
objective: 'Fill all empty cells with digits 1-9 such that each row, column, and 3×3 box contains each digit exactly once.',
|
||||
|
||||
winCondition: 'All cells filled correctly (no validation enforced - trust yourself!)',
|
||||
} as const;
|
||||
|
||||
export type GameInfo = typeof gameInfo;
|
||||
@@ -1,3 +1,5 @@
|
||||
export { useGame } from './useGame';
|
||||
export { useGameStatus } from './useGameStatus';
|
||||
export type { GameManager, GameOptions, GameStatus, GameStatusManager, Difficulty } from './types';
|
||||
export { gameInfo } from './gameInfo';
|
||||
export type { GameInfo } from './gameInfo';
|
||||
|
||||
Reference in New Issue
Block a user