chesspal 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli/cli.js +6 -6
- package/dist/commands/{analyse-game.d.ts → analysis/analyse.d.ts} +2 -2
- package/dist/commands/{analyse-game.js → analysis/analyse.js} +7 -11
- package/dist/commands/{annotate-game.d.ts → analysis/annotate.d.ts} +1 -1
- package/dist/commands/{annotate-game.js → analysis/annotate.js} +6 -9
- package/dist/commands/{delete-review.d.ts → analysis/delete-review.d.ts} +1 -1
- package/dist/commands/{delete-review.js → analysis/delete-review.js} +5 -5
- package/dist/commands/analysis/index.d.ts +4 -0
- package/dist/commands/analysis/index.js +5 -0
- package/dist/commands/{study-games.d.ts → analysis/study-games.d.ts} +1 -1
- package/dist/commands/{study-games.js → analysis/study-games.js} +4 -5
- package/dist/commands/{agents.d.ts → answers/agents.d.ts} +3 -3
- package/dist/commands/{agents.js → answers/agents.js} +5 -5
- package/dist/commands/{clock.d.ts → answers/clock.d.ts} +2 -2
- package/dist/commands/{clock.js → answers/clock.js} +2 -2
- package/dist/commands/{drawings.d.ts → answers/drawings.d.ts} +1 -1
- package/dist/commands/{drawings.js → answers/drawings.js} +1 -1
- package/dist/commands/answers/index.d.ts +12 -0
- package/dist/commands/answers/index.js +14 -0
- package/dist/commands/{lead-input.d.ts → answers/lead-input.d.ts} +1 -1
- package/dist/commands/{lead-input.js → answers/lead-input.js} +1 -1
- package/dist/commands/{answer-lines.d.ts → answers/lines.d.ts} +2 -2
- package/dist/commands/{answer-lines.js → answers/lines.js} +4 -4
- package/dist/commands/{opening-book.d.ts → answers/opening-book.d.ts} +1 -1
- package/dist/commands/{opening-book.js → answers/opening-book.js} +3 -3
- package/dist/commands/{play-move.d.ts → answers/play-move.d.ts} +2 -2
- package/dist/commands/{play-move.js → answers/play-move.js} +3 -3
- package/dist/commands/{say.d.ts → answers/say.d.ts} +3 -3
- package/dist/commands/{say.js → answers/say.js} +4 -4
- package/dist/commands/{speech.js → answers/speech.js} +1 -1
- package/dist/commands/{study.d.ts → answers/study.d.ts} +3 -3
- package/dist/commands/{study.js → answers/study.js} +3 -3
- package/dist/commands/{game-summary.d.ts → answers/summary.d.ts} +2 -2
- package/dist/commands/{game-summary.js → answers/summary.js} +4 -4
- package/dist/commands/{view.d.ts → answers/view.d.ts} +1 -1
- package/dist/commands/{ai-move.d.ts → game/ai-move.d.ts} +2 -2
- package/dist/commands/{ai-move.js → game/ai-move.js} +6 -11
- package/dist/commands/{coach.d.ts → game/coach.d.ts} +1 -1
- package/dist/commands/{coach.js → game/coach.js} +7 -13
- package/dist/commands/{draw-offer.d.ts → game/draw-offer.d.ts} +1 -1
- package/dist/commands/{draw-offer.js → game/draw-offer.js} +4 -4
- package/dist/commands/{end-game.d.ts → game/end.d.ts} +2 -2
- package/dist/commands/{end-game.js → game/end.js} +5 -9
- package/dist/commands/{export-game.d.ts → game/export.d.ts} +1 -1
- package/dist/commands/{export-game.js → game/export.js} +4 -4
- package/dist/commands/game/index.d.ts +11 -0
- package/dist/commands/game/index.js +13 -0
- package/dist/commands/{levels.d.ts → game/levels.d.ts} +3 -3
- package/dist/commands/{levels.js → game/levels.js} +3 -3
- package/dist/commands/{look.d.ts → game/look.d.ts} +3 -4
- package/dist/commands/{look.js → game/look.js} +5 -10
- package/dist/commands/{new-game.d.ts → game/new.d.ts} +3 -4
- package/dist/commands/{new-game.js → game/new.js} +17 -13
- package/dist/commands/{page-link.d.ts → game/page-link.d.ts} +1 -1
- package/dist/commands/{player-move.d.ts → game/player-move.d.ts} +2 -2
- package/dist/commands/{player-move.js → game/player-move.js} +4 -8
- package/dist/commands/{ponder.d.ts → game/ponder.d.ts} +3 -3
- package/dist/commands/{ponder.js → game/ponder.js} +6 -9
- package/dist/commands/{position.d.ts → game/position.d.ts} +2 -2
- package/dist/commands/{position.js → game/position.js} +5 -7
- package/dist/commands/{status.d.ts → game/status.d.ts} +2 -4
- package/dist/commands/{status.js → game/status.js} +12 -17
- package/dist/commands/index.d.ts +6 -17
- package/dist/commands/index.js +11 -38
- package/dist/commands/{delete-game.d.ts → profiles/delete-game.d.ts} +1 -1
- package/dist/commands/{delete-game.js → profiles/delete-game.js} +3 -3
- package/dist/commands/profiles/index.d.ts +4 -0
- package/dist/commands/profiles/index.js +5 -0
- package/dist/commands/{past-games.d.ts → profiles/past-games.d.ts} +1 -1
- package/dist/commands/{past-games.js → profiles/past-games.js} +5 -5
- package/dist/commands/{profiles.d.ts → profiles/profiles.d.ts} +7 -7
- package/dist/commands/{profiles.js → profiles/profiles.js} +4 -4
- package/dist/commands/{ratings.d.ts → profiles/ratings.d.ts} +1 -1
- package/dist/commands/{ratings.js → profiles/ratings.js} +2 -2
- package/dist/commands/{context.js → registry/context.js} +2 -2
- package/dist/commands/registry/index.d.ts +2 -0
- package/dist/commands/registry/index.js +3 -0
- package/dist/commands/setup/index.d.ts +2 -0
- package/dist/commands/setup/index.js +3 -0
- package/dist/commands/{init.d.ts → setup/init.d.ts} +1 -1
- package/dist/commands/{init.js → setup/init.js} +2 -3
- package/dist/commands/{instructions.d.ts → setup/instructions.d.ts} +2 -2
- package/dist/commands/{instructions.js → setup/instructions.js} +3 -3
- package/dist/commands/{ai-say.d.ts → talk/ai-say.d.ts} +2 -3
- package/dist/commands/{ai-say.js → talk/ai-say.js} +5 -9
- package/dist/commands/talk/index.d.ts +2 -0
- package/dist/commands/talk/index.js +3 -0
- package/dist/commands/{player-say.d.ts → talk/player-say.d.ts} +1 -1
- package/dist/commands/{player-say.js → talk/player-say.js} +4 -4
- package/dist/page/app/app.js +19 -11
- package/dist/page/app/served.js +7 -0
- package/dist/page/avatars/torretta.js +10 -3
- package/dist/page/dialogs/dialogs.css +10 -0
- package/dist/page/dialogs/profiles.js +1 -5
- package/dist/page/dialogs/settings.js +18 -4
- package/dist/page/game/column.js +1 -1
- package/dist/page/game/game.css +1 -1
- package/dist/page/guide/blocks.js +13 -2
- package/dist/page/guide/credits.js +6 -0
- package/dist/page/guide/drawings/analysis.js +13 -0
- package/dist/page/guide/drawings/drawings.css +329 -0
- package/dist/page/guide/drawings/drawings.js +15 -0
- package/dist/page/guide/drawings/game.js +15 -0
- package/dist/page/guide/drawings/helps.js +13 -0
- package/dist/page/guide/drawings/how-it-works.js +13 -0
- package/dist/page/guide/drawings/parts.js +103 -0
- package/dist/page/guide/drawings/players.js +19 -0
- package/dist/page/guide/drawings/talk.js +9 -0
- package/dist/page/guide/en.md +39 -25
- package/dist/page/guide/guide.css +123 -91
- package/dist/page/guide/guide.js +47 -25
- package/dist/page/guide/it.md +39 -25
- package/dist/page/guide/markdown.js +5 -0
- package/dist/page/helps/helps.css +127 -83
- package/dist/page/helps/helps.js +45 -26
- package/dist/page/helps/view.js +13 -3
- package/dist/page/{guide/foot.js → layout/footer.js} +7 -8
- package/dist/page/layout/header.js +5 -3
- package/dist/page/layout/layout.css +114 -10
- package/dist/page/layout/window.js +6 -26
- package/dist/page/main.js +1 -1
- package/dist/page/pieces/pieces.js +5 -2
- package/dist/page/style.css +1 -0
- package/dist/page/table/table.css +69 -0
- package/dist/page/table/update.js +82 -0
- package/dist/page/talk/chat.css +6 -6
- package/dist/page/talk/talk.css +17 -67
- package/dist/page/talk/talk.js +5 -5
- package/dist/page/talk/voice.js +12 -0
- package/dist/page/text.js +66 -18
- package/dist/page/theme.css +2 -0
- package/dist/server/{bell.js → bell/bell.js} +3 -3
- package/dist/server/bell/index.d.ts +1 -0
- package/dist/server/bell/index.js +2 -0
- package/dist/server/{caller.d.ts → mcp/caller.d.ts} +1 -1
- package/dist/server/{caller.js → mcp/caller.js} +1 -1
- package/dist/server/mcp/index.d.ts +1 -0
- package/dist/server/mcp/index.js +2 -0
- package/dist/server/{mcp.d.ts → mcp/mcp.d.ts} +1 -1
- package/dist/server/{mcp.js → mcp/mcp.js} +9 -9
- package/dist/server/page/game.js +16 -3
- package/dist/server/page/http.d.ts +1 -1
- package/dist/server/page/index.d.ts +3 -0
- package/dist/server/page/index.js +3 -0
- package/dist/server/page/page.d.ts +12 -3
- package/dist/server/page/page.js +13 -4
- package/dist/server/page/table.d.ts +7 -1
- package/dist/server/page/table.js +79 -3
- package/dist/server/page/update.d.ts +18 -0
- package/dist/server/page/update.js +40 -0
- package/dist/server/table/browser.d.ts +1 -1
- package/dist/server/table/browser.js +1 -1
- package/dist/server/table/hosts/chats.d.ts +1 -1
- package/dist/server/table/hosts/chats.js +2 -2
- package/dist/server/table/hosts/index.d.ts +1 -1
- package/dist/server/table/hosts/index.js +1 -1
- package/dist/server/table/hosts/play.d.ts +8 -1
- package/dist/server/table/hosts/play.js +40 -4
- package/dist/server/table/hosts/seat.d.ts +5 -1
- package/dist/server/table/hosts/seat.js +1 -1
- package/dist/server/table/index.d.ts +3 -2
- package/dist/server/table/index.js +3 -2
- package/dist/server/table/launch.d.ts +5 -2
- package/dist/server/table/launch.js +6 -3
- package/dist/server/table/link.d.ts +1 -1
- package/dist/server/table/link.js +3 -3
- package/dist/server/table/table.d.ts +4 -5
- package/dist/server/table/table.js +15 -12
- package/dist/server/table/update.d.ts +17 -0
- package/dist/server/table/update.js +77 -0
- package/dist/sites/index.d.ts +1 -1
- package/dist/sites/index.js +2 -2
- package/dist/version.d.ts +4 -0
- package/dist/version.js +12 -1
- package/package.json +1 -1
- /package/dist/commands/{speech.d.ts → answers/speech.d.ts} +0 -0
- /package/dist/commands/{view.js → answers/view.js} +0 -0
- /package/dist/commands/{page-link.js → game/page-link.js} +0 -0
- /package/dist/commands/{context.d.ts → registry/context.d.ts} +0 -0
- /package/dist/commands/{registry.d.ts → registry/registry.d.ts} +0 -0
- /package/dist/commands/{registry.js → registry/registry.js} +0 -0
- /package/dist/server/{bell.d.ts → bell/bell.d.ts} +0 -0
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
/* The guide's drawings (Zoe): sketches of the page on its own ground, every colour from the theme, so one drawing serves light and dark */
|
|
2
|
+
|
|
3
|
+
.guide-drawing {
|
|
4
|
+
max-width: 520px;
|
|
5
|
+
margin: 6px auto 16px;
|
|
6
|
+
overflow: hidden;
|
|
7
|
+
border: 1px solid var(--line);
|
|
8
|
+
border-radius: var(--radius);
|
|
9
|
+
background: var(--page);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.guide-art {
|
|
13
|
+
display: block;
|
|
14
|
+
width: 100%;
|
|
15
|
+
height: auto;
|
|
16
|
+
aspect-ratio: 480 / 220;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/* The page's cards and what is written on them, as bars */
|
|
20
|
+
.guide-art .paper {
|
|
21
|
+
fill: var(--card);
|
|
22
|
+
stroke: var(--line);
|
|
23
|
+
stroke-width: 1.5;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.guide-art .quote {
|
|
27
|
+
fill: var(--quote);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.guide-art .words {
|
|
31
|
+
fill: var(--say);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.guide-art .field {
|
|
35
|
+
fill: var(--page);
|
|
36
|
+
stroke: var(--line);
|
|
37
|
+
stroke-width: 1.5;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.guide-art .bar {
|
|
41
|
+
fill: color-mix(in oklab, var(--soft) 45%, var(--card));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.guide-art .bar.strong {
|
|
45
|
+
fill: color-mix(in oklab, var(--ink) 70%, var(--card));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.guide-art .bar.on-words {
|
|
49
|
+
fill: color-mix(in oklab, var(--say-ink) 55%, var(--say));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.guide-art .rule {
|
|
53
|
+
stroke: var(--line);
|
|
54
|
+
stroke-width: 1.5;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.guide-art .bullet {
|
|
58
|
+
fill: color-mix(in oklab, var(--soft) 60%, var(--card));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.guide-art .button,
|
|
62
|
+
.guide-art .soft-line {
|
|
63
|
+
fill: none;
|
|
64
|
+
stroke: var(--soft);
|
|
65
|
+
stroke-width: 1.5;
|
|
66
|
+
stroke-linecap: round;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/* What the page speaks of, in the accent */
|
|
70
|
+
.guide-art .accent {
|
|
71
|
+
fill: var(--accent);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.guide-art .bar.on-last {
|
|
75
|
+
fill: color-mix(in oklab, var(--fixed-ink) 70%, transparent);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.guide-art .bar.on-accent {
|
|
79
|
+
fill: var(--on-accent);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.guide-art .accent-line,
|
|
83
|
+
.guide-art .on-accent-line,
|
|
84
|
+
.guide-art .thread {
|
|
85
|
+
fill: none;
|
|
86
|
+
stroke: var(--accent);
|
|
87
|
+
stroke-width: 2.5;
|
|
88
|
+
stroke-linecap: round;
|
|
89
|
+
stroke-linejoin: round;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.guide-art .on-accent-line {
|
|
93
|
+
stroke: var(--on-accent);
|
|
94
|
+
stroke-width: 2;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/* The tick of the player in use and the pencil to their profile, as the window of the players draws them */
|
|
98
|
+
.guide-art .tick,
|
|
99
|
+
.guide-art .pencil {
|
|
100
|
+
fill: none;
|
|
101
|
+
stroke: var(--accent);
|
|
102
|
+
stroke-linecap: round;
|
|
103
|
+
stroke-linejoin: round;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.guide-art .tick {
|
|
107
|
+
stroke-width: 2;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.guide-art .pencil {
|
|
111
|
+
stroke-width: 2.4;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
.guide-art .knot,
|
|
116
|
+
.guide-art .caret {
|
|
117
|
+
fill: var(--accent);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.guide-art .focused,
|
|
121
|
+
.guide-art .call {
|
|
122
|
+
fill: var(--card);
|
|
123
|
+
stroke: var(--accent);
|
|
124
|
+
stroke-width: 2;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.guide-art .call-square,
|
|
128
|
+
.guide-art .chosen {
|
|
129
|
+
fill: none;
|
|
130
|
+
stroke: var(--accent);
|
|
131
|
+
stroke-width: 1.5;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.guide-art .chosen {
|
|
135
|
+
stroke-width: 2.5;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/* The board and what the page draws on it */
|
|
139
|
+
.guide-art .light {
|
|
140
|
+
fill: var(--light-square);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.guide-art .dark {
|
|
144
|
+
fill: var(--dark-square);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.guide-art .last {
|
|
148
|
+
fill: var(--last-move);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.guide-art .hint {
|
|
152
|
+
fill: var(--hint);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.guide-art .over {
|
|
156
|
+
fill: none;
|
|
157
|
+
stroke: var(--hover-edge);
|
|
158
|
+
stroke-width: 2.5;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.guide-art .ghost {
|
|
162
|
+
opacity: var(--ghost);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.guide-art .lift-shadow {
|
|
166
|
+
fill: var(--lift-shadow);
|
|
167
|
+
opacity: 0.6;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.guide-art .pointer {
|
|
171
|
+
fill: var(--ink);
|
|
172
|
+
stroke: var(--card);
|
|
173
|
+
stroke-width: 1.2;
|
|
174
|
+
stroke-linejoin: round;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.guide-art .drawn {
|
|
178
|
+
stroke: var(--help-halo);
|
|
179
|
+
stroke-width: 1.2;
|
|
180
|
+
stroke-linejoin: round;
|
|
181
|
+
opacity: 0.85;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.guide-art .drawn.green {
|
|
185
|
+
fill: var(--drawn-green);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.guide-art .help-halo,
|
|
189
|
+
.guide-art .help-line {
|
|
190
|
+
fill: none;
|
|
191
|
+
stroke-linecap: round;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
.guide-art .help-halo {
|
|
195
|
+
stroke: var(--help-halo);
|
|
196
|
+
stroke-width: 4.5;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.guide-art .help-line {
|
|
200
|
+
stroke: var(--help-line);
|
|
201
|
+
stroke-width: 2.2;
|
|
202
|
+
stroke-dasharray: 5 4;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.guide-art .danger {
|
|
206
|
+
fill: var(--drawn-red);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.guide-art .danger-line {
|
|
210
|
+
stroke: var(--drawn-red);
|
|
211
|
+
stroke-width: 2;
|
|
212
|
+
stroke-linecap: round;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.guide-art .danger-dot {
|
|
216
|
+
fill: var(--help-on);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.guide-art .danger-row {
|
|
220
|
+
fill: color-mix(in oklab, var(--drawn-red) 12%, var(--card));
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/* The move badges: a disc in the colour of the judgement, a white sign */
|
|
224
|
+
.guide-art .judgement.best {
|
|
225
|
+
fill: var(--badge-best);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.guide-art .judgement.mistake {
|
|
229
|
+
fill: var(--badge-mistake);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.guide-art .judgement.blunder {
|
|
233
|
+
fill: var(--badge-blunder);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
.guide-art .sign {
|
|
237
|
+
fill: none;
|
|
238
|
+
stroke: var(--badge-ink);
|
|
239
|
+
stroke-linecap: round;
|
|
240
|
+
stroke-linejoin: round;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.guide-art .sign .dot {
|
|
244
|
+
fill: var(--badge-ink);
|
|
245
|
+
stroke: none;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.guide-art .clock {
|
|
249
|
+
fill: none;
|
|
250
|
+
stroke: var(--soft);
|
|
251
|
+
stroke-width: 1.3;
|
|
252
|
+
stroke-linecap: round;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
.guide-art .clock.on-accent {
|
|
256
|
+
stroke: var(--on-accent);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/* The Torretta, and the players' faces on their discs */
|
|
260
|
+
.guide-art .tower .antenna {
|
|
261
|
+
fill: none;
|
|
262
|
+
stroke: var(--torretta-shade);
|
|
263
|
+
stroke-width: 4;
|
|
264
|
+
stroke-linecap: round;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.guide-art .tower .light-bulb {
|
|
268
|
+
fill: var(--torretta-light);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.guide-art .tower .shade {
|
|
272
|
+
fill: var(--torretta-shade);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
.guide-art .tower .body {
|
|
276
|
+
fill: var(--torretta-body);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.guide-art .tower .screen {
|
|
280
|
+
fill: var(--torretta-screen);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
.guide-art .tower .features {
|
|
284
|
+
fill: var(--torretta-face);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.guide-art .person {
|
|
288
|
+
fill: var(--card);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
.guide-art .tone-player {
|
|
292
|
+
fill: var(--badge-brilliant);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
.guide-art .tone-1 {
|
|
296
|
+
fill: var(--badge-great);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.guide-art .tone-2 {
|
|
300
|
+
fill: var(--badge-book);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.guide-art .tone-3 {
|
|
304
|
+
fill: var(--badge-excellent);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
.guide-art .tone-4 {
|
|
308
|
+
fill: var(--badge-miss);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.guide-art .tone-5 {
|
|
312
|
+
fill: var(--badge-note);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
.guide-art .tone-6 {
|
|
316
|
+
fill: var(--badge-mistake);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
.guide-art .tone-7 {
|
|
320
|
+
fill: var(--badge-good);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
.guide-art .tone-8 {
|
|
324
|
+
fill: var(--badge-inaccuracy);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
.guide-art .tone-9 {
|
|
328
|
+
fill: var(--torretta-body);
|
|
329
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Analysis } from "./analysis.js";
|
|
2
|
+
import { Game } from "./game.js";
|
|
3
|
+
import { Helps } from "./helps.js";
|
|
4
|
+
import { HowItWorks } from "./how-it-works.js";
|
|
5
|
+
import { Players } from "./players.js";
|
|
6
|
+
import { Talk } from "./talk.js";
|
|
7
|
+
/** The guide's drawings, by the name its markdown gives them: . */
|
|
8
|
+
export const drawings = {
|
|
9
|
+
"how-it-works": HowItWorks,
|
|
10
|
+
game: Game,
|
|
11
|
+
talk: Talk,
|
|
12
|
+
helps: Helps,
|
|
13
|
+
analysis: Analysis,
|
|
14
|
+
players: Players,
|
|
15
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
|
|
2
|
+
// Playing a move: a knight lifted from its square under the pointer, the dots of where it may go, the gold edge where it would land, and the player's clock running
|
|
3
|
+
import { Bar, Board, Card, centre, Clock, corner, Face, PieceAt, PieceOn, Pieces, Square, Torretta } from "./parts.js";
|
|
4
|
+
const grid = { x: 140, y: 10, cell: 25 };
|
|
5
|
+
const position = ["rnbqkbnr", "pppp.ppp", "........", "....p...", "....P...", "........", "PPPP.PPP", "RNBQKB.R"];
|
|
6
|
+
/** The board after 1.e4 e5 with White's knight in the air, the two players' cards on the left and the moves on the right. */
|
|
7
|
+
export function Game() {
|
|
8
|
+
const over = corner(grid, 5, 3);
|
|
9
|
+
return (_jsxs("svg", { class: "guide-art", viewBox: "0 0 480 220", "aria-hidden": "true", children: [_jsxs(Board, { grid: grid, children: [_jsx(Square, { grid: grid, file: 4, rank: 7, class: "last" }), _jsx(Square, { grid: grid, file: 4, rank: 5, class: "last" }), _jsx(Pieces, { grid: grid, ranks: position }), _jsx(PieceOn, { grid: grid, file: 6, rank: 1, letter: "N", class: "ghost" }), _jsx(Dot, { file: 4, rank: 2 }), _jsx(Dot, { file: 7, rank: 3 }), _jsx("rect", { class: "over", x: over.x + 1.25, y: over.y + 1.25, width: grid.cell - 2.5, height: grid.cell - 2.5 })] }), _jsx("ellipse", { class: "lift-shadow", cx: over.x + 13, cy: over.y + 20, rx: "11", ry: "3.5" }), _jsx(PieceAt, { x: over.x - 3.5, y: over.y - 15, size: 32, letter: "N" }), _jsx("path", { class: "pointer", transform: `translate(${over.x + 17} ${over.y + 8})`, d: "M0 0V13L3.5 10L6 15.5L8.2 14.5L5.8 9.3H10Z" }), _jsx(Card, { x: 16, y: 10, width: 112, height: 48 }), _jsx(Torretta, { x: 18, y: 14, size: 32, bust: true }), _jsx(Bar, { x: 54, y: 20, width: 46, strong: true }), _jsx(Bar, { x: 54, y: 30, width: 30 }), _jsx("rect", { class: "quote", x: "54", y: "40", width: "44", height: "12", rx: "6" }), _jsx(Clock, { x: 61, y: 46, r: 3.4 }), _jsx(Bar, { x: 68, y: 43.5, width: 24 }), _jsx(Card, { x: 16, y: 162, width: 112, height: 48 }), _jsx(Face, { x: 34, y: 180, r: 12, tone: "tone-player" }), _jsx(Bar, { x: 54, y: 170, width: 46, strong: true }), _jsx(Bar, { x: 54, y: 180, width: 30 }), _jsx("rect", { class: "accent", x: "54", y: "192", width: "44", height: "12", rx: "6" }), _jsx(Clock, { x: 61, y: 198, r: 3.4, class: "clock on-accent" }), _jsx(Bar, { x: 68, y: 195.5, width: 24, class: "bar on-accent" }), _jsx(Card, { x: 352, y: 10, width: 112, height: 44 }), _jsx(Bar, { x: 362, y: 22, width: 70, strong: true }), _jsx(Bar, { x: 362, y: 34, width: 52 }), _jsx(Card, { x: 352, y: 150, width: 112, height: 60 }), _jsx(Bar, { x: 362, y: 162, width: 40, strong: true }), _jsx(Bar, { x: 362, y: 184, width: 8 }), _jsx(Bar, { x: 378, y: 184, width: 28 }), _jsx("rect", { class: "last", x: "414", y: "179", width: "40", height: "15", rx: "4" }), _jsx(Bar, { x: 420, y: 184, width: 28, class: "bar on-last" })] }));
|
|
10
|
+
}
|
|
11
|
+
/** The dot of a square the lifted piece may go to. */
|
|
12
|
+
function Dot({ file, rank }) {
|
|
13
|
+
const { x, y } = centre(grid, file, rank);
|
|
14
|
+
return _jsx("circle", { class: "hint", cx: x, cy: y, r: grid.cell * 0.165 });
|
|
15
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
|
|
2
|
+
import { Arrow, Badge, Bar, Board, Card, centre, Pieces, Square } from "./parts.js";
|
|
3
|
+
const grid = { x: 16, y: 10, cell: 25 };
|
|
4
|
+
const position = ["...qk...", ".....ppp", "p.n.....", ".B..p...", "....P...", "..N..N..", ".....PPP", ".....RK."];
|
|
5
|
+
/** The board with its marks, and the Helps card open on its first tab. */
|
|
6
|
+
export function Helps() {
|
|
7
|
+
const bishop = centre(grid, 1, 5);
|
|
8
|
+
return (_jsxs("svg", { class: "guide-art", viewBox: "0 0 480 220", "aria-hidden": "true", children: [_jsxs(Board, { grid: grid, children: [_jsx(Square, { grid: grid, file: 0, rank: 7, class: "last" }), _jsx(Square, { grid: grid, file: 0, rank: 6, class: "last" }), _jsx(Pieces, { grid: grid, ranks: position })] }), _jsx("path", { class: "help-halo", d: `M${bishop.x} ${bishop.y}L116 35` }), _jsx("path", { class: "help-line", d: `M${bishop.x} ${bishop.y}L116 35` }), _jsx("path", { class: "danger", d: "M41 110V97L54 110Z" }), _jsx("circle", { class: "danger-dot", cx: "44.5", cy: "106", r: "1.7" }), _jsx(Arrow, { from: centre(grid, 5, 3), to: centre(grid, 4, 5), width: 5, class: "drawn green" }), _jsx(Badge, { x: 38, y: 63, r: 6.5, kind: "best" }), _jsx(Card, { x: 236, y: 36, width: 228, height: 148 }), _jsx("circle", { class: "accent-line", cx: "252", cy: "55", r: "5.5" }), _jsx("circle", { class: "accent", cx: "252", cy: "55", r: "2" }), _jsx(Bar, { x: 264, y: 52.5, width: 44, class: "bar accent" }), _jsx("rect", { class: "button", x: "420", y: "48", width: "14", height: "14", rx: "3" }), _jsx("rect", { class: "button", x: "440", y: "48", width: "14", height: "14", rx: "3" }), _jsx(Bar, { x: 250, y: 70, width: 34, strong: true }), _jsx(Bar, { x: 298, y: 70, width: 40 }), _jsx("path", { class: "rule", d: "M246 85.5H454" }), _jsx("rect", { class: "accent", x: "246", y: "82", width: "42", height: "2.5", rx: "1" }), _jsx(Row, { y: 96, width: 96, children: _jsx("path", { class: "danger", d: "M252 112V100L264 112Z" }) }), _jsxs(Row, { y: 124, width: 88, children: [_jsx("path", { class: "danger-line", d: "M253 141L259 135" }), _jsx("circle", { class: "danger", cx: "260.5", cy: "133.5", r: "3.5" })] }), _jsx("rect", { class: "quote", x: "246", y: "152", width: "208", height: "22", rx: "4" }), _jsx("circle", { class: "soft-line", cx: "257", cy: "163", r: "4.5" }), _jsx(Bar, { x: 272, y: 160.5, width: 112 }), _jsx(Bar, { x: 418, y: 160.5, width: 8, strong: true }), _jsx(Bar, { x: 434, y: 160.5, width: 8, strong: true })] }));
|
|
9
|
+
}
|
|
10
|
+
/** A row of the card about the player's pieces in trouble: a red tint and edge, its sign, a line and a count. */
|
|
11
|
+
function Row({ y, width, children }) {
|
|
12
|
+
return (_jsxs("g", { children: [_jsx("rect", { class: "danger-row", x: "246", y: y, width: "208", height: "22", rx: "4" }), _jsx("rect", { class: "danger", x: "246", y: y, width: "3", height: "22" }), children, _jsx(Bar, { x: 272, y: y + 8.5, width: width, strong: true }), _jsx(Bar, { x: 434, y: y + 8.5, width: 8, strong: true })] }));
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
|
|
2
|
+
// How Chesspal works: the board's page and the AI's chat, two windows tied by a thread, the call through which the AI plays
|
|
3
|
+
import { Bar, Board, Card, Chevron, Face, Pieces, Square, Torretta } from "./parts.js";
|
|
4
|
+
const grid = { x: 26, y: 42, cell: 19 };
|
|
5
|
+
const position = [".....rk.", ".....ppp", "..n.....", "....p...", "....P...", ".....N..", ".....PPP", ".....RK."];
|
|
6
|
+
/** The page with its board and the Torretta, the chat beside it, and the thread between them. */
|
|
7
|
+
export function HowItWorks() {
|
|
8
|
+
return (_jsxs("svg", { class: "guide-art", viewBox: "0 0 480 220", "aria-hidden": "true", children: [_jsx(Window, { x: 16, width: 212 }), _jsxs(Board, { grid: grid, children: [_jsx(Square, { grid: grid, file: 1, rank: 8, class: "last" }), _jsx(Square, { grid: grid, file: 2, rank: 6, class: "last" }), _jsx(Pieces, { grid: grid, ranks: position })] }), _jsx(Torretta, { x: 186, y: 40, size: 32 }), _jsx(Bar, { x: 190, y: 78, width: 26, strong: true }), _jsx(Bar, { x: 190, y: 88, width: 18 }), _jsx(Face, { x: 203, y: 182, r: 11, tone: "tone-player" }), _jsx(Window, { x: 278, width: 186 }), _jsx(Card, { x: 288, y: 40, width: 166, height: 24, class: "quote" }), _jsx(Bar, { x: 296, y: 49, width: 100, strong: true }), _jsx("circle", { class: "bullet", cx: "293", cy: "78", r: "2.5" }), _jsx(Bar, { x: 300, y: 75, width: 130 }), _jsx(Bar, { x: 300, y: 86, width: 96 }), _jsx(Card, { x: 288, y: 102, width: 166, height: 26, class: "call" }), _jsx("rect", { class: "light", x: "296", y: "109", width: "12", height: "12" }), _jsx("rect", { class: "dark", x: "296", y: "109", width: "6", height: "6" }), _jsx("rect", { class: "dark", x: "302", y: "115", width: "6", height: "6" }), _jsx("rect", { class: "call-square", x: "296", y: "109", width: "12", height: "12" }), _jsx(Bar, { x: 316, y: 112, width: 74, strong: true }), _jsx("circle", { class: "bullet", cx: "293", cy: "146", r: "2.5" }), _jsx(Bar, { x: 300, y: 143, width: 120 }), _jsx(Bar, { x: 300, y: 154, width: 80 }), _jsx("rect", { class: "field", x: "288", y: "170", width: "166", height: "24", rx: "5" }), _jsx("g", { class: "accent-line", children: _jsx(Chevron, { x: 299, y: 182, size: 8 }) }), _jsx("rect", { class: "caret", x: "309", y: "176", width: "2", height: "12", rx: "1" }), _jsx("path", { class: "thread", d: "M228 108C258 108 258 115 288 115" }), _jsx("circle", { class: "knot", cx: "228", cy: "108", r: "4" }), _jsx("circle", { class: "knot", cx: "288", cy: "115", r: "4" })] }));
|
|
9
|
+
}
|
|
10
|
+
/** A window with its title bar and three dots, as tall as the drawing leaves. */
|
|
11
|
+
function Window({ x, width }) {
|
|
12
|
+
return (_jsxs("g", { children: [_jsx(Card, { x: x, y: 16, width: width, height: 188 }), _jsx("path", { class: "rule", d: `M${x} 32H${x + width}` }), _jsx("circle", { class: "bullet", cx: x + 11, cy: "24", r: "2.5" }), _jsx("circle", { class: "bullet", cx: x + 20, cy: "24", r: "2.5" }), _jsx("circle", { class: "bullet", cx: x + 29, cy: "24", r: "2.5" })] }));
|
|
13
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "preact/jsx-runtime";
|
|
2
|
+
import { useContext, useId } from "preact/hooks";
|
|
3
|
+
import { ChosenSet, pieceSymbol } from "../../pieces/pieces.js";
|
|
4
|
+
/** The top-left corner of a square: `file` 0 to 7 from a, `rank` 1 to 8, White at the bottom. */
|
|
5
|
+
export function corner(grid, file, rank) {
|
|
6
|
+
return { x: grid.x + file * grid.cell, y: grid.y + (8 - rank) * grid.cell };
|
|
7
|
+
}
|
|
8
|
+
/** The centre of a square. */
|
|
9
|
+
export function centre(grid, file, rank) {
|
|
10
|
+
const { x, y } = corner(grid, file, rank);
|
|
11
|
+
return { x: x + grid.cell / 2, y: y + grid.cell / 2 };
|
|
12
|
+
}
|
|
13
|
+
/** A card of the page, its corners as the page's. */
|
|
14
|
+
export function Card({ x, y, width, height, class: name = "paper" }) {
|
|
15
|
+
return _jsx("rect", { class: name, x: x, y: y, width: width, height: height, rx: "6" });
|
|
16
|
+
}
|
|
17
|
+
/** A line of text, as a rounded bar: `strong` for a title or a name. */
|
|
18
|
+
export function Bar({ x, y, width, strong = false, class: name }) {
|
|
19
|
+
return _jsx("rect", { class: name ?? (strong ? "bar strong" : "bar"), x: x, y: y, width: width, height: "5", rx: "2.5" });
|
|
20
|
+
}
|
|
21
|
+
/** The board's squares, light and dark. */
|
|
22
|
+
export function Board({ grid, children }) {
|
|
23
|
+
return (_jsxs("g", { children: [_jsx("rect", { class: "light", x: grid.x, y: grid.y, width: grid.cell * 8, height: grid.cell * 8 }), _jsx("path", { class: "dark", d: darkSquares(grid) }), children] }));
|
|
24
|
+
}
|
|
25
|
+
/** A square filled with one of the board's colours: the last move, a hint. */
|
|
26
|
+
export function Square({ grid, file, rank, class: name }) {
|
|
27
|
+
const { x, y } = corner(grid, file, rank);
|
|
28
|
+
return _jsx("rect", { class: name, x: x, y: y, width: grid.cell, height: grid.cell });
|
|
29
|
+
}
|
|
30
|
+
/** A piece of the chosen set by its FEN letter, on a square of the board. */
|
|
31
|
+
export function PieceOn({ grid, file, rank, letter, class: name }) {
|
|
32
|
+
const { x, y } = corner(grid, file, rank);
|
|
33
|
+
return _jsx(PieceAt, { x: x, y: y, size: grid.cell, letter: letter, class: name });
|
|
34
|
+
}
|
|
35
|
+
/** A piece of the chosen set anywhere in the drawing, `size` wide, coloured by the settings as the board's. */
|
|
36
|
+
export function PieceAt({ x, y, size, letter, class: name = "" }) {
|
|
37
|
+
const set = useContext(ChosenSet);
|
|
38
|
+
const side = letter === letter.toUpperCase() ? "white" : "black";
|
|
39
|
+
return _jsx("use", { href: pieceSymbol(letter, set), x: x, y: y, width: size, height: size, class: `piece ${side} ${name}` });
|
|
40
|
+
}
|
|
41
|
+
/** The pieces of a position, one string a rank from the 8th down, "." for an empty square: "....k..." */
|
|
42
|
+
export function Pieces({ grid, ranks }) {
|
|
43
|
+
return (_jsx("g", { children: ranks.flatMap((row, index) => [...row].map((letter, file) => letter === "." ? null : _jsx(PieceOn, { grid: grid, file: file, rank: 8 - index, letter: letter }, `${file}${index}`))) }));
|
|
44
|
+
}
|
|
45
|
+
/** An arrow from one point to another, its shaft `width` wide, as the AI draws them on the board. */
|
|
46
|
+
export function Arrow({ from, to, width, class: name }) {
|
|
47
|
+
return _jsx("polygon", { class: name, points: arrowPoints(from, to, width) });
|
|
48
|
+
}
|
|
49
|
+
/** The Torretta with its neutral face, `size` wide, its top-left corner at x, y; as a `bust`, as on a player's card, in a disc `size` wide, clipped to it. */
|
|
50
|
+
export function Torretta({ x, y, size, bust = false }) {
|
|
51
|
+
const clip = useId();
|
|
52
|
+
if (bust) {
|
|
53
|
+
return (_jsxs("g", { transform: `translate(${x} ${y}) scale(${size / 96}) translate(-16 -8)`, children: [_jsx("clipPath", { id: clip, children: _jsx("circle", { cx: "64", cy: "56", r: "48" }) }), _jsx("circle", { class: "words", cx: "64", cy: "56", r: "48" }), _jsx("g", { "clip-path": `url(#${clip})`, children: _jsx(Figure, {}) })] }));
|
|
54
|
+
}
|
|
55
|
+
return (_jsx("g", { transform: `translate(${x} ${y}) scale(${size / 128})`, children: _jsx(Figure, {}) }));
|
|
56
|
+
}
|
|
57
|
+
/** A person's head and shoulders in a disc of `tone`, a class of drawings.css; `ring` draws the accent around it. */
|
|
58
|
+
export function Face({ x, y, r, tone, ring = false }) {
|
|
59
|
+
const side = r * 0.7;
|
|
60
|
+
const low = y + r * 0.71;
|
|
61
|
+
return (_jsxs("g", { children: [ring && _jsx("circle", { class: "chosen", cx: x, cy: y, r: r + 3.5 }), _jsx("circle", { class: tone, cx: x, cy: y, r: r }), _jsx("circle", { class: "person", cx: x, cy: y - r * 0.2, r: r * 0.34 }), _jsx("path", { class: "person", d: `M${x - side} ${low}Q${x - side} ${y + r * 0.22} ${x} ${y + r * 0.22}Q${x + side} ${y + r * 0.22} ${x + side} ${low}A${r} ${r} 0 0 1 ${x - side} ${low}Z` })] }));
|
|
62
|
+
}
|
|
63
|
+
/** A move's badge, a disc and its sign: best (a tick), mistake (?) or blunder (??). */
|
|
64
|
+
export function Badge({ x, y, r, kind }) {
|
|
65
|
+
return (_jsxs("g", { children: [_jsx("circle", { class: `judgement ${kind}`, cx: x, cy: y, r: r }), kind === "best" && _jsx("path", { class: "sign", style: { strokeWidth: r * 0.28 }, d: `M${x - r * 0.45} ${y + r * 0.02}L${x - r * 0.12} ${y + r * 0.36}L${x + r * 0.45} ${y - r * 0.32}` }), kind === "mistake" && _jsx(Question, { x: x, y: y, size: r }), kind === "blunder" && (_jsxs(_Fragment, { children: [_jsx(Question, { x: x - r * 0.36, y: y, size: r * 0.8 }), _jsx(Question, { x: x + r * 0.36, y: y, size: r * 0.8 })] }))] }));
|
|
66
|
+
}
|
|
67
|
+
/** A small clock face with its two hands. */
|
|
68
|
+
export function Clock({ x, y, r, class: name = "clock" }) {
|
|
69
|
+
return (_jsxs("g", { class: name, children: [_jsx("circle", { cx: x, cy: y, r: r }), _jsx("path", { d: `M${x} ${y - r * 0.6}V${y}L${x + r * 0.45} ${y + r * 0.3}` })] }));
|
|
70
|
+
}
|
|
71
|
+
/** A chevron pointing left or right, centred on x, y. */
|
|
72
|
+
export function Chevron({ x, y, size, left = false }) {
|
|
73
|
+
const reach = left ? -size / 2 : size / 2;
|
|
74
|
+
return _jsx("path", { d: `M${x - reach / 2} ${y - size / 2}L${x + reach / 2} ${y}L${x - reach / 2} ${y + size / 2}` });
|
|
75
|
+
}
|
|
76
|
+
/** The Torretta's figure on its own grid of 128, its disc's frame 16 8 96 96 as the page's bust. */
|
|
77
|
+
function Figure() {
|
|
78
|
+
return (_jsxs("g", { class: "tower", children: [_jsx("path", { class: "antenna", d: "M64 31V19" }), _jsx("circle", { class: "light-bulb", cx: "64", cy: "16", r: "5" }), _jsx("rect", { class: "shade", x: "29", y: "64", width: "12", height: "26", rx: "2" }), _jsx("rect", { class: "shade", x: "87", y: "64", width: "12", height: "26", rx: "2" }), _jsx("path", { class: "body", d: "M34 30H47V40H57V30H71V40H81V30H94V54L89 58L92 106H36L39 58L34 54Z" }), _jsx("rect", { class: "shade", x: "30", y: "104", width: "68", height: "12", rx: "4" }), _jsx("rect", { class: "screen", x: "44", y: "63", width: "40", height: "32", rx: "7" }), _jsx("circle", { class: "features", cx: "55", cy: "76", r: "4.6" }), _jsx("circle", { class: "features", cx: "73", cy: "76", r: "4.6" }), _jsx("rect", { class: "features", x: "58", y: "85.4", width: "12", height: "3.2", rx: "1.6" })] }));
|
|
79
|
+
}
|
|
80
|
+
/** A question mark on a grid of one, `size` wide, centred on x, y. */
|
|
81
|
+
function Question({ x, y, size }) {
|
|
82
|
+
return (_jsxs("g", { class: "sign", transform: `translate(${x} ${y}) scale(${size})`, children: [_jsx("path", { style: { strokeWidth: 0.24 }, d: "M-0.3 -0.22Q-0.3 -0.55 0 -0.55Q0.3 -0.55 0.3 -0.25Q0.3 -0.02 0 0.08V0.2" }), _jsx("circle", { class: "dot", cy: "0.48", r: "0.14" })] }));
|
|
83
|
+
}
|
|
84
|
+
function darkSquares(grid) {
|
|
85
|
+
const steps = [];
|
|
86
|
+
for (let row = 0; row < 8; row++) {
|
|
87
|
+
for (let column = 0; column < 8; column++) {
|
|
88
|
+
if ((row + column) % 2 === 1) {
|
|
89
|
+
steps.push(`M${grid.x + column * grid.cell} ${grid.y + row * grid.cell}h${grid.cell}v${grid.cell}h${-grid.cell}z`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return steps.join("");
|
|
94
|
+
}
|
|
95
|
+
function arrowPoints(from, to, width) {
|
|
96
|
+
const length = Math.hypot(to.x - from.x, to.y - from.y);
|
|
97
|
+
const along = { x: (to.x - from.x) / length, y: (to.y - from.y) / length };
|
|
98
|
+
const across = { x: -along.y, y: along.x };
|
|
99
|
+
const head = width * 2.2;
|
|
100
|
+
const neck = { x: to.x - along.x * head, y: to.y - along.y * head };
|
|
101
|
+
const at = (base, side) => `${(base.x + across.x * side).toFixed(1)},${(base.y + across.y * side).toFixed(1)}`;
|
|
102
|
+
return [at(from, width / 2), at(neck, width / 2), at(neck, width * 1.15), `${to.x},${to.y}`, at(neck, -width * 1.15), at(neck, -width / 2), at(from, -width / 2)].join(" ");
|
|
103
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "preact/jsx-runtime";
|
|
2
|
+
// The players: the player's face in the header, ringed, and under it the window of the players, the one in use ticked, with the pencil to their profile
|
|
3
|
+
import { Bar, Card, Face, Torretta } from "./parts.js";
|
|
4
|
+
/** The players in the window, from the top: the player's own is the second. */
|
|
5
|
+
const players = [{ tone: "tone-2", name: 58 }, { tone: "tone-player", name: 46 }, { tone: "tone-6", name: 66 }];
|
|
6
|
+
const own = 1;
|
|
7
|
+
const row = { x: 136, y: 102, width: 298, height: 28, step: 34 };
|
|
8
|
+
/** A strip of the header with the player's face at its end, and the window «Chi gioca?» it opens. */
|
|
9
|
+
export function Players() {
|
|
10
|
+
return (_jsxs("svg", { class: "guide-art", viewBox: "0 0 480 220", "aria-hidden": "true", children: [_jsx(Card, { x: 16, y: 10, width: 448, height: 36 }), _jsx(Torretta, { x: 22, y: 11, size: 34 }), _jsx("rect", { class: "quote", x: "64", y: "19", width: "60", height: "18", rx: "9" }), [350, 376, 402].map((x) => _jsx("rect", { class: "field", x: x, y: "18", width: "20", height: "20", rx: "5" }, x)), _jsx(Face, { x: 442, y: 28, r: 11, tone: "tone-player", ring: true }), _jsx("rect", { class: "lift-shadow", x: "121", y: "63", width: "330", height: "150", rx: "6" }), _jsx(Card, { x: 120, y: 60, width: 330, height: 150 }), _jsx(Bar, { x: 136, y: 73, width: 62, strong: true }), _jsx("path", { class: "soft-line", d: "M426 70L434 78M434 70L426 78" }), _jsx(Bar, { x: 136, y: 88, width: 120 }), players.map((player, index) => _jsx(PlayerRow, { index: index, tone: player.tone, name: player.name }, player.tone))] }));
|
|
11
|
+
}
|
|
12
|
+
/** A line of the window: a face and a name; the player's own is ticked and has the pencil beside it. */
|
|
13
|
+
function PlayerRow({ index, tone, name }) {
|
|
14
|
+
const y = row.y + index * row.step;
|
|
15
|
+
const middle = y + row.height / 2;
|
|
16
|
+
const mine = index === own;
|
|
17
|
+
const width = mine ? row.width - row.height - 6 : row.width;
|
|
18
|
+
return (_jsxs("g", { children: [_jsx(Card, { x: row.x, y: y, width: width, height: row.height }), _jsx(Face, { x: row.x + 16, y: middle, r: 9, tone: tone }), _jsx(Bar, { x: row.x + 32, y: middle - 2.5, width: name, strong: true }), mine && (_jsxs(_Fragment, { children: [_jsx("path", { class: "tick", d: `M${row.x + width - 26} ${middle}l4 4l7 -8` }), _jsx(Card, { x: row.x + row.width - row.height, y: y, width: row.height, height: row.height }), _jsxs("g", { class: "pencil", transform: `translate(${row.x + row.width - row.height + 6} ${y + 6}) scale(0.667)`, children: [_jsx("path", { d: "M4 20L5 15L15.5 4.5L19.5 8.5L9 19Z" }), _jsx("path", { d: "M13.5 6.5L17.5 10.5" })] })] }))] }));
|
|
19
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
|
|
2
|
+
// Talking to the AI: under its name, the player's question, its answer, and the box where the player writes, beside the board
|
|
3
|
+
import { Bar, Board, Card, Chevron, Pieces, Torretta } from "./parts.js";
|
|
4
|
+
const grid = { x: 256, y: 10, cell: 30 };
|
|
5
|
+
const position = [".....rk.", ".....ppp", "..n.....", "....p...", "..B.P...", ".....N..", ".....PPP", "......K."];
|
|
6
|
+
/** The AI's card, the talk under it and the box with its send button, the board cut by the drawing's edge. */
|
|
7
|
+
export function Talk() {
|
|
8
|
+
return (_jsxs("svg", { class: "guide-art", viewBox: "0 0 480 220", "aria-hidden": "true", children: [_jsx(Board, { grid: grid, children: _jsx(Pieces, { grid: grid, ranks: position }) }), _jsx(Card, { x: 16, y: 10, width: 220, height: 46 }), _jsx(Torretta, { x: 18, y: 13, size: 36, bust: true }), _jsx(Bar, { x: 58, y: 24, width: 56, strong: true }), _jsx(Bar, { x: 58, y: 35, width: 34 }), _jsx(Card, { x: 86, y: 66, width: 150, height: 24 }), _jsx(Bar, { x: 96, y: 75.5, width: 110, strong: true }), _jsx(Card, { x: 16, y: 100, width: 200, height: 42, class: "words" }), _jsx(Bar, { x: 26, y: 111, width: 170, class: "bar on-words" }), _jsx(Bar, { x: 26, y: 123, width: 120, class: "bar on-words" }), _jsx(Card, { x: 16, y: 154, width: 220, height: 56, class: "paper focused" }), _jsx(Bar, { x: 28, y: 168, width: 104 }), _jsx("rect", { class: "caret", x: "136", y: "163", width: "2", height: "15", rx: "1" }), _jsx("rect", { class: "accent", x: "176", y: "187", width: "50", height: "16", rx: "8" }), _jsx(Bar, { x: 186, y: 192.5, width: 18, class: "bar on-accent" }), _jsx("g", { class: "on-accent-line", children: _jsx(Chevron, { x: 213, y: 195, size: 7 }) })] }));
|
|
9
|
+
}
|
package/dist/page/guide/en.md
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
# Chesspal: the guide
|
|
2
2
|
|
|
3
|
-
With **Chesspal** you play chess against an **AI**, on a real board
|
|
3
|
+
With **Chesspal** you play chess against an **AI**, on a real board, and learn with it. This guide is for players: you do not need to know how to program.
|
|
4
4
|
|
|
5
5
|
## How it works
|
|
6
6
|
|
|
7
|
+

|
|
8
|
+
|
|
7
9
|
| Who | What they do |
|
|
8
10
|
|---|---|
|
|
9
11
|
| **You** | You move on the board and talk with the AI. |
|
|
@@ -14,53 +16,65 @@ There are two windows: this **page**, with the board, and the AI's **chat**, in
|
|
|
14
16
|
|
|
15
17
|
No chess engine plays for the AI: every move and every judgment is its own. Chesspal checks that each move is legal and tells the AI what is on the board: the pieces attacked and defended, the pins, the opening's name.
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
1. Install **Node.js** from [nodejs.org](https://nodejs.org), the recommended (LTS) version, and an AI with your own subscription: **Claude Code** or **Codex**.
|
|
20
|
-
2. Open a terminal, the window where you type commands (on Windows, Command Prompt: press Start, type `cmd`, press Enter; on macOS, Terminal), and type `npm install -g chesspal`, then `chesspal`: this page opens. The first time it offers an icon on your desktop, to open it with a double click.
|
|
21
|
-
3. Press **Claude Code** or **Codex**: the AI's chat opens in a window of its own. Keep it open while you play.
|
|
22
|
-
4. Press **New game**, choose your colour, the clock and the AI's level, and press **Start**.
|
|
23
|
-
|
|
24
|
-
## If you are lost
|
|
25
|
-
|
|
26
|
-
- **The AI does not answer**: look at its window. If it is asking you something, answer there; if you closed it, press **Claude Code** or **Codex** again.
|
|
27
|
-
- **The page does not open**: double-click Chesspal's icon, or open it as in the [Quick start](#quick-start).
|
|
28
|
-
- **Your games** are in a folder on your computer: **Who's playing?**, from your picture at the top right, shows where, and **Open the folder** opens it.
|
|
19
|
+
### Getting started
|
|
29
20
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
- You talk with the AI in the box under its name, a few words with each move: it reads them with your move. You can also write to it in its window.
|
|
34
|
-
- A **move written** in the chat counts too: `e4`, `Nf3`, with the English letters of the pieces (K Q R B N), or in words.
|
|
35
|
-
- At each **new game**, the chat the page opened starts again clean by itself, once the AI has stopped thinking: a long chat makes the AI slower.
|
|
21
|
+
1. Click the **AI's name**, at the top left, and choose its chat among those on your computer: **Claude Code** or **Codex**. It opens in a window of its own: keep it open while you play.
|
|
22
|
+
2. Press **New game**, choose your colour, the clock and the AI's level, and press **Start**.
|
|
23
|
+
3. Move: the AI answers on the board, and with a few words under its name.
|
|
36
24
|
|
|
37
25
|
## The game
|
|
38
26
|
|
|
27
|
+

|
|
28
|
+
|
|
39
29
|
- **Move** by dragging a piece, or by clicking the piece and then its square. The dots show the legal moves; when a move is not allowed, the page says why.
|
|
40
30
|
- **The clock**, if you chose one, starts with **Start**. The AI has its own and knows how much time it has left.
|
|
41
31
|
- **Offer a draw** on your turn, once each side has moved; **Resign** ends the game.
|
|
42
|
-
- **The helps**: with "The AI teaches as you play", in the settings, the **Helps** card shows the pieces in danger, the pins and the pawns, and the AI, as your coach, gives you an idea. The AI draws coloured arrows on the board: the **?** beside the moves explains every mark.
|
|
43
32
|
- **Flip** turns the board round; **PGN** saves the moves in the file every chess site reads, to open on Lichess or Chess.com.
|
|
44
33
|
|
|
34
|
+
## Talking with the AI
|
|
35
|
+
|
|
36
|
+

|
|
37
|
+
|
|
38
|
+
- You talk with the AI in the **box under its name**, a few words with each move: it reads them with your move. You can also write to it in its window.
|
|
39
|
+
- A **move written** in the chat counts too: `e4`, `Nf3`, with the English letters of the pieces (K Q R B N), or in words.
|
|
40
|
+
- **The AI's name** opens the choice of its chat: Claude Code or Codex, the model (which AI: some are faster, others stronger) and how much it reasons. The more it reasons, the slower it plays. If you change them, the chat starts afresh in the same window: the AI forgets what you talked about, and the game stays as it is.
|
|
41
|
+
- At each **new game**, the chat the page opened starts afresh by itself, once the AI has stopped thinking: a long chat makes the AI slower.
|
|
42
|
+
|
|
43
|
+
## Helps and marks
|
|
44
|
+
|
|
45
|
+

|
|
46
|
+
|
|
47
|
+
- With **"The AI teaches as you play"**, in the settings, the **Helps** card shows the pieces in danger, the pins and the pawns, and the AI, as your coach, gives you an idea.
|
|
48
|
+
- The AI draws **coloured arrows** on the board: the **?** beside the moves explains every mark.
|
|
49
|
+
- In the review, a **badge** on a move gives the AI's judgment: a great move, an inaccuracy, a blunder.
|
|
50
|
+
|
|
45
51
|
## Review and analysis
|
|
46
52
|
|
|
47
|
-
|
|
53
|
+

|
|
54
|
+
|
|
55
|
+
- When the game is over, press **Analyse the game**: the AI goes over it and puts its judgments and notes on the moves. Read them by stepping through the moves with the arrows at the foot of the column, or by clicking a move.
|
|
48
56
|
- **Analyses**, in the header, opens your analyses, and loads a game played elsewhere: paste its PGN, or choose a .pgn file.
|
|
49
57
|
- Ask the AI about the game in the box under its name.
|
|
50
58
|
- **Annotated PGN** saves the game with its comments.
|
|
51
59
|
|
|
52
60
|
## Players and profile
|
|
53
61
|
|
|
54
|
-
|
|
55
|
-
|
|
62
|
+

|
|
63
|
+
|
|
64
|
+
- **Who's playing?**: your picture at the top right, or your name beside the board, opens the list of the players: there you choose one or add one. Each has their own games and settings.
|
|
65
|
+
- **Your profile**: in **Who's playing?**, the pencil beside your name changes your picture, your name, how you play, your names on Lichess and Chess.com and your FIDE rating.
|
|
56
66
|
- **Your rating**: from your names there, Chesspal reads your public rating, the one of your rapid games if you play them, and tells the AI. No passwords: anyone can see that rating on the site. Without a name there, the AI knows how you play from **How do you play?**
|
|
57
67
|
- **Your FIDE rating**, if you play tournaments, you type yourself: no site gives it to Chesspal. The AI reads it beside the site's, each on its own.
|
|
58
68
|
- If you load a game played on Lichess or Chess.com, Chesspal knows which colour you played.
|
|
59
69
|
|
|
60
70
|
## Questions and problems
|
|
61
71
|
|
|
62
|
-
- **The AI
|
|
72
|
+
- **The AI does not answer, and its clock runs**: look at its window, which may have gone behind the others: find it in the bar at the bottom. If it is asking you something, answer there; if you closed it, click the AI's name and open another.
|
|
73
|
+
- **The AI is slow**: it really thinks over each move. From its name, choose a faster model, or less reasoning.
|
|
74
|
+
- **A piece does not move**: it is not your turn, or the move is not allowed; the page says why.
|
|
75
|
+
- **Closed the page?** Open it again from Chesspal's icon, on the desktop or in the menu: the game you left halfway is still there.
|
|
76
|
+
- **Your games** are in a folder on your computer: **Who's playing?**, from your picture at the top right, shows where, and **Open the folder** opens it. For a backup copy it, with the chat and the page closed.
|
|
77
|
+
- **A new version of Chesspal**: an arrow at the top tells you, and installs it between games.
|
|
63
78
|
- **What it costs**: Chesspal is free; the AI uses your own subscription, and you pay nothing more.
|
|
64
79
|
- **Can the AI play an illegal move?** No: Chesspal checks every move. Its judgments are its own, though, and an AI can be wrong, like a person.
|
|
65
|
-
- **A backup**: copy the folder of your games, with the chat and the page closed.
|
|
66
80
|
- **Something does not work?** Tell us on [GitHub](https://github.com/stefanocaronia/chesspal/issues): what you did, what you expected, what happened. GitHub is the site where Chesspal is made: you write there with a free account, and anyone can read it.
|