Merge branch 'master' of auder.net:vchess
authorBenjamin Auder <benjamin.auder@somewhere>
Tue, 3 Mar 2020 22:13:19 +0000 (23:13 +0100)
committerBenjamin Auder <benjamin.auder@somewhere>
Tue, 3 Mar 2020 22:13:19 +0000 (23:13 +0100)
16 files changed:
client/public/images/pieces/Threechecks/bk_1.svg [moved from client/public/images/pieces/Check3/bk_1.svg with 100% similarity]
client/public/images/pieces/Threechecks/bk_2.svg [moved from client/public/images/pieces/Check3/bk_2.svg with 100% similarity]
client/public/images/pieces/Threechecks/bk_3.svg [moved from client/public/images/pieces/Check3/bk_3.svg with 100% similarity]
client/public/images/pieces/Threechecks/wk_1.svg [moved from client/public/images/pieces/Check3/wk_1.svg with 100% similarity]
client/public/images/pieces/Threechecks/wk_2.svg [moved from client/public/images/pieces/Check3/wk_2.svg with 100% similarity]
client/public/images/pieces/Threechecks/wk_3.svg [moved from client/public/images/pieces/Check3/wk_3.svg with 100% similarity]
client/src/components/ComputerGame.vue
client/src/components/ContactForm.vue
client/src/utils/timeControl.js
client/src/variants/Allmate.js
client/src/variants/Baroque.js
client/src/variants/Knightrelay.js
client/src/variants/Threechecks.js [moved from client/src/variants/Check3.js with 92% similarity]
client/src/views/Game.vue
client/src/views/Hall.vue
server/db/populate.sql

