From 32f57b428838b84966ea02cc7193c4c81bc4cec9 Mon Sep 17 00:00:00 2001
From: Benjamin Auder <benjamin.auder@somewhere>
Date: Fri, 14 Jan 2022 10:34:03 +0100
Subject: [PATCH] Implemented random rematch

---
 TODO       |  4 +--
 app.js     |  5 +--
 index.html | 13 +++++---
 server.js  | 93 ++++++++++++++++++++++++++++--------------------------
 4 files changed, 63 insertions(+), 52 deletions(-)

diff --git a/TODO b/TODO
index f3b7eeb..21b1040 100644
--- a/TODO
+++ b/TODO
@@ -1,14 +1,14 @@
 Dark Racing Kings ?
 Checkered-Teleport ?
 
-// rem ref to bordContainer --> rethink CSS design...
+// rem ref to boardContainer --> rethink CSS design...
 
 // TODO: Otage, Emergo, Pacosako : fonction "buildPiece(arg1, arg2)" returns HTML element with 2 SVG or SVG + number
 
 add mode diagram --> use vchess rules (only english? only french?)
 add variants : Chakart first (dark,cylinder)
 
-bouton random rematch
+bouton random rematch : OK, now better style + show rules if random (or not?)
 cancel en rouge
 flèche sur plateau + mode diagramme
 coté serveur : si disconnect, supprimer rematch en cours
diff --git a/app.js b/app.js
index 0a1fffe..e269c5b 100644
--- a/app.js
+++ b/app.js
@@ -86,8 +86,9 @@ function cancelSeek() {
   if (send("cancelseek", {vname: seek_vname})) toggleVisible("newGame");
 }
 
-function sendRematch() {
-  if (send("rematch", {gid: gid})) toggleVisible("pendingRematch");
+function sendRematch(random) {
+  if (send("rematch", {gid: gid, random: !!random}))
+    toggleVisible("pendingRematch");
 }
 function cancelRematch() {
   if (send("norematch", {gid: gid})) toggleVisible("newGame");
diff --git a/index.html b/index.html
index caab4e9..72b9091 100644
--- a/index.html
+++ b/index.html
@@ -16,16 +16,21 @@
       <div id="boardContainer"></div>
       <div id="gameStopped">
         <h1>Game over</h1>
+        <h4>Rematch</h4>
         <div class="btn-wrap">
           <button id="rematchBtn"
                   onClick="sendRematch()">
-            Rematch
+            Same
           </button>
-          <button class="cancel-something"
-                  onClick="cancelRematch()">
-            Close
+          <button id="rematchBtn"
+                  onClick="sendRematch('random')">
+            Random
           </button>
         </div>
+        <button class="cancel-something"
+                onClick="cancelRematch()">
+          Close
+        </button>
       </div>
       <div id="pendingRematch">
         <div class="loader hour-glass"></div>
diff --git a/server.js b/server.js
index a068c6e..9c85eeb 100644
--- a/server.js
+++ b/server.js
@@ -17,48 +17,54 @@ function send(sid, code, data) {
   if (socket) socket.send(JSON.stringify(Object.assign({ code: code }, data)));
 }
 
+function launchGame(vname, players, options) {
+  const gid =
+    Crypto.randomBytes(randstrSize).toString("hex").slice(0, randstrSize);
+  games[gid] = {
+    vname: vname,
+    players: players.map(p => {
+               return (!p ? null : {sid: p.sid, name: p.name});
+             }),
+    options: options,
+    time: Date.now()
+  };
+  if (players.every(p => p)) {
+    const gameInfo = Object.assign(
+      // Provide seed so that both players initialize with same FEN
+      {seed: Math.floor(Math.random() * 1984), gid: gid},
+      games[gid]);
+    for (const p of players) {
+      send(p.sid,
+           "gamestart",
+           Object.assign({randvar: p.randvar}, gameInfo));
+    }
+  }
+  else {
+    // Incomplete players array: do not start game yet
+    send(sid, "gamecreated", {gid: gid});
+    // If nobody joins within 5 minutes, delete game
+    setTimeout(
+      () => {
+        if (games[gid] && games[gid].players.some(p => !p))
+          delete games[gid];
+      },
+      5 * 60000
+    );
+  }
+}
+
+function getRandomVariant() {
+  // Pick a variant at random in the list
+  const index = Math.floor(Math.random() * variants.length);
+  return variants[index].name;
+}
+
 wss.on("connection", (socket, req) => {
   const sid = req.url.split("=")[1]; //...?sid=...
   sockets[sid] = socket;
   socket.isAlive = true;
   socket.on("pong", () => socket.isAlive = true);
 
-  function launchGame(vname, players, options) {
-    const gid =
-      Crypto.randomBytes(randstrSize).toString("hex").slice(0, randstrSize);
-    games[gid] = {
-      vname: vname,
-      players: players.map(p => {
-                 return (!p ? null : {sid: p.sid, name: p.name});
-               }),
-      options: options,
-      time: Date.now()
-    };
-    if (players.every(p => p)) {
-      const gameInfo = Object.assign(
-        // Provide seed so that both players initialize with same FEN
-        {seed: Math.floor(Math.random() * 1984), gid: gid},
-        games[gid]);
-      for (const p of players) {
-        send(p.sid,
-             "gamestart",
-             Object.assign({randvar: p.randvar}, gameInfo));
-      }
-    }
-    else {
-      // Incomplete players array: do not start game yet
-      send(sid, "gamecreated", {gid: gid});
-      // If nobody joins within 5 minutes, delete game
-      setTimeout(
-        () => {
-          if (games[gid] && games[gid].players.some(p => !p))
-            delete games[gid];
-        },
-        5 * 60000
-      );
-    }
-  }
-
   socket.on("message", (msg) => {
     const obj = JSON.parse(msg);
     switch (obj.code) {
@@ -83,11 +89,7 @@ wss.on("connection", (socket, req) => {
         }
         if (opponent) {
           delete challenges[choice];
-          if (choice == "_random") {
-            // Pick a variant at random in the list
-            const index = Math.floor(Math.random() * variants.length);
-            choice = variants[index].name;
-          }
+          if (choice == "_random") choice = getRandomVariant();
           // Launch game
           let players = [
             {sid: sid, name: obj.name, randvar: randvar},
@@ -120,11 +122,14 @@ wss.on("connection", (socket, req) => {
         if (!games[obj.gid]) send(sid, "closerematch");
         else {
           const myIndex = (games[obj.gid].players[0].sid == sid ? 0 : 1);
-          if (!games[obj.gid].rematch) games[obj.gid].rematch = [false, false];
-          games[obj.gid].rematch[myIndex] = true;
+          if (!games[obj.gid].rematch) games[obj.gid].rematch = [0, 0];
+          games[obj.gid].rematch[myIndex] = !obj.random ? 1 : 2;
           if (games[obj.gid].rematch[1-myIndex]) {
             // Launch new game, colors reversed
-            launchGame(games[obj.gid].vname,
+            let vname = games[obj.gid].vname;
+            if (games[obj.gid].rematch.every(r => r == 2))
+              vname = getRandomVariant();
+            launchGame(vname,
                        games[obj.gid].players.reverse(),
                        games[obj.gid].options);
           }
-- 
2.44.0