From f0a812b7b11bc2a1514d2aa10ecc257d10d988d5 Mon Sep 17 00:00:00 2001 From: Benjamin Auder <benjamin.auder@somewhere> Date: Tue, 26 Jan 2021 23:11:44 +0100 Subject: [PATCH] Add Ice Age Chess --- client/public/images/pieces/Iceage/SOURCE | 1 + .../public/images/pieces/Iceage/icecube.svg | 163 ++++++++++++++++++ client/src/base_rules.js | 4 + client/src/translations/en.js | 5 +- client/src/translations/es.js | 5 +- client/src/translations/fr.js | 5 +- client/src/translations/rules/Iceage/en.pug | 43 +++++ client/src/translations/rules/Iceage/es.pug | 48 ++++++ client/src/translations/rules/Iceage/fr.pug | 48 ++++++ client/src/translations/variants/en.pug | 1 + client/src/translations/variants/es.pug | 1 + client/src/translations/variants/fr.pug | 1 + client/src/variants/Iceage.js | 143 +++++++++++++++ client/src/views/Game.vue | 24 +-- server/db/populate.sql | 1 + 15 files changed, 476 insertions(+), 17 deletions(-) create mode 100644 client/public/images/pieces/Iceage/SOURCE create mode 100644 client/public/images/pieces/Iceage/icecube.svg create mode 100644 client/src/translations/rules/Iceage/en.pug create mode 100644 client/src/translations/rules/Iceage/es.pug create mode 100644 client/src/translations/rules/Iceage/fr.pug create mode 100644 client/src/variants/Iceage.js diff --git a/client/public/images/pieces/Iceage/SOURCE b/client/public/images/pieces/Iceage/SOURCE new file mode 100644 index 00000000..764be1fc --- /dev/null +++ b/client/public/images/pieces/Iceage/SOURCE @@ -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 index 00000000..b3de8f91 --- /dev/null +++ b/client/public/images/pieces/Iceage/icecube.svg @@ -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> diff --git a/client/src/base_rules.js b/client/src/base_rules.js index aff47109..df150262 100644 --- a/client/src/base_rules.js +++ b/client/src/base_rules.js @@ -135,6 +135,10 @@ export const ChessRules = class ChessRules { 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() { diff --git a/client/src/translations/en.js b/client/src/translations/en.js index 7bf8e720..cd10d039 100644 --- a/client/src/translations/en.js +++ b/client/src/translations/en.js @@ -222,14 +222,15 @@ export const translations = { "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", + "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)", diff --git a/client/src/translations/es.js b/client/src/translations/es.js index 3154983b..11d64a48 100644 --- a/client/src/translations/es.js +++ b/client/src/translations/es.js @@ -222,14 +222,15 @@ export const translations = { "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", + "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)", diff --git a/client/src/translations/fr.js b/client/src/translations/fr.js index a0518ee3..4d134fc2 100644 --- a/client/src/translations/fr.js +++ b/client/src/translations/fr.js @@ -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)", - "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", + "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)", diff --git a/client/src/translations/rules/Iceage/en.pug b/client/src/translations/rules/Iceage/en.pug new file mode 100644 index 00000000..fbcac3ca --- /dev/null +++ b/client/src/translations/rules/Iceage/en.pug @@ -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 + | 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 index 00000000..03328437 --- /dev/null +++ b/client/src/translations/rules/Iceage/es.pug @@ -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 + | 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 index 00000000..8f285b73 --- /dev/null +++ b/client/src/translations/rules/Iceage/fr.pug @@ -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 + | 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". diff --git a/client/src/translations/variants/en.pug b/client/src/translations/variants/en.pug index 2c14ba6d..a895843b 100644 --- a/client/src/translations/variants/en.pug +++ b/client/src/translations/variants/en.pug @@ -467,6 +467,7 @@ p. "Fusion", "Gridolina", "Hamilton", + "Iceage", "Kingsmaker", "Magnetic", "Refusal", diff --git a/client/src/translations/variants/es.pug b/client/src/translations/variants/es.pug index 69756b12..609ac032 100644 --- a/client/src/translations/variants/es.pug +++ b/client/src/translations/variants/es.pug @@ -477,6 +477,7 @@ p. "Fusion", "Gridolina", "Hamilton", + "Iceage", "Kingsmaker", "Magnetic", "Refusal", diff --git a/client/src/translations/variants/fr.pug b/client/src/translations/variants/fr.pug index 91585e93..6c846970 100644 --- a/client/src/translations/variants/fr.pug +++ b/client/src/translations/variants/fr.pug @@ -475,6 +475,7 @@ p. "Fusion", "Gridolina", "Hamilton", + "Iceage", "Kingsmaker", "Magnetic", "Refusal", diff --git a/client/src/variants/Iceage.js b/client/src/variants/Iceage.js new file mode 100644 index 00000000..01f82d85 --- /dev/null +++ b/client/src/variants/Iceage.js @@ -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; + } + +}; diff --git a/client/src/views/Game.vue b/client/src/views/Game.vue index 6aea261e..65d46460 100644 --- a/client/src/views/Game.vue +++ b/client/src/views/Game.vue @@ -1406,18 +1406,20 @@ export default { // 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); diff --git a/server/db/populate.sql b/server/db/populate.sql index 56483794..9b7842be 100644 --- a/server/db/populate.sql +++ b/server/db/populate.sql @@ -80,6 +80,7 @@ insert or ignore into Variants (name, description) values ('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'), -- 2.48.1