index aee1f70..9699c5a 100644 (file)
@@ -38,7 +38,8 @@ export default {
     this.compWorker.onmessage = e => {
       let compMove = e.data;
       // Small delay for the bot to appear "more human"
-      const delay = Math.max(500 - (Date.now() - this.timeStart), 0);
+      const minDelay = this.gameInfo.mode == "versus" ? 500 : 1000;
+      const delay = Math.max(minDelay - (Date.now() - this.timeStart), 0);
       let self = this;
       setTimeout(() => {
         if (this.currentUrl != document.location.href) return; //page change
index cadbf73..f9c5c60 100644 (file)
@@ -12,7 +12,7 @@ div
       label.modal-close(for="modalContact")
       fieldset
         label(for="userEmail") {{ st.tr["Email"] }}
-        input#userEmail(type="email")
+        input#userEmail(type="email" :value="st.user.email")
       fieldset
         label(for="mailSubject") {{ st.tr["Subject"] }}
         input#mailSubject(type="text")
index 9106b96..b4bac05 100644 (file)
@@ -14,9 +14,9 @@ function timeUnitToSeconds(value, unit) {
   return seconds;
 }
 
+// Used only if increment, hence live game: no "day" unit
 function isLargerUnit(unit1, unit2) {
   return (
-    (unit1 == "d" && unit2 != "d") ||
     (unit1 == "h" && ["s", "m"].includes(unit2)) ||
     (unit1 == "m" && unit2 == "s")
   );
@@ -24,9 +24,8 @@ function isLargerUnit(unit1, unit2) {
 
 export function extractTime(cadence) {
   let tcParts = cadence.replace(/ /g, "").split("+");
-  // Concatenate usual time control suffixes, in case of none is provided
+  // Concatenate usual time control suffix, in case of none is provided
   tcParts[0] += "m";
-  tcParts[1] += "s";
   const mainTimeArray = tcParts[0].match(/^([0-9]+)([smhd]+)$/);
   if (!mainTimeArray) return null;
   const mainTimeValue = parseInt(mainTimeArray[1]);
@@ -34,6 +33,7 @@ export function extractTime(cadence) {
   const mainTime = timeUnitToSeconds(mainTimeValue, mainTimeUnit);
   let increment = 0;
   if (tcParts.length >= 2) {
+    tcParts[1] += "s";
     const incrementArray = tcParts[1].match(/^([0-9]+)([smhd]+)$/);
     if (!incrementArray) return null;
     const incrementValue = parseInt(incrementArray[1]);
index 5636f56..728de25 100644 (file)
@@ -5,10 +5,6 @@ export const VariantRules = class AllmateRules extends ChessRules {
     return false;
   }
 
-  canTake(sq1, sq2) {
-    return false; //Captures handled differently
-  }
-
   getCheckSquares() {
     // No notion of check
     return [];
@@ -20,6 +16,10 @@ export const VariantRules = class AllmateRules extends ChessRules {
 
   getPotentialMovesFrom([x, y]) {
     let moves = super.getPotentialMovesFrom([x, y]);
+    // Remove standard captures (without removing castling):
+    moves = moves.filter(m => {
+      return m.vanish.length == 1 || m.appear.length == 2;
+    });
 
     // Augment moves with "mate-captures":
     // TODO: this is coded in a highly inefficient way...
index 8f1f9ba..ae4b511 100644 (file)
@@ -72,7 +72,7 @@ export const VariantRules = class BaroqueRules extends ChessRules {
       ) {
         const oppPiece = this.getPiece(i, j);
         if (oppPiece == V.IMMOBILIZER) {
-          // Moving is impossible only if this immobilizer is not neutralized
+          // Moving is possible only if this immobilizer is neutralized
           for (let step2 of adjacentSteps) {
             const [i2, j2] = [i + step2[0], j + step2[1]];
             if (i2 == x && j2 == y) continue; //skip initial piece!
@@ -474,8 +474,8 @@ export const VariantRules = class BaroqueRules extends ChessRules {
   }
 
   isAttackedByBishop([x, y], colors) {
-    // We cheat a little here: since this function is used exclusively for king,
-    // it's enough to check the immediate surrounding of the square.
+    // We cheat a little here: since this function is used exclusively for
+    // the king, it's enough to check the immediate surrounding of the square.
     const adjacentSteps = V.steps[V.ROOK].concat(V.steps[V.BISHOP]);
     for (let step of adjacentSteps) {
       const [i, j] = [x + step[0], y + step[1]];
@@ -512,6 +512,23 @@ export const VariantRules = class BaroqueRules extends ChessRules {
     return false;
   }
 
+  isAttackedByKing([x, y], colors) {
+    const steps = V.steps[V.ROOK].concat(V.steps[V.BISHOP]);
+    for (let step of steps) {
+      let rx = x + step[0],
+          ry = y + step[1];
+      if (
+        V.OnBoard(rx, ry) &&
+        this.getPiece(rx, ry) === V.KING &&
+        colors.includes(this.getColor(rx, ry)) &&
+        !this.isImmobilized([rx, ry])
+      ) {
+        return true;
+      }
+    }
+    return false;
+  }
+
   static get VALUES() {
     return {
       p: 1,
index eebb0f2..de1e89a 100644 (file)
@@ -29,7 +29,7 @@ export const VariantRules = class KnightrelayRules extends ChessRules {
             // Potential promotions:
             const finalPieces = piece == V.PAWN && x + step[0] == lastRank
               ? [V.ROOK, V.KNIGHT, V.BISHOP, V.QUEEN]
-              : [V.PAWN];
+              : [piece];
             for (let p of finalPieces) {
               moves.push(
                 this.getBasicMove([x,y], [x+step[0],y+step[1]], {
similarity index 92%
rename from client/src/variants/Check3.js
rename to client/src/variants/Threechecks.js
index ea5ab84..78aaf1f 100644 (file)
@@ -1,6 +1,6 @@
 import { ChessRules } from "@/base_rules";
 
-export const VariantRules = class Check3Rules extends ChessRules {
+export const VariantRules = class ThreechecksRules extends ChessRules {
   static IsGoodFlags(flags) {
     // 4 for castle + 2 for checks (0,1 or 2)
     return !!flags.match(/^[01]{4,4}[012]{2,2}$/);
@@ -28,7 +28,7 @@ export const VariantRules = class Check3Rules extends ChessRules {
     // TODO: !!this.checkFlags condition for printDiagram, but clearly not good.
     // This is just a temporary fix.
     if (b[1] == 'k' && this.checkFlags && this.checkFlags[b[0]] > 0)
-      return "Check3/" + b[0] + 'k_' + this.checkFlags[b[0]];
+      return "Threechecks/" + b[0] + 'k_' + this.checkFlags[b[0]];
     return b;
   }
 
index ec25588..6c289e6 100644 (file)
@@ -399,7 +399,7 @@ export default {
             move.move,
             "received",
             null,
-            {addTime:move.addTime});
+            {addTime: move.addTime});
           break;
         }
         case "resign":
@@ -440,7 +440,7 @@ export default {
           data.lastMove.move,
           "received",
           null,
-          {addTime:data.lastMove.addTime, initime:data.initime});
+          {addTime: data.lastMove.addTime, initime: data.initime});
       }
       if (data.drawSent) this.drawOffer = "received";
       if (data.score != "*") {
@@ -507,24 +507,19 @@ export default {
               game.players[0]
             ];
           }
-          // corr game: need to compute the clocks + initime
           // NOTE: clocks in seconds, initime in milliseconds
-          game.clocks = [tc.mainTime, tc.mainTime];
           game.moves.sort((m1, m2) => m1.idx - m2.idx); //in case of
           const L = game.moves.length;
           if (game.score == "*") {
             // Set clocks + initime
+            game.clocks = [tc.mainTime, tc.mainTime];
             game.initime = [0, 0];
-            if (L >= 3) {
-              let addTime = [0, 0];
-              for (let i = 2; i < L; i++) {
-                addTime[i % 2] +=
-                  tc.increment -
-                  (game.moves[i].played - game.moves[i - 1].played) / 1000;
-              }
-              for (let i = 0; i <= 1; i++) game.clocks[i] += addTime[i];
+            if (L >= 1) {
+              const gameLastupdate = game.moves[L-1].played;
+              game.initime[L % 2] = gameLastupdate;
+              if (L >= 2)
+                game.clocks[L % 2] = Date.now() - gameLastupdate;
             }
-            if (L >= 1) game.initime[L % 2] = game.moves[L - 1].played;
           }
           // Sort chat messages from newest to oldest
           game.chats.sort((c1, c2) => {
@@ -680,19 +675,20 @@ export default {
           var filtered_move = getFilteredMove(move);
         }
         // Send move ("newmove" event) to people in the room (if our turn)
-        let addTime = data ? data.addTime : 0;
+        let addTime = (data && this.game.type == "live") ? data.addTime : 0;
         if (moveCol == this.game.mycolor) {
           if (this.drawOffer == "received")
             // I refuse draw
             this.drawOffer = "";
-          if (this.game.movesCount >= 2) {
+          // 'addTime' is irrelevant for corr games:
+          if (this.game.type == "live" && this.game.movesCount >= 2) {
             const elapsed = Date.now() - this.game.initime[colorIdx];
             // elapsed time is measured in milliseconds
             addTime = this.game.increment - elapsed / 1000;
           }
           const sendMove = {
             move: filtered_move,
-            addTime: addTime,
+            addTime: addTime, //undefined for corr games
             cancelDrawOffer: this.drawOffer == "",
             // Players' SID required for /mygames page
             // TODO: precompute and add this field to game object?
@@ -705,9 +701,13 @@ export default {
         this.game.movesCount++;
         // TODO: notifyTurn
         // (add)Time indication: useful in case of lastate infos requested
-        this.game.moves.push({move:move, addTime:addTime});
+        this.game.moves.push(this.game.type == "live"
+          ? {move:move, addTime:addTime}
+          : move);
         this.game.fen = this.vr.getFen();
-        this.game.clocks[colorIdx] += addTime;
+        if (this.game.type == "live") this.game.clocks[colorIdx] += addTime;
+        // In corr games, just reset clock to mainTime:
+        else this.game.clocks[colorIdx] = extractTime(this.game.cadence).mainTime;
         // data.initime is set only when I receive a "lastate" move from opponent
         this.game.initime[nextIdx] = (data && data.initime) ? data.initime : Date.now();
         this.re_setClocks();
index 9bcfd05..a48997a 100644 (file)
@@ -45,14 +45,14 @@ main
         fieldset
           label(for="cadence") {{ st.tr["Cadence"] }} *
           div#predefinedCadences
-            button(type="button") 5+3
             button(type="button") 15+5
             button(type="button") 45+30
-            button(type="button") 7d+2d
+            button(type="button") 3d
+            button(type="button") 7d
           input#cadence(
             type="text"
             v-model="newchallenge.cadence"
-            placeholder="5+0, 1h+30s, 7d+1d ..."
+            placeholder="5+0, 1h+30s, 5d ..."
           )
         fieldset(v-if="st.user.id > 0")
           label(for="selectPlayers") {{ st.tr["Play with?"] }}
index 60cd18e..0989f71 100644 (file)
@@ -11,7 +11,6 @@ insert or ignore into Variants (name,description) values
   ('Benedict', 'Change colors'),
   ('Berolina', 'Pawns move diagonally'),
   ('Checkered', 'Shared pieces'),
-  ('Check3', 'Give three checks'),
   ('Chess960', 'Standard rules'),
   ('Circular', 'Run forward'),
   ('Crazyhouse', 'Captures reborn'),
@@ -33,6 +32,7 @@ insert or ignore into Variants (name,description) values
   ('Recycle', 'Reuse pieces'),
   ('Shatranj', 'Ancient rules'),
   ('Suction', 'Attract opposite king'),
+  ('Threechecks', 'Give three checks'),
   ('Upsidedown', 'Board upside down'),
   ('Wildebeest', 'Balanced sliders & leapers'),
   ('Wormhole', 'Squares disappear'),