* Browser back and forward buttons work as undo / redo buttons for user moves (and other user actions).
* Visuals are acceptable.
## Screenshot
![screenshot](docs/screenshot.png)
## Usage
* `npm ci` to install dependencies;
@ -128,9 +137,9 @@ and then either the server will merge current query parameters with submitted da
and redirect the client to the page with the new query parameters,
or the client-side web component will do the merging.
* Server part is implemented in [`src/backend/progressive-form.ts`](/src/backend/progressive-form.ts).
* Client part is implemented in [`src/frontend/components/progressive-form.ts`](/src/frontend/components/progressive-form.ts).
* Usage example is in [`src/backend/components/counter.tsx`](/src/backend/components/counter.tsx).
* Server part is implemented in [`src/backend/progressive-form.ts`](src/backend/progressive-form.ts).
* Client part is implemented in [`src/frontend/components/progressive-form.ts`](src/frontend/components/progressive-form.ts).
* Usage example is in [`src/backend/components/counter.tsx`](src/backend/components/counter.tsx).
#### Game board
@ -146,9 +155,9 @@ Additionally, the board itself is just a table with a button in every cell.
And these buttons get their values and texts set dynamically,
and get enabled (when it's a valid move) or disabled (when the cell is occupied, or when the game is over) automatically.
* Server part is implemented in [`src/branch/main/src/backend/components/boardgame.tsx`](/src/branch/main/src/backend/components/boardgame.tsx).
* Client part is implemented as web component in [`src/frontend/components/board-game.ts`](/src/frontend/components/board-game.ts).
* Shared part is implemented in [`src/branch/main/src/shared/display.ts`](/src/branch/main/src/shared/display.ts).
* Server part is implemented in [`src/backend/components/boardgame.tsx`](src/backend/components/boardgame.tsx).
* Client part is implemented as web component in [`src/frontend/components/board-game.ts`](src/frontend/components/board-game.ts).
* Shared part is implemented in [`src/shared/display.ts`](src/shared/display.ts).
#### Computer opponent
@ -160,13 +169,13 @@ without leaving a trace of the intermediate state (when it was computer player's
so that the history back/forward button only work as undo/redo for user actions
(with subsequent computer actions coupled to user actions that caused them).
* Server part is implemented in [`src/backend/main/boardgame-handler.ts`](/src/backend/main/boardgame-handler.ts)
* Client part is implemented in the same [`src/frontend/components/board-game.ts`](/src/frontend/components/board-game.ts) (see call to `replaceLocation`).
* Shared part is implemented in [`src/branch/main/src/shared/gameplay/boardgame.ts`](/src/branch/main/src/shared/gameplay/boardgame.ts).
* Server part is implemented in [`src/backend/main/boardgame-handler.ts`](src/backend/main/boardgame-handler.ts)
* Client part is implemented in the same [`src/frontend/components/board-game.ts`](src/frontend/components/board-game.ts) (see call to `replaceLocation`).
* Shared part is implemented in [`src/shared/gameplay/boardgame.ts`](src/shared/gameplay/boardgame.ts).
### Gameplay
Mostly defined in [`src/shared/datatypes`](/src/shared/datatypes), [`src/shared/gameplay`](/src/shared/gameplay) and [`src/shared/game-variants`](/src/shared/game-variants).
Mostly defined in [`src/shared/datatypes`](src/shared/datatypes), [`src/shared/gameplay`](src/shared/gameplay) and [`src/shared/game-variants`](src/shared/game-variants).
The main idea is that every possible state of the board belongs to one of the four categories:
player X won, player Y won, undecided (neither won but moves can still be made)
@ -232,7 +241,7 @@ I decided that this complexity is not needed.
If computer player is selected for boards larger than 12 squares, no computer moves will be made,
and humans will have to make moves both for O and for X.