1
+ import { SourceCode } from "../../.." ;
2
+
3
+ export const gameModel : SourceCode = {
4
+ path : '../../../core/model/GameModel.ts' ,
5
+ content : `import { MediatorObservable, Model, Observable } from 'react-obsidian';
6
+ import { CurrentPlayer } from '../entities/CurrentPlayer';
7
+ import { Squares } from '../entities/Squares';
8
+ import { type CalculateWinnerUseCase } from '../usecases/CalculateWinnerUseCase';
9
+ import { History } from '../entities/History';
10
+ import { persist } from '../../persistency/persist.legacy';
11
+
12
+ export default class GameModel extends Model {
13
+ @persist('CurrentPlayer') private readonly currentPlayer = new CurrentPlayer('X');
14
+ @persist('Squares') private readonly squares = new Squares();
15
+ @persist('History') private readonly history = new History(this.squares.value);
16
+ @persist('Status') public readonly status = new MediatorObservable<string>();
17
+ @persist('IsReady') public readonly isReady = new Observable<boolean>(false);
18
+
19
+ constructor(calculateWinnerUseCase: CalculateWinnerUseCase) {
20
+ super();
21
+ this.status.mapSource(this.currentPlayer, (player) => {
22
+ const winner = calculateWinnerUseCase.calculate(this.squares.value);
23
+ return winner ? \`Winner: \${winner}\` : \`Next player: \${player}\`;
24
+ });
25
+ }
26
+
27
+ public onSquareClick(index: number) {
28
+ if (this.squares.value[index]) return;
29
+ this.squares.mark(index, this.currentPlayer.value);
30
+ this.currentPlayer.nextPlayer();
31
+ this.history.add(this.squares.value, this.currentPlayer.value);
32
+ }
33
+
34
+ public onHistoryEntryClick(index: number) {
35
+ this.history.goTo(index);
36
+ this.squares.value = this.history.value[index].squares;
37
+ this.currentPlayer.value = this.history.value[index].currentPlayer;
38
+ }
39
+ }
40
+ ` } ;
0 commit comments