Fix computer mode in rules tab
[vchess.git] / public / javascripts / components / room.js
CommitLineData
b6487fb9
BA
1// TODO: main playing hall, chat + online players + current challenges + button "new game"
2/*
3input#modal-newgame.modal(type="checkbox")
4div(role="dialog" aria-labelledby="newGameTxt")
5 .card.smallpad.small-modal
6 label#close-newgame.modal-close(for="modal-newgame")
7 h3#newGameTxt= translations["New game"]
8 p= translations["Waiting for opponent..."]
9*/
10
7ee085c2
BA
11
12
13
14// TODO: my-challenge-list, gérant clicks sur challenges, affichage, réception/émission des infos sur challenges
15// de même, my-player-list
16
17
18
19
2305d34a
BA
20// TODO: si on est en train de jouer une partie, le notifier aux nouveaux connectés
21
b6487fb9
BA
22/*
23Players + challenges : == "room" home of variant (surligner si nouveau défi perso et pas affichage courant)
24joueurs en ligne (dte),
25Nouvelle partie + défis en temps réel + parties en cours (milieu, tabs),
26chat général (gauche, activé ou non (bool global storage)).
27(cadences base + incrément, corr == incr >= 1jour ou base >= 7j)
28--> correspondance: stocker sur serveur lastMove + peerId + color + movesCount + gameId + variant + timeleft
29quand je poste un lastMove corr, supprimer mon ancien lastMove le cas échéant (tlm l'a eu)
30fin de partie corr: garder maxi nbPlayers lastMove sur serveur, pendant 7 jours (arbitraire)
31*/
81da2786
BA
32 case "newgame": //opponent found
33 // oppid: opponent socket ID
34 this.newGame("human", data.fen, data.color, data.oppid, data.gameid);
35 break;
36
37 // TODO: elsewhere, probably (new game button)
38 clickGameSeek: function(e) {
39 this.getRidOfTooltip(e.currentTarget);
40 if (this.mode == "human" && this.score == "*")
41 return; //no newgame while playing
42 if (this.seek)
43 {
44 this.conn.send(JSON.stringify({code:"cancelnewgame"}));
45 this.seek = false;
46 }
47 else
48 this.newGame("human");
49 },
50 clickComputerGame: function(e) {
51 this.getRidOfTooltip(e.currentTarget);
52 if (this.mode == "computer" && this.score == "*"
53 && this.vr.turn != this.mycolor)
54 {
55 // Wait for computer reply first (avoid potential "ghost move" bug)
56 return;
57 }
58 this.newGame("computer");
59 },
60 clickFriendGame: function(e) {
61 this.getRidOfTooltip(e.currentTarget);
62 document.getElementById("modal-fenedit").checked = true;
63 },
64 // In main hall :
65 newGame: function(mode, fenInit, color, oppId, gameId) {
66 const fen = fenInit || VariantRules.GenRandInitFen();
67 console.log(fen); //DEBUG
68 if (mode=="human" && !oppId)
69 {
70 const storageVariant = localStorage.getItem("variant");
8d7e2786 71 if (!!storageVariant && storageVariant !== variant.name
81da2786
BA
72 && localStorage["score"] == "*")
73 {
74 return alert(translations["Finish your "] +
75 storageVariant + translations[" game first!"]);
76 }
77 // Send game request and wait..
78 try {
79 this.conn.send(JSON.stringify({code:"newgame", fen:fen, gameid: getRandString() }));
80 } catch (INVALID_STATE_ERR) {
81 return; //nothing achieved
82 }
83 this.seek = true;
84 let modalBox = document.getElementById("modal-newgame");
85 modalBox.checked = true;
86 setTimeout(() => { modalBox.checked = false; }, 2000);
87 return;
88 }
89 const prefix = this.getStoragePrefix(mode);
90 if (mode == "computer")
91 {
92 const storageVariant = localStorage.getItem(prefix+"variant");
93 if (!!storageVariant)
94 {
95 const score = localStorage.getItem(prefix+"score");
8d7e2786 96 if (storageVariant !== variant.name && score == "*")
81da2786
BA
97 {
98 if (!confirm(storageVariant +
99 translations[": unfinished computer game will be erased"]))
100 {
101 return;
102 }
103 }
104 }
105 }
106 else if (mode == "friend")
107 {
108 const storageVariant = localStorage.getItem(prefix+"variant");
109 if (!!storageVariant)
110 {
111 const score = localStorage.getItem(prefix+"score");
8d7e2786 112 if (storageVariant !== variant.name && score == "*")
81da2786
BA
113 {
114 if (!confirm(storageVariant +
115 translations[": current analysis will be erased"]))
116 {
117 return;
118 }
119 }
120 }
121 }
122 this.vr = new VariantRules(fen, []);
123 this.score = "*";
124 this.pgnTxt = ""; //redundant with this.score = "*", but cleaner
125 this.mode = mode;
126 this.incheck = [];
127 this.fenStart = V.ParseFen(fen).position; //this is enough
128 if (mode=="human")
129 {
130 // Opponent found!
131 this.gameId = gameId;
132 this.oppid = oppId;
133 this.oppConnected = true;
134 this.mycolor = color;
135 this.seek = false;
136 if (this.sound >= 1)
137 new Audio("/sounds/newgame.mp3").play().catch(err => {});
138 document.getElementById("modal-newgame").checked = false;
139 }
140 else if (mode == "computer")
141 {
142 this.compWorker.postMessage(["init",this.vr.getFen()]);
143 this.mycolor = (Math.random() < 0.5 ? 'w' : 'b');
144 if (this.mycolor != this.vr.turn)
145 this.playComputerMove();
146 }
147 else if (mode == "friend")
148 this.mycolor = "w"; //convention...
149 //else: problem solving: nothing more to do
150 if (mode != "problem")
151 this.setStorage(); //store game state in case of interruptions
152 },
153 continueGame: function(mode) {
154 this.mode = mode;
155 this.oppid = (mode=="human" ? localStorage.getItem("oppid") : undefined);
156 const prefix = this.getStoragePrefix(mode);
157 this.mycolor = localStorage.getItem(prefix+"mycolor");
158 const moves = JSON.parse(localStorage.getItem(prefix+"moves"));
159 const fen = localStorage.getItem(prefix+"fen");
160 const score = localStorage.getItem(prefix+"score"); //set in "endGame()"
161 this.fenStart = localStorage.getItem(prefix+"fenStart");
162 this.vr = new VariantRules(fen, moves);
163 this.incheck = this.vr.getCheckSquares(this.vr.turn);
164 if (mode == "human")
165 {
166 this.gameId = localStorage.getItem("gameId");
167 // Send ping to server (answer pong if opponent is connected)
168 this.conn.send(JSON.stringify({
169 code:"ping",oppid:this.oppid,gameId:this.gameId}));
170 }
171 else if (mode == "computer")
172 {
173 this.compWorker.postMessage(["init",fen]);
174 if (score == "*" && this.mycolor != this.vr.turn)
175 this.playComputerMove();
176 }
177 //else: nothing special to do in friend mode
178 if (score != "*")
179 {
180 // Small delay required when continuation run faster than drawing page
181 setTimeout(() => this.endGame(score), 100);
182 }
183 },
184
185
186 // TODO: option du bouton "new game"
187 const modalFenEdit = [
188 h('input',
189 {
190 attrs: { "id": "modal-fenedit", type: "checkbox" },
191 "class": { "modal": true },
192 }),
193 h('div',
194 {
195 attrs: { "role": "dialog", "aria-labelledby": "titleFenedit" },
196 },
197 [
198 h('div',
199 {
200 "class": { "card": true, "smallpad": true },
201 },
202 [
203 h('label',
204 {
205 attrs: { "id": "close-fenedit", "for": "modal-fenedit" },
206 "class": { "modal-close": true },
207 }
208 ),
209 h('h3',
210 {
211 attrs: { "id": "titleFenedit" },
212 "class": { "section": true },
213 domProps: { innerHTML: translations["Game state (FEN):"] },
214 }
215 ),
216 h('input',
217 {
218 attrs: {
219 "id": "input-fen",
220 type: "text",
221 value: VariantRules.GenRandInitFen(),
222 },
223 }
224 ),
225 h('button',
226 {
227 on: { click:
228 () => {
229 const fen = document.getElementById("input-fen").value;
230 document.getElementById("modal-fenedit").checked = false;
231 this.newGame("friend", fen);
232 }
233 },
234 domProps: { innerHTML: translations["Ok"] },
235 }
236 ),
237 h('button',
238 {
239 on: { click:
240 () => {
241 document.getElementById("input-fen").value =
242 VariantRules.GenRandInitFen();
243 }
244 },
245 domProps: { innerHTML: translations["Random"] },
246 }
247 ),
248 ]
249 )
250 ]
251 )
252 ];
253 elementArray = elementArray.concat(modalFenEdit);