diff --git a/README.md b/README.md index 029a05b..07370c8 100644 --- a/README.md +++ b/README.md @@ -24,10 +24,38 @@ t3core-cli - Two-player Tic Tac Toe in the terminal - Interactive menu with settings -- Colored symbols and styled board +- Optional arrow-key navigation in interactive terminals +- Colored symbols and styled board, with styling toggle +- Sound toggle and reset-to-default settings +- Move history view and rollback support +- Optional game info panel - Win and draw detection - Play again prompt +## Controls + +### Menu + +- `1` starts a new game. +- `2` opens settings. +- `3` exits. + +### Game + +- Enter a field number from `1` to `9` to place a move. +- When arrow-key navigation is enabled, use arrow keys to choose a field and `Enter` to confirm. +- Press `h` to show or hide move history after at least one move. +- Press `i` to show or hide game info. +- Press `q` to return to the main menu. In arrow-key mode, `Esc` and `Backspace` also return to the menu. + +### Settings + +- `1` toggles sound. +- `2` toggles styling. +- `3` toggles arrow-key navigation when the terminal supports it and styling is enabled. +- `4` resets settings to default. +- Press `q` to return to the main menu. In arrow-key mode, `Esc` and `Backspace` also return to the menu. + ## Requirements - Node.js >= 16.0.0 diff --git a/_plans/board-ui-upgrade.md b/_plans/board-ui-upgrade.md deleted file mode 100644 index 5cced7e..0000000 --- a/_plans/board-ui-upgrade.md +++ /dev/null @@ -1,93 +0,0 @@ -# Board UI Upgrade — Unicode + Arrow Key Navigation - -Upgrade planszy do Unicode box-drawing i zastąpienie wpisywania numeru nawigacją strzałkami + Enter, bez żadnych nowych zależności. - ---- - -## Nowe paczki npm (propozycja) - -### Do rozważenia teraz - -| Paczka | Wersja | Rozmiar | Po co | -|--------|--------|---------|-------| -| `nanospinner` | `^1.1.0` | ~20 kB, 0 deps | Spinner podczas ładowania/resetu gry | - -``` -yarn add nanospinner -``` - -### Do rozważenia w przyszłości — pełny rebuild na `ink` - -> **Notatka o `ink`** — React dla terminala ([github.com/vadimdemedes/ink](https://github.com/vadimdemedes/ink)) -> -> Ink pozwala budować interaktywne CLI używając komponentów React + hooków. Używa **Yoga** (Flexbox engine od Meta) do layoutu. -> Używają go: Claude Code, Gemini CLI, GitHub Copilot CLI, Cloudflare Wrangler, Gatsby, Prisma, Shopify CLI. -> -> **Instalacja:** `npm install ink react` -> -> **Kluczowe API:** -> -> - `` — kolorowanie tekstu (zastępuje `styledLabel.ts`) -> - `` — layout Flexbox w terminalu -> - `useInput(handler)` — hook na klawisze (strzałki, Enter, q) — **zastąpiłby cały `arrowKeyInput.ts`** -> - `useFocus()` / `useFocusManager()` — focus między polami planszy -> - `useApp()` — `exit()` zamiast `process.exit(0)` -> -> **Co by oznaczało przepisanie na ink:** -> -> - Cały obecny kod UI (`Header.ts`, `Board.ts`, `MenuOptions.ts`, itd.) → komponenty React `.tsx` -> - `UserInput.ts` (readline) → `useInput` hook -> - `styledLabel.ts` → `` z props kolorów -> - `navigateTo` / routing → `useState` w root komponencie -> - Wymaga: zmiana `tsconfig.json` (JSX), dodanie `react` + `@types/react`, przepisanie `tsup.config.ts` -> - Projekt przechodzi z `"type": "commonjs"` na ESM (ink v5 jest ESM-only) -> -> **Wniosek:** Duży refactor (~całe `src/`), ale efekt: deklaratywny, testowalny UI z `ink testing library`. -> Warto rozważyć przy kolejnym major release (v2.0). - ---- - -## Zakres zmian (obecny plan — bez ink) - -### 2. Nawigacja strzałkami — nowy util `arrowKeyInput.ts` - -Nowy plik: `src/features/game/components/PlayerEntry/utils/arrowKeyInput.ts` - -Mechanizm (Node.js stdlib only): - -1. `readline.emitKeypressEvents(process.stdin)` -2. `process.stdin.setRawMode(true)` — przechwytuje klawisze surowo -3. Listener na `keypress`: - - `↑ ↓ ← →` — przesuwa kursor po siatce 3x3 (mod 3 dla wierszy/kolumn) - - `Enter` / `Space` — zatwierdza wybrane pole - - `q` — wróć do menu - - `h` — historia (jeśli movesCount > 0) -4. Po każdym ruchu: `\x1b[{n}A` (move cursor up) + przerysowanie planszy z nowym podświetleniem -5. `process.stdin.setRawMode(false)` + cleanup po zatwierdzeniu - -**Zwraca:** `Promise` — ten sam interface co obecne `getPlayerAnswer` - ---- - -### 3. Podmiana wejścia w `PlayerEntry.ts` - -`getPlayerAnswer()` → `arrowKeyInput()` w `PlayerEntry.ts`. - -Usunięcie tekstu "Select the number of the field (1-9)" — zastąpienie wskazówką: `"Use arrow keys, Enter to confirm"`. - -**Pliki:** `src/features/game/components/PlayerEntry/PlayerEntry.ts` - ---- - -### 4. Tryb fallback - -Jeśli `settings.style === false` — zostaje obecna plansza tekstowa i wpisywanie numeru (bez raw mode). -Opcjonalnie: nowy toggle `settings.arrows` w `settings.global.ts`. - ---- - -## Ryzyko / uwagi - -- `setRawMode` nie działa w środowiskach bez TTY (CI, pipe) — wymagany guard `process.stdin.isTTY` -- Przerysowanie planszy w miejscu: używamy `\x1b[{n}A` zamiast `console.clear()` żeby nie flashować całego ekranu -- `closeInput()` z `UserInput.ts` zamyka globalny readline — trzeba upewnić się że raw mode nie koliduje z tym samym `process.stdin` diff --git a/src/features/game/components/GameInformations/components/GameHint/GameHint.ts b/src/features/game/components/GameInformations/components/GameHint/GameHint.ts index 8c957e2..8eaaf36 100644 --- a/src/features/game/components/GameInformations/components/GameHint/GameHint.ts +++ b/src/features/game/components/GameInformations/components/GameHint/GameHint.ts @@ -9,7 +9,7 @@ const getHistoryInstruction = () => { const useArrowKeys = keyHandler?.running; return useArrowKeys - ? "SelectPrevious move" + ? "Select previous move" : `Back to previous move from 0 to ${game.movesCount}. (0 is start from the beginning)`; };