Add Ice Age Chess
authorBenjamin Auder <benjamin.auder@somewhere>
Tue, 26 Jan 2021 22:11:44 +0000 (23:11 +0100)
committerBenjamin Auder <benjamin.auder@somewhere>
Tue, 26 Jan 2021 22:11:44 +0000 (23:11 +0100)
15 files changed:
client/public/images/pieces/Iceage/SOURCE [new file with mode: 0644]
client/public/images/pieces/Iceage/icecube.svg [new file with mode: 0644]
client/src/base_rules.js
client/src/translations/en.js
client/src/translations/es.js
client/src/translations/fr.js
client/src/translations/rules/Iceage/en.pug [new file with mode: 0644]
client/src/translations/rules/Iceage/es.pug [new file with mode: 0644]
client/src/translations/rules/Iceage/fr.pug [new file with mode: 0644]
client/src/translations/variants/en.pug
client/src/translations/variants/es.pug
client/src/translations/variants/fr.pug
client/src/variants/Iceage.js [new file with mode: 0644]
client/src/views/Game.vue
server/db/populate.sql

diff --git a/client/public/images/pieces/Iceage/SOURCE b/client/public/images/pieces/Iceage/SOURCE
new file mode 100644 (file)
index 0000000..764be1f
--- /dev/null
@@ -0,0 +1 @@
+https://all-free-download.com/free-vector/download/ice-cube-clip-art_23220.html
diff --git a/client/public/images/pieces/Iceage/icecube.svg b/client/public/images/pieces/Iceage/icecube.svg
new file mode 100644 (file)
index 0000000..b3de8f9
--- /dev/null
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   width="223.17236"
+   height="207.59424"
+   viewBox="0 0 223.17236 207.59424"
+   overflow="visible"
+   enable-background="new 0 0 223.17236 207.59424"
+   xml:space="preserve"
+   id="svg56"
+   sodipodi:docname="cc.svg"
+   inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07, custom)"><metadata
+   id="metadata62"><rdf:RDF><cc:Work
+       rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+         rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+   id="defs60" /><sodipodi:namedview
+   pagecolor="#ffffff"
+   bordercolor="#666666"
+   borderopacity="1"
+   objecttolerance="10"
+   gridtolerance="10"
+   guidetolerance="10"
+   inkscape:pageopacity="0"
+   inkscape:pageshadow="2"
+   inkscape:window-width="1920"
+   inkscape:window-height="1060"
+   id="namedview58"
+   showgrid="false"
+   inkscape:zoom="4.2534899"
+   inkscape:cx="111.58618"
+   inkscape:cy="101.79589"
+   inkscape:window-x="0"
+   inkscape:window-y="20"
+   inkscape:window-maximized="0"
+   inkscape:current-layer="svg56" />
+<g
+   id="Layer_1"
+   transform="matrix(0.9,0,0,0.84995245,14.967333,14.540503)">
+       <path
+   fill="#30eefb"
+   d="m 120.11377,0 87.46777,26.18115 c 0,0 4.06348,110.19531 -0.49707,153.98242 -35.53613,-10.84863 -97.05371,-35.83008 -97.05371,-35.83008 0,0 -94.21338,46.62989 -102.16846,39.79102 C -0.09327,177.28564 2.61669,17.83301 2.61669,17.83301 Z"
+   id="path2" />
+       <!--<path
+   fill="#65f3fa"
+   d="m 221.03662,115.26514 c 3.91504,1.72265 1.54102,1.95019 0,0 z"
+   id="path4" />-->
+       <path
+   fill="#65f3fa"
+   d="m 205.83838,178.84717 c 0,-0.0176 -0.005,-0.0147 0,0"
+   id="path6" />
+       <line
+   fill="none"
+   stroke="#65f3fa"
+   x1="140.16553"
+   y1="207.09131"
+   x2="140.16943"
+   y2="207.09424"
+   id="line8" />
+       <g
+   id="g16">
+               <g
+   id="g14">
+                       <path
+   fill="none"
+   d="m 123.84619,35.54297 c -1.50098,45.99951 -2.88574,67.85693 -5.45508,111.79639"
+   id="path10" />
+                       <path
+   fill="#3ec3f7"
+   d="m 118.84619,35.54297 c -1.22461,37.30029 -3.27539,74.5415 -5.45508,111.79639 -0.16504,2.82422 0.94238,10 5,10 4.28125,0 4.83398,-7.16797 5,-10 2.17969,-37.25488 4.23047,-74.49609 5.45508,-111.79639 0.0928,-2.8291 -0.89355,-10 -5,-10 -4.23242,0 -4.90723,7.1665 -5,10 z"
+   id="path12" />
+               </g>
+       </g>
+       <path
+   opacity="0.65"
+   fill="#d8fcfd"
+   d="m 120.71924,0.18164 c 14.71191,5.04053 88.9834,20.00781 88.59668,25.95947 -0.27246,4.16016 -83.74316,19.19531 -89.45312,17.38184 C 84.81055,32.39062 37.31348,19.71533 0,19.74121 Z"
+   id="path18" />
+       <path
+   fill="#3ec3f7"
+   d="m 112.18701,142.84814 c 0,0 94.89746,30.63086 94.89746,37.31543 0,6.68457 -88.15137,26.5459 -88.15137,26.5459 0,0 -86.87158,-14.04883 -109.6289,-23.95508 -22.75684,-9.90625 102.88281,-39.90625 102.88281,-39.90625 z"
+   id="path20" />
+       <g
+   opacity="0.4"
+   id="g24">
+               <path
+   fill-rule="evenodd"
+   clip-rule="evenodd"
+   fill="#d8fcfd"
+   d="m 205.64111,28.13721 c -9.2627,2.87549 -81.55078,13.56494 -81.83887,18.68457 -1.55371,27.63086 -2.58984,55.31738 -2.74609,82.99121 -0.0889,15.78906 -0.11523,31.72559 1.58105,47.44824 0.10645,0.98145 3.99609,23.65723 8.45996,15.81152 6.12598,-10.76953 -1.87012,-33.44336 -3.71191,-44.72363 -2.37598,-14.57422 2.01367,-27.80859 7.21777,-41.61133 8.33203,-22.09717 27.69141,-8.30957 26.77832,11.21777 -0.65039,13.9043 -9.77051,31.88672 -12.56543,46.04199 -1.85156,9.38379 -4.27734,25.07422 2.73926,33.36426 6.22559,7.35645 35.44727,-10.54102 41.3584,-13.68555 26.00391,-13.83105 18.03613,-39.94141 17.88574,-66.20508 -0.10449,-18.41895 -0.3877,-36.8457 -1.20508,-55.24805 -0.32323,-7.30565 1.87306,-28.19774 -3.95312,-34.08592"
+   id="path22" />
+       </g>
+       <g
+   opacity="0.4"
+   id="g36">
+               <path
+   fill-rule="evenodd"
+   clip-rule="evenodd"
+   fill="#cafcfc"
+   d="m 87.51367,13.68896 c 28.32568,8.12988 47.3833,33.41992 77.75146,19.35693 C 152.87939,22.24854 111.51123,10.19678 87.51367,13.68896 Z"
+   id="path26" />
+               <g
+   id="g34">
+                       <path
+   fill="none"
+   d="m 87.51367,13.68896 c 28.32568,8.12988 47.3833,33.41992 77.75146,19.35693 C 152.87939,22.24854 111.51123,10.19678 87.51367,13.68896 Z"
+   id="path28" />
+                       <g
+   id="g32">
+                               <path
+   fill="#d6eef4"
+   d="m 146.69775,47.47705 c 0.0146,-0.4043 -0.26465,-0.80566 0.18359,-0.99561 1.38477,-0.41699 2.56348,0.98096 3.9707,0.45312 l 0.0537,-0.65869 c 1.10254,0.19775 2.27734,0.46289 3.47559,0.5708 2.125,-0.38281 4.17871,-0.99805 6.11816,-1.76709 -0.11621,-0.21484 -0.19727,-0.41895 -0.0244,-0.55957 0.7666,-0.41113 1.98828,-0.4834 3.13965,-0.85107 l 0.46582,-0.28613 c 0.082,-0.17871 0.0381,-0.40674 0.0107,-0.54639 0.51758,-0.16162 0.99316,-0.2666 1.44043,-0.354 l 1.82129,-1.30225 0.89648,-0.66113 0.22266,-0.16602 0.11133,-0.08301 0.0137,-0.01025 0.003,-0.0024 c 0.84082,-5.8877 -1.875,13.1748 1.88477,-13.2002 l -0.009,-0.0044 -0.0342,-0.01709 -0.0693,-0.03418 -0.55371,-0.27051 c -1.4707,-0.67188 -2.9668,-1.49658 -4.39355,-1.8916 -2.88379,-1.02539 -5.74023,-1.6792 -8.65723,-2.28369 -1.36328,0.03223 -2.70312,0.07812 -3.8584,-0.15186 -1.65332,-0.45166 -3.49805,-1.62695 -5.00488,-2.33057 -0.60742,2.21777 -4.69824,1.95264 -4.74219,4.4126 -0.97461,-0.40186 -2.43945,-1.021 -2.72852,-0.41895 -0.85938,1.77832 -2.35059,3.6709 -5.26855,3.97412 -1.07617,-0.07617 -2.41113,-1.30225 -2.88477,-1.02148 -0.7373,0.44434 0.93066,1.69531 0.18945,2.13818 7.20117,2.84912 14.57031,4.70117 20.86914,8.10107 0.71582,0.04102 1.98633,0.58984 3.61816,1.39648 0.45117,0.19824 0.70215,0.4248 1.09277,0.65186 l 0.55762,0.35107 0.28809,0.17969 0.14648,0.09082 0.0732,0.0459 0.0371,0.02295 0.0186,0.01123 0.01,0.0059 0.005,0.0029 c -0.47363,3.34229 4.14746,-29.0957 2.1875,-15.36328 -0.99316,0.46582 -2.03906,1.06836 -3.12305,1.45752 -4.31445,1.88232 -8.96094,2.23828 -10.83398,1.97266 l -0.34082,0.03662 c -2.05078,-0.14404 -4.53516,-0.29053 -6.55078,0.16846 -0.95117,0.3501 -1.98535,0.79004 -3.05078,1.13477 l 0.85254,1.41602 c -0.91992,-0.31299 -1.83105,-0.60254 -2.3125,-0.32227 -2.29297,0.2876 -1.56348,1.73975 -1.19336,3.5127 0.39941,0.84375 -0.7373,1.61133 0.0332,2.55713 -0.69922,-0.22021 -1.03125,-0.37598 -1.71973,-0.62842 -0.2832,0.60693 2.24316,0.36816 1.4541,1.23145 -0.61523,-0.4292 -1.48145,-0.31592 -2.18066,-0.57178 -0.0391,0.9248 2.34863,1.11572 2.00391,1.89307 -0.47559,0.10303 -1.65918,-1.76855 -2.13672,-0.77539 -0.0967,0.19824 0.61328,0.46436 0.96875,0.59863 -2.30859,-0.3877 -3.91699,0.104 -2.23828,1.95801 -0.73047,-0.26367 -1.56055,-1.09131 -2.36719,-1.22314 l -9.8e-4,0.01855 c 0.36133,0.17285 0.93066,0.625 1.27441,0.76758 l -1.26367,-0.53076 0.0635,0.50781 c 0.27441,0.24463 0.56152,0.46533 0.89258,0.60596 l -0.84692,-0.356 c 0.0898,0.41162 0.2207,0.82373 0.38574,1.22754 0.77832,1.05615 1.52832,2.34668 2.1084,2.57227 4.61721,2.04687 9.96194,3.41552 15.44631,3.59374 z"
+   id="path30" />
+                       </g>
+               </g>
+       </g>
+       <path
+   opacity="0.5"
+   fill-rule="evenodd"
+   clip-rule="evenodd"
+   fill="#d8fcfd"
+   d="M 14.76758,170.56689 C 12.07715,138.42822 11.77588,100.68212 13.86133,57.33642 34.48779,13.45947 34.79004,51.20557 14.76758,170.56689 Z"
+   id="path38" />
+       <g
+   opacity="0.65"
+   id="g42">
+               <path
+   fill-rule="evenodd"
+   clip-rule="evenodd"
+   fill="#d8fcfd"
+   d="M 122.45752,46.8501 C 117.43604,31.20655 30.69678,21.91016 14.34473,21.16114 c -8.69824,-0.39746 -7.396,97.7876 -7.37256,106.81494 0.04297,16.79492 -0.22363,33.86133 1.70752,50.58398 1.88818,16.35547 29.48389,14.19727 43.17676,16.3457 6.24951,0.98242 50.11523,12.59375 42.5752,-2.03711 -8.08252,-15.68555 -16.54004,-12.35156 -31.92773,-11.30664 -3.78174,0.25586 -28.06787,-8.11328 -27.92871,-10.96484 0.04395,-0.91406 15.56152,-7.55664 17.03711,-8.76172 8.35059,-6.82422 8.72998,-15.99414 7.68213,-25.54688 -2.17285,-19.81445 2.98828,-56.21484 8.08203,-71.2085 4.21387,-12.4043 18.42041,32.79883 18.42041,32.79883 0,0 -10.23633,28.68701 -4.43555,47.73975 1.93018,6.33789 6.40674,34.34961 17.83154,32.28711 14.87695,-2.68555 16.0752,-17.03711 17.04297,-27.7832 1.72754,-19.19922 3.30762,-38.41406 4.66016,-57.63916 0.93358,-13.26319 5.74706,-32.59375 1.56151,-45.6333"
+   id="path40" />
+       </g>
+       <g
+   opacity="0.45"
+   id="g52">
+               <g
+   id="g50">
+                       <path
+   fill="none"
+   d="m 100.76514,47.06055 c 6.03027,21.68359 12.05957,81.31787 -2.0083,113.06787"
+   id="path44" />
+                       <g
+   id="g48">
+                               <path
+   fill="#ddfcfd"
+   d="m 95.31689,75.17334 c 0.40283,-0.03271 0.76172,-0.44336 1.0127,0.10254 0.60693,1.74414 -0.60889,3.32227 -0.06934,5.07373 l 0.66113,0.06787 c -0.15039,1.41504 -0.37988,2.89014 -0.55127,4.38623 0.26123,2.70996 0.61523,5.40332 0.979,8.08887 0.23535,-0.08203 0.45264,-0.12695 0.55029,0.13867 0.21631,1.11523 0.04541,2.68262 0.0376,4.29688 l 0.14014,0.70703 c 0.14746,0.17871 0.37891,0.21973 0.52051,0.24512 0.0019,0.73047 -0.02539,1.38281 -0.0874,1.98438 1.42725,7.89307 2.78613,15.99268 3.53613,24.88916 0.4082,1.89844 0.81543,3.82227 0.90283,5.65234 -0.0698,2.68359 -1.06006,5.97656 -1.52051,8.51953 2.35986,-0.0156 2.11719,6.5293 4.65723,5.79883 -0.36475,1.76562 -1.17627,4.36328 -0.6084,4.66797 1.70996,0.92188 3.69043,2.88281 3.10547,8.19531 -0.47607,2.03125 -2.37939,4.66211 -2.27832,5.48633 0.15332,1.31055 2.24219,-1.94336 2.40283,-0.64258 6.57715,-14.46094 7.47461,-28.69531 8.39062,-43.01172 -0.13867,-5.05664 -1.32812,-37.54736 -2.40625,-45.85742 l -0.11719,-0.75244 c -0.37305,-4.55225 -1.3125,-10.05371 -2.84473,-13.74854 -0.8584,-1.67285 -1.75977,-3.33057 -2.77197,-4.98486 -0.19287,0.89941 -0.42236,1.729 -0.68604,2.45264 -0.25195,-1.79639 -0.62549,-3.60645 -1.16016,-4.20605 -1.75439,-3.59717 -2.42578,-1.16113 -3.66699,0.5874 -0.46045,1.16602 -1.77686,0.0063 -2.1333,1.73682 -0.20508,-1.14844 -0.30762,-1.72461 -0.51123,-2.87988 -0.6665,0.0093 1.05664,3.45654 -0.15479,2.87988 0.01,-1.14502 -0.6123,-2.2998 -0.84668,-3.42969 -0.75049,0.57812 0.49756,4.00293 -0.38379,3.99951 -0.32373,-0.56006 0.50293,-3.43066 -0.60596,-3.41064 -0.21826,0.0039 -0.01904,1.14062 0.08154,1.70752 -1.06006,-3.41504 -2.60449,-4.90576 -2.97168,-1.61865 -0.23047,-1.05078 -0.15576,-2.65186 -0.57715,-3.72656 l -0.01465,0.01318 c 0.10352,0.56494 0.12354,1.57764 0.23682,2.09082 l -0.41406,-1.90234 -0.35596,0.44922 c -0.0127,0.50293 0,0.99854 0.10596,1.48926 l -0.27295,-1.25391 -0.72021,1.31299 c -0.30908,1.63574 -0.96582,3.23486 -0.8418,4.07178 0.89505,6.62107 1.57571,13.50534 2.25198,20.33347 z"
+   id="path46" />
+                       </g>
+               </g>
+       </g>
+</g>
+<g
+   id="Layer_2"
+   transform="matrix(0.9,0,0,0.84995245,11.158592,15.562068)">
+</g>
+</svg>
index aff4710..df15026 100644 (file)
@@ -135,6 +135,10 @@ export const ChessRules = class ChessRules {
   static get LoseOnRepetition() {
     return false;
   }
   static get LoseOnRepetition() {
     return false;
   }
+  // And in some others (Iceage), repetitions should be ignored:
+  static get IgnoreRepetition() {
+    return false;
+  }
 
   // At some stages, some games could wait clicks only:
   onlyClick() {
 
   // At some stages, some games could wait clicks only:
   onlyClick() {
index 7bf8e72..cd10d03 100644 (file)
@@ -222,14 +222,15 @@ export const translations = {
   "Friendly pieces": "Friendly pieces",
   "Fusion pieces (v1)": "Fusion pieces (v1)",
   "Fusion pieces (v2)": "Fusion pieces (v2)",
   "Friendly pieces": "Friendly pieces",
   "Fusion pieces (v1)": "Fusion pieces (v1)",
   "Fusion pieces (v2)": "Fusion pieces (v2)",
-  "In the shadow": "In the shadow",
-  "Interweaved colorbound teams": "Interweaved colorbound teams",
   "General's Chess": "General's Chess",
   "Geometric Chess": "Geometric Chess",
   "Get strong at self-mate": "Get strong at self-mate",
   "Give three checks": "Give three checks",
   "Harassed kings": "Harassed kings",
   "Hawaiian Checkers": "Hawaiian Checkers",
   "General's Chess": "General's Chess",
   "Geometric Chess": "Geometric Chess",
   "Get strong at self-mate": "Get strong at self-mate",
   "Give three checks": "Give three checks",
   "Harassed kings": "Harassed kings",
   "Hawaiian Checkers": "Hawaiian Checkers",
+  "Ice Age is coming!": "Ice Age is coming!",
+  "In the shadow": "In the shadow",
+  "Interweaved colorbound teams": "Interweaved colorbound teams",
   "Japanese Chess": "Japanese Chess",
   "Jump the borders": "Jump the borders",
   "Keep antiking in check (v1)": "Keep antiking in check (v1)",
   "Japanese Chess": "Japanese Chess",
   "Jump the borders": "Jump the borders",
   "Keep antiking in check (v1)": "Keep antiking in check (v1)",
index 3154983..11d64a4 100644 (file)
@@ -222,14 +222,15 @@ export const translations = {
   "Friendly pieces": "Piezas amistosas",
   "Fusion pieces (v1)": "Fusionar piezas (v1)",
   "Fusion pieces (v2)": "Fusionar piezas (v2)",
   "Friendly pieces": "Piezas amistosas",
   "Fusion pieces (v1)": "Fusionar piezas (v1)",
   "Fusion pieces (v2)": "Fusionar piezas (v2)",
-  "In the shadow": "En la sombra",
-  "Interweaved colorbound teams": "Equipos unicolores entrelazados",
   "General's Chess": "Ajedrez de los Generales",
   "Geometric Chess": "Ajedrez geométrico",
   "Get strong at self-mate": "Progreso en mates asistidos",
   "Give three checks": "Dar tres jaques",
   "Harassed kings": "Reyes acosados",
   "Hawaiian Checkers": "Damas hawaianas",
   "General's Chess": "Ajedrez de los Generales",
   "Geometric Chess": "Ajedrez geométrico",
   "Get strong at self-mate": "Progreso en mates asistidos",
   "Give three checks": "Dar tres jaques",
   "Harassed kings": "Reyes acosados",
   "Hawaiian Checkers": "Damas hawaianas",
+  "Ice Age is coming!": "¡Se acerca la Edad de Hielo!",
+  "In the shadow": "En la sombra",
+  "Interweaved colorbound teams": "Equipos unicolores entrelazados",
   "Japanese Chess": "Ajedrez japonés",
   "Jump the borders": "Saltar las fronteras",
   "Keep antiking in check (v1)": "Mantener el antirey en jaque (v1)",
   "Japanese Chess": "Ajedrez japonés",
   "Jump the borders": "Saltar las fronteras",
   "Keep antiking in check (v1)": "Mantener el antirey en jaque (v1)",
index a0518ee..4d134fc 100644 (file)
@@ -222,14 +222,15 @@ export const translations = {
   "Friendly pieces": "Pièces amies",
   "Fusion pieces (v1)": "Fusionner les pièces (v1)",
   "Fusion pieces (v2)": "Fusionner les pièces (v2)",
   "Friendly pieces": "Pièces amies",
   "Fusion pieces (v1)": "Fusionner les pièces (v1)",
   "Fusion pieces (v2)": "Fusionner les pièces (v2)",
-  "In the shadow": "Dans l'ombre",
-  "Interweaved colorbound teams": "Équipes unicolores entremêlées",
   "General's Chess": "Échecs des Généraux",
   "Geometric Chess": "Échecs géométriques",
   "Get strong at self-mate": "Progressez en mats aidés",
   "Give three checks": "Donnez trois échecs",
   "Harassed kings": "Rois harcelés",
   "Hawaiian Checkers": "Dames hawaïennes",
   "General's Chess": "Échecs des Généraux",
   "Geometric Chess": "Échecs géométriques",
   "Get strong at self-mate": "Progressez en mats aidés",
   "Give three checks": "Donnez trois échecs",
   "Harassed kings": "Rois harcelés",
   "Hawaiian Checkers": "Dames hawaïennes",
+  "Ice Age is coming!": "L'Âge de Glace arrive !",
+  "In the shadow": "Dans l'ombre",
+  "Interweaved colorbound teams": "Équipes unicolores entremêlées",
   "Japanese Chess": "Échecs japonais",
   "Jump the borders": "Sauter les frontières",
   "Keep antiking in check (v1)": "Gardez l'antiroi en échec (v1)",
   "Japanese Chess": "Échecs japonais",
   "Jump the borders": "Sauter les frontières",
   "Keep antiking in check (v1)": "Gardez l'antiroi en échec (v1)",
diff --git a/client/src/translations/rules/Iceage/en.pug b/client/src/translations/rules/Iceage/en.pug
new file mode 100644 (file)
index 0000000..fbcac3c
--- /dev/null
@@ -0,0 +1,43 @@
+p.boxed
+  | Every 20 moves, most empty squares freeze and isolated pieces vanish.
+
+p
+  | Ice Age is a 
+  a(href="https://www.chessvariants.com/boardrules.dir/iceage.html")
+    | chess variant
+  | &nbsp;invented by Köksal Karakus in 2000.
+  | It can also be played on 
+  a(href="https://brainking.com/en/GameRules?tp=100") brainking.com
+  | .
+
+figure.diagram-container
+  .diagram
+    | fen:rnbqkbnr/pppppppp/cccccccc/cccccccc/cccccccc/cccccccc/PPPPPPPP/RNBQKBNR:
+  figcaption Deterministic initial position
+
+p.
+  If the board is filled with ice cubes, you can only move by capturing them.
+  Ice cubes behave as normal pieces, which cannot move.
+
+p.
+  Just after the 20th black move (and before the 21st white one),
+  "ice age is coming":
+ul
+  li all empty squares freeze, except those orthogonally surrounded by pieces.
+  li all pieces which are not adjacent to any other piece (black or white) vanish.
+p.
+  If only one king remains, the other side loses.
+  But if both disappeared, then the result is a draw.
+
+figure.diagram-container
+  .diagram.diag12
+    | fen:2rq1rk1/3bpp2/1c1p1bP1/1p2n3/4P2P/1NN2P1c/PPPQ4/1K1R3R:
+  .diagram.diag22
+    | fen:cccq1rkc/cccbppcc/cccp1bPc/ccccnccc/ccccPccc/cNrccPcc/PPPQcccc/1K1Rcccc:
+  figcaption Before and after 20...Rxc3
+
+p.
+  Then, every 20 moves ice age comes again: after move 40, 60, and so on.
+  This condition excepted, the game follows FIDE chess rules, without draws
+  on repetition: indeed, as the author notices, sometimes a win is possible
+  by "waiting until the enemy king freezes".
diff --git a/client/src/translations/rules/Iceage/es.pug b/client/src/translations/rules/Iceage/es.pug
new file mode 100644 (file)
index 0000000..0332843
--- /dev/null
@@ -0,0 +1,48 @@
+p.boxed
+  | Cada 20 movimientos, la mayoría de las casillas vacías se congelan
+  | y las piezas aisladas desaparecen.
+
+p
+  | Ice Age es 
+  a(href="https://www.chessvariants.com/boardrules.dir/iceage.html")
+    | una variante
+  | &nbsp;inventado por Köksal Karakus en 2000.
+  | También puedes jugarlo en 
+  a(href="https://brainking.com/en/GameRules?tp=100") brainking.com
+  | .
+
+figure.diagram-container
+  .diagram
+    | fen:rnbqkbnr/pppppppp/cccccccc/cccccccc/cccccccc/cccccccc/PPPPPPPP/RNBQKBNR:
+  figcaption Posición inicial determinista
+
+p.
+  Si el tablero está lleno de bloques de hielo, solo puedes mover
+  capturarlos. Se comportan como piezas estacionarias normales.
+
+p.
+  Inmediatamente después del 20mo movimiento negro (y antes del 20mo
+  movimiento blanco), "la edad de hielo se acerca":
+ul
+  li.
+    todas las casillas vacías se congelan,
+    excepto aquellas rodeadas ortogonalmente por piezas.
+  li.
+    todas las piezas que no están adyacentes a otra habitación
+    (amigo o enemigo) desaparece.
+p.
+  Si solo queda un rey, el otro lado pierde.
+  Pero si ambos se van, entonces el juego es un empate.
+
+figure.diagram-container
+  .diagram.diag12
+    | fen:2rq1rk1/3bpp2/1c1p1bP1/1p2n3/4P2P/1NN2P1c/PPPQ4/1K1R3R:
+  .diagram.diag22
+    | fen:cccq1rkc/cccbppcc/cccp1bPc/ccccnccc/ccccPccc/cNrccPcc/PPPQcccc/1K1Rcccc:
+  figcaption Antes y después de 20...Rxc3
+
+p.
+  Luego, cada 20 jugadas regresa la edad de hielo: después del 40, 60,
+  etc. Salvo esta condición, el juego sigue las reglas de ajedrez de la FIDE,
+  sin los empates por repetición: de hecho, como señala el autor,
+  a veces puedes ganar "esperando que el rey contrario se congele".
diff --git a/client/src/translations/rules/Iceage/fr.pug b/client/src/translations/rules/Iceage/fr.pug
new file mode 100644 (file)
index 0000000..8f285b7
--- /dev/null
@@ -0,0 +1,48 @@
+p.boxed
+  | Tous les 20 coups, la plupart des cases vides gèlent
+  | et les pièces isolées disparaissent.
+
+p
+  | Ice Age est 
+  a(href="https://www.chessvariants.com/boardrules.dir/iceage.html")
+    | une variante
+  | &nbsp;inventée par Köksal Karakus en 2000.
+  | On peut aussi y jouer sur 
+  a(href="https://brainking.com/en/GameRules?tp=100") brainking.com
+  | .
+
+figure.diagram-container
+  .diagram
+    | fen:rnbqkbnr/pppppppp/cccccccc/cccccccc/cccccccc/cccccccc/PPPPPPPP/RNBQKBNR:
+  figcaption Position initiale déterministe
+
+p.
+  Si l'échiquier est rempli de blocs de glace, vous ne pouvez bougez qu'en
+  les capturant. Ceux-ci se comportent comme des pièces normales, immobiles.
+
+p.
+  Immédiatement après le 20eme coup noir (et avant le 21 coup blanc),
+  "l'âge de glace arrive" :
+ul
+  li.
+    toutes les cases vides gèlent,
+    sauf celles orthogonalement entourées de pièces.
+  li.
+    toutes les pièces qui ne sont pas adjacentes à une autre pièce
+    (amie ou ennemie) disparaissent.
+p.
+  Si un seul roi subsiste, l'autre camp perd.
+  Mais si les deux ont disparu, alors la partie est nulle.
+
+figure.diagram-container
+  .diagram.diag12
+    | fen:2rq1rk1/3bpp2/1c1p1bP1/1p2n3/4P2P/1NN2P1c/PPPQ4/1K1R3R:
+  .diagram.diag22
+    | fen:cccq1rkc/cccbppcc/cccp1bPc/ccccnccc/ccccPccc/cNrccPcc/PPPQcccc/1K1Rcccc:
+  figcaption Avant et après 20...Rxc3
+
+p.
+  Ensuite, tous les 20 coups l'âge de glace revient : après le 40eme, 60eme,
+  etc. Cette condition exceptée, la partie suit les règles FIDE des échecs,
+  sans les nulles par répétition : en effet, comme l'auteur le fait remarquer,
+  on peut parfois gagner en "attendant que le roi adverse gèle".
index 2c14ba6..a895843 100644 (file)
@@ -467,6 +467,7 @@ p.
     "Fusion",
     "Gridolina",
     "Hamilton",
     "Fusion",
     "Gridolina",
     "Hamilton",
+    "Iceage",
     "Kingsmaker",
     "Magnetic",
     "Refusal",
     "Kingsmaker",
     "Magnetic",
     "Refusal",
index 69756b1..609ac03 100644 (file)
@@ -477,6 +477,7 @@ p.
     "Fusion",
     "Gridolina",
     "Hamilton",
     "Fusion",
     "Gridolina",
     "Hamilton",
+    "Iceage",
     "Kingsmaker",
     "Magnetic",
     "Refusal",
     "Kingsmaker",
     "Magnetic",
     "Refusal",
index 91585e9..6c84697 100644 (file)
@@ -475,6 +475,7 @@ p.
     "Fusion",
     "Gridolina",
     "Hamilton",
     "Fusion",
     "Gridolina",
     "Hamilton",
+    "Iceage",
     "Kingsmaker",
     "Magnetic",
     "Refusal",
     "Kingsmaker",
     "Magnetic",
     "Refusal",
diff --git a/client/src/variants/Iceage.js b/client/src/variants/Iceage.js
new file mode 100644 (file)
index 0000000..01f82d8
--- /dev/null
@@ -0,0 +1,143 @@
+import { ChessRules } from "@/base_rules";
+
+export class IceageRules extends ChessRules {
+
+  static get IgnoreRepetition() {
+    return true;
+  }
+
+  static get ICECUBE() {
+    return "cc";
+  }
+
+  static board2fen(b) {
+    if (b[0] == 'c') return 'c';
+    return ChessRules.board2fen(b);
+  }
+
+  static fen2board(f) {
+    if (f == 'c') return V.ICECUBE;
+    return ChessRules.fen2board(f);
+  }
+
+  getPpath(b) {
+    if (b[0] == 'c') return "Iceage/icecube";
+    return b;
+  }
+
+  static IsGoodPosition(position) {
+    if (position.length == 0) return false;
+    const rows = position.split("/");
+    if (rows.length != V.size.x) return false;
+    let kings = { "k": 0, "K": 0 };
+    for (let row of rows) {
+      let sumElts = 0;
+      for (let i = 0; i < row.length; i++) {
+        if (['K','k'].includes(row[i])) kings[row[i]]++;
+        if (['c'].concat(V.PIECES).includes(row[i].toLowerCase())) sumElts++;
+        else {
+          const num = parseInt(row[i], 10);
+          if (isNaN(num)) return false;
+          sumElts += num;
+        }
+      }
+      if (sumElts != V.size.y) return false;
+    }
+    if (Object.values(kings).some(v => v != 1)) return false;
+    return true;
+  }
+
+  static GenRandInitFen(randomness) {
+    return ChessRules.GenRandInitFen(randomness).replace(/8/g, "cccccccc");
+  }
+
+  play(move) {
+    const iceAgeAfterMove = (this.movesCount % 40 == 39);
+    if (iceAgeAfterMove)
+      // Next ice age after this move:
+      move.state = JSON.stringify(this.board);
+    super.play(move);
+    if (iceAgeAfterMove) {
+      for (let i=0; i<8; i++) {
+        for (let j=0; j<8; j++) {
+          if (this.board[i][j] == V.EMPTY) {
+            const surrounded = V.steps[V.ROOK].every(s => {
+              const [ii, jj] = [i + s[0], j + s[1]];
+              return (
+                !V.OnBoard(ii, jj) ||
+                ![V.EMPTY, V.ICECUBE].includes(this.board[ii][jj])
+              );
+            });
+            if (!surrounded) this.board[i][j] = V.ICECUBE;
+          }
+          else if (this.board[i][j] != V.ICECUBE) {
+            const steps = V.steps[V.ROOK].concat(V.steps[V.BISHOP]);
+            const connected = steps.some(s => {
+              const [ii, jj] = [i + s[0], j + s[1]];
+              return (
+                V.OnBoard(ii, jj) &&
+                ![V.EMPTY, V.ICECUBE].includes(this.board[ii][jj])
+              );
+            });
+            if (!connected) this.board[i][j] = V.ICECUBE;
+          }
+        }
+      }
+      // Update king position (no need to update flags: game over)
+      const kp = this.kingPos;
+      if (this.getPiece(kp['w'][0], kp['w'][1]) != V.KING)
+        this.kingPos['w'] = [-1, -1];
+      if (this.getPiece(kp['b'][0], kp['b'][1]) != V.KING)
+        this.kingPos['b'] = [-1, -1];
+    }
+  }
+
+  undo(move) {
+    super.undo(move);
+    if (!!move.state) {
+      this.board = JSON.parse(move.state);
+      if (this.kingPos['w'][0] < 0 || this.kingPos['b'][0] < 0) {
+        for (let i=0; i<8; i++) {
+          for (let j=0; j<8; j++) {
+            if (this.board[i][j] != V.EMPTY && this.getPiece(i, j) == V.KING)
+              this.kingPos[this.getColor(i, j)] = [i, j];
+          }
+        }
+      }
+    }
+  }
+
+  getCheckSquares() {
+    if (this.kingPos[this.turn][0] < 0) return [];
+    return super.getCheckSquares();
+  }
+
+  getCurrentScore() {
+    const kingDisappear = {
+      w: this.kingPos['w'][0] < 0,
+      b: this.kingPos['b'][0] < 0
+    };
+    if (kingDisappear['w'] && kingDisappear['b']) return "1/2";
+    if (kingDisappear['w']) return "0-1";
+    if (kingDisappear['b']) return "1-0";
+    return super.getCurrentScore();
+  }
+
+  static get SEARCH_DEPTH() {
+    return 2;
+  }
+
+  evalPosition() {
+    let evaluation = 0;
+    for (let i = 0; i < V.size.x; i++) {
+      for (let j = 0; j < V.size.y; j++) {
+        if (![V.EMPTY,V.ICECUBE].includes(this.board[i][j])) {
+          const sign = this.getColor(i, j) == "w" ? 1 : -1;
+          evaluation += sign * V.VALUES[this.getPiece(i, j)];
+        }
+      }
+    }
+    return evaluation;
+  }
+
+};
index 6aea261..65d4646 100644 (file)
@@ -1406,18 +1406,20 @@ export default {
           // In corr games, just reset clock to mainTime:
           this.game.clocks[colorIdx] = extractTime(this.game.cadence).mainTime;
         }
           // In corr games, just reset clock to mainTime:
           this.game.clocks[colorIdx] = extractTime(this.game.cadence).mainTime;
         }
-        // If repetition detected, consider that a draw offer was received:
-        const fenObj = this.vr.getFenForRepeat();
-        this.repeat[fenObj] =
-          !!this.repeat[fenObj]
-            ? this.repeat[fenObj] + 1
-            : 1;
-        if (this.repeat[fenObj] >= 3) {
-          if (V.LoseOnRepetition)
-            this.gameOver(moveCol == "w" ? "0-1" : "1-0", "Repetition");
-          else this.drawOffer = "threerep";
+        if (!V.IgnoreRepetition) {
+          // If repetition detected, consider that a draw offer was received:
+          const fenObj = this.vr.getFenForRepeat();
+          this.repeat[fenObj] =
+            !!this.repeat[fenObj]
+              ? this.repeat[fenObj] + 1
+              : 1;
+          if (this.repeat[fenObj] >= 3) {
+            if (V.LoseOnRepetition)
+              this.gameOver(moveCol == "w" ? "0-1" : "1-0", "Repetition");
+            else this.drawOffer = "threerep";
+          }
+          else if (this.drawOffer == "threerep") this.drawOffer = "";
         }
         }
-        else if (this.drawOffer == "threerep") this.drawOffer = "";
         if (!!this.game.mycolor && !data.receiveMyMove) {
           // NOTE: 'var' to see that variable outside this block
           var filtered_move = getFilteredMove(move);
         if (!!this.game.mycolor && !data.receiveMyMove) {
           // NOTE: 'var' to see that variable outside this block
           var filtered_move = getFilteredMove(move);
index 5648379..9b7842b 100644 (file)
@@ -80,6 +80,7 @@ insert or ignore into Variants (name, description) values
   ('Hoppelpoppel', 'Knibis and Bisknis'),
   ('Horde', 'A pawns cloud'),
   ('Hypnotic', 'Mind control (v1)'),
   ('Hoppelpoppel', 'Knibis and Bisknis'),
   ('Horde', 'A pawns cloud'),
   ('Hypnotic', 'Mind control (v1)'),
+  ('Iceage', 'Ice Age is coming!'),
   ('Interweave', 'Interweaved colorbound teams'),
   ('Isardam', 'No paralyzed pieces'),
   ('Janggi', 'Korean Chess'),
   ('Interweave', 'Interweaved colorbound teams'),
   ('Isardam', 'No paralyzed pieces'),
   ('Janggi', 'Korean Chess'),