First draft of S-chess variant + a few fixes
authorBenjamin Auder <benjamin.auder@somewhere>
Sun, 22 Mar 2020 03:10:46 +0000 (04:10 +0100)
committerBenjamin Auder <benjamin.auder@somewhere>
Sun, 22 Mar 2020 03:10:46 +0000 (04:10 +0100)
22 files changed:
TODO
client/public/images/pieces/Schess/be.svg [new file with mode: 0644]
client/public/images/pieces/Schess/bh.svg [new file with mode: 0644]
client/public/images/pieces/Schess/we.svg [new file with mode: 0644]
client/public/images/pieces/Schess/wh.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/Ball/en.pug
client/src/translations/rules/Ball/es.pug
client/src/translations/rules/Ball/fr.pug
client/src/translations/rules/Schess/en.pug [new file with mode: 0644]
client/src/translations/rules/Schess/es.pug [new file with mode: 0644]
client/src/translations/rules/Schess/fr.pug [new file with mode: 0644]
client/src/variants/Ball.js
client/src/variants/Cannibal.js
client/src/variants/Checkered.js
client/src/variants/Schess.js [new file with mode: 0644]
client/src/variants/Twokings.js
client/src/views/Hall.vue
server/db/populate.sql

diff --git a/TODO b/TODO
index 4a63843..1a566ad 100644 (file)
--- a/TODO
+++ b/TODO
@@ -2,8 +2,6 @@
 Landing pieces from empty board:
 https://www.chessvariants.com/diffsetup.dir/unachess.html
 
 Landing pieces from empty board:
 https://www.chessvariants.com/diffsetup.dir/unachess.html
 
-S-chess https://en.wikipedia.org/wiki/Seirawan_chess
-
 Generator variant, called "Matrix" ?
 Peces on first rank never move but generate new pieces. Pawn don't generate.
 A generator captured and replaced by a similar piece does not generate.
 Generator variant, called "Matrix" ?
 Peces on first rank never move but generate new pieces. Pawn don't generate.
 A generator captured and replaced by a similar piece does not generate.
diff --git a/client/public/images/pieces/Schess/be.svg b/client/public/images/pieces/Schess/be.svg
new file mode 100644 (file)
index 0000000..5868980
--- /dev/null
@@ -0,0 +1,177 @@
+<?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:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="177.17"
+   height="177.17"
+   shape-rendering="geometricPrecision"
+   image-rendering="optimizeQuality"
+   fill-rule="evenodd"
+   clip-rule="evenodd"
+   viewBox="0 0 50 50"
+   version="1.1"
+   id="svg12863"
+   sodipodi:docname="BE.svg"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
+  <metadata
+     id="metadata12867">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="958"
+     inkscape:window-height="1008"
+     id="namedview12865"
+     showgrid="false"
+     showguides="false"
+     inkscape:zoom="1.7295106"
+     inkscape:cx="113.03876"
+     inkscape:cy="25.507445"
+     inkscape:window-x="953"
+     inkscape:window-y="0"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="g13475" />
+  <defs
+     id="defs12857">
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient7924">
+      <stop
+         style="stop-color:#bdbdbd;stop-opacity:1"
+         offset="0"
+         id="stop7920" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="1"
+         id="stop7922" />
+    </linearGradient>
+    <linearGradient
+       id="0"
+       x1="21.405"
+       x2="77.64"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         stop-color="#fff"
+         id="stop12852" />
+      <stop
+         offset="1"
+         stop-color="#fff"
+         stop-opacity="0"
+         id="stop12854" />
+    </linearGradient>
+    <linearGradient
+       gradientTransform="matrix(-0.1675513,0,0,0.13095695,124.76512,-29.396941)"
+       inkscape:collect="always"
+       xlink:href="#linearGradient15233"
+       id="linearGradient15235"
+       x1="233.09853"
+       y1="541.73389"
+       x2="313.64203"
+       y2="543.00366"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient15233">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop15229" />
+      <stop
+         style="stop-color:#808080;stop-opacity:1"
+         offset="1"
+         id="stop15231" />
+    </linearGradient>
+    <linearGradient
+       gradientTransform="matrix(0.9198676,0,0,0.9198676,70.368497,62.093614)"
+       id="0-9"
+       x1="21.405001"
+       x2="77.639999"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         stop-color="#fff"
+         id="stop832" />
+      <stop
+         offset="1"
+         stop-color="#fff"
+         stop-opacity="0"
+         id="stop834" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient7924"
+       id="linearGradient7926"
+       x1="72.16153"
+       y1="60.468464"
+       x2="102.88117"
+       y2="61.068867"
+       gradientUnits="userSpaceOnUse" />
+  </defs>
+  <g
+     id="g13475"
+     transform="matrix(1.087113,0,0,1.087113,-73.92342,-28.092572)">
+    <g
+       id="g3742"
+       transform="matrix(1.0010156,0,0,0.96471961,1.3426644,4.4892019)"
+       style="stroke-width:1.29800129;stroke-miterlimit:4;stroke-dasharray:none">
+      <path
+         sodipodi:nodetypes="ccccccccccccccccccsccccscc"
+         inkscape:connector-curvature="0"
+         id="path15217"
+         d="m 80.170737,65.446865 c 7.959966,0.05175 12.863181,0.134926 20.764343,0.173751 -0.0313,-1.787287 -0.57046,-3.574566 -1.564593,-5.361853 3.335183,-5.444552 2.470753,-8.628563 -0.601773,-10.817777 -1.497374,-2.28856 -2.816741,-4.697661 -4.934499,-7.713548 -2.194464,-1.576302 -4.89172,-2.984182 -6.378752,-4.797452 -0.910852,-1.833367 -0.488519,-2.972058 1.323892,-3.386435 4.4914,0.357556 2.357004,3.951786 2.768138,6.302535 7.43243,5.383284 10.365377,-0.813629 10.109717,-3.010167 -0.78922,-0.387682 -1.30908,0.386374 -2.116516,0.813351 -0.679496,-0.410687 -1.206499,-0.547042 -1.855162,-0.531147 -1.165715,0.697219 -0.911748,1.138135 -1.27192,1.992758 1.068542,-6.140328 -0.411256,-10.15656 -8.717439,-10.646984 -5.267627,0.497669 -7.800554,3.231384 -8.417453,7.895978 0.719979,0.470339 1.479558,0.907418 1.557299,1.510788 -0.109149,1.972593 0.950229,4.059356 1.684938,6.114398 l -0.764677,0.458925 0.170216,1.173483 c 0.136101,0.319128 0.923481,-0.368319 1.168278,-0.06651 0.303052,0.373609 0.633202,2.346961 0.569544,2.620121 -0.970882,-2.521911 -3.434646,-3.945637 -5.716799,-5.50296 -1.031381,-1.196133 -2.44949,-2.18241 -2.486529,-1.568473 0.348905,1.779496 1.051645,4.586961 2.447877,7.432109 -0.115746,2.689798 -0.674193,5.073016 -0.202043,7.682109 0.667915,3.690864 2.621218,4.742331 2.463913,9.233005 z"
+         style="fill:#1f1a17;fill-opacity:1;stroke:#1f1a17;stroke-width:1.58502242;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+      <path
+         sodipodi:nodetypes="cccc"
+         inkscape:connector-curvature="0"
+         id="path15219"
+         d="m 85.617775,45.612152 c -0.949811,3.856625 -1.96871,4.338269 -3.346087,4.685844 -6.222,-8.589631 -5.974098,-14.325406 -4.057871,-16.292866 1.898378,3.33009 3.710947,9.102032 7.403958,11.607022 z"
+         style="fill:url(#linearGradient15235);fill-opacity:1;stroke:#1f1a17;stroke-width:1.58502242;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+      <ellipse
+         transform="scale(-1,1)"
+         ry="1.30557"
+         rx="0.67696226"
+         cy="46.857224"
+         cx="-93.159279"
+         id="path15267"
+         style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.29800129;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.98431373;paint-order:normal" />
+      <path
+         sodipodi:nodetypes="ccc"
+         inkscape:connector-curvature="0"
+         id="path18972"
+         d="m 99.208344,53.500595 c 1.622596,2.882086 3.961876,5.732799 4.393136,11.337916 -5.232241,-1.86886 -1.39599,-0.545523 -4.680756,-0.751623"
+         style="fill:#1f1a17;fill-opacity:1;stroke:#1f1a17;stroke-width:1.58502242;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+      <path
+         sodipodi:nodetypes="cc"
+         inkscape:connector-curvature="0"
+         id="path19000"
+         d="m 101.47622,56.506134 -2.267876,-3.00554"
+         style="fill:#2b0000;stroke:#ffffff;stroke-width:1.58502242;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+      <path
+         sodipodi:nodetypes="ccc"
+         inkscape:connector-curvature="0"
+         id="path19002"
+         d="M 101.42685,64.206224 C 98.936706,63.34891 92.454719,64.31533 87.895907,64.715496 89.57682,62.663941 89.716729,59.58505 89.890762,56.528908"
+         style="fill:none;fill-opacity:1;stroke:url(#linearGradient7926);stroke-width:1.58502242;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    </g>
+  </g>
+</svg>
diff --git a/client/public/images/pieces/Schess/bh.svg b/client/public/images/pieces/Schess/bh.svg
new file mode 100644 (file)
index 0000000..da18014
--- /dev/null
@@ -0,0 +1,118 @@
+<?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"
+   width="177.17"
+   height="177.17"
+   shape-rendering="geometricPrecision"
+   image-rendering="optimizeQuality"
+   fill-rule="evenodd"
+   clip-rule="evenodd"
+   viewBox="0 0 50 50"
+   version="1.1"
+   id="svg12863"
+   sodipodi:docname="BH.svg"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
+  <metadata
+     id="metadata12867">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <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="1017"
+     id="namedview12865"
+     showgrid="false"
+     showguides="false"
+     inkscape:zoom="2.8284271"
+     inkscape:cx="182.47608"
+     inkscape:cy="55.534186"
+     inkscape:window-x="-8"
+     inkscape:window-y="-8"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="g13475" />
+  <defs
+     id="defs12857">
+    <linearGradient
+       id="0"
+       x1="21.405"
+       x2="77.64"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         stop-color="#fff"
+         id="stop12852" />
+      <stop
+         offset="1"
+         stop-color="#fff"
+         stop-opacity="0"
+         id="stop12854" />
+    </linearGradient>
+  </defs>
+  <g
+     id="g13475"
+     transform="matrix(1.087113,0,0,1.087113,-73.92342,-28.092572)">
+    <g
+       id="g3155"
+       transform="matrix(0.97074389,0,0,0.97074389,2.6622636,3.5031888)">
+      <g
+         transform="matrix(0.99867819,0,0,1.060145,0.12021655,-3.9657669)"
+         id="g3145">
+        <path
+           sodipodi:nodetypes="cccccccccccccccccccc"
+           inkscape:connector-curvature="0"
+           id="path13430"
+           d="m 84.568171,35.093828 -6.217144,0.149811 c -6.203086,2.383935 -6.962587,5.934352 -4.793947,10.112228 -0.05331,-4.629564 3.609449,-3.313402 6.366959,-3.445648 9.559786,5.46999 4.25599,14.805717 -0.599244,18.426723 l 4.419419,0.449433 -0.524338,3.07112 4.269605,-2.92131 2.696594,3.520551 3.895081,-2.92131 1.573012,2.621691 2.022444,-2.696597 c 1.307039,1.013938 2.064854,2.354644 2.627738,3.526604 l 1.86659,-3.226981 c 1.23104,0.812023 1.87638,2.044599 2.8464,3.07112 v -4.119794 l 4.41942,2.621688 C 110.0094,46.435659 108.3116,35.260707 95.504357,31.573276 92.79365,31.513132 90.012856,31.228707 87.639293,32.247423 Z"
+           style="fill:#1f1a17;fill-opacity:1;stroke:#1f1a17;stroke-width:1.69328892;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+        <path
+           sodipodi:nodetypes="cc"
+           inkscape:connector-curvature="0"
+           id="path13434"
+           d="m 83.103812,35.805085 c -0.02515,1.008854 0.490503,1.148881 1.112288,1.324152"
+           style="fill:#ffffff;stroke:#ffffff;stroke-width:1.29800129;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+        <path
+           transform="rotate(-3.1672079)"
+           d="m 91.413755,41.973846 a 2.5158896,1.8273305 0 0 1 -1.307932,1.602928 2.5158896,1.8273305 0 0 1 -2.563889,-0.0637 2.5158896,1.8273305 0 0 1 -1.154078,-1.664092 l 2.510009,0.124859 z"
+           sodipodi:end="3.2099747"
+           sodipodi:start="0"
+           sodipodi:ry="1.8273305"
+           sodipodi:rx="2.5158896"
+           sodipodi:cy="41.973846"
+           sodipodi:cx="88.897865"
+           sodipodi:type="arc"
+           id="path13436"
+           style="opacity:1;fill:#ffffff;fill-opacity:0.98431373;stroke:#ffffff;stroke-width:1.69328892;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.98431373;paint-order:normal" />
+        <path
+           inkscape:connector-curvature="0"
+           id="path13438"
+           d="m 93.644067,36.864407 3.760592,-0.423729"
+           style="fill:#ffffff;stroke:#ffffff;stroke-width:1.69328892;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+      </g>
+      <path
+         sodipodi:nodetypes="ccccc"
+         inkscape:connector-curvature="0"
+         id="path3147"
+         d="m 79.742662,41.383025 c 0.310502,0.194594 0.639867,0.423478 1.021127,0.70652 l 10.764209,2.445766 0.131338,-0.769265 z"
+         style="fill:#ffffff;stroke:none;stroke-width:0.25960028px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    </g>
+  </g>
+</svg>
diff --git a/client/public/images/pieces/Schess/we.svg b/client/public/images/pieces/Schess/we.svg
new file mode 100644 (file)
index 0000000..05f8ffa
--- /dev/null
@@ -0,0 +1,201 @@
+<?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:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="177.17"
+   height="177.17"
+   shape-rendering="geometricPrecision"
+   image-rendering="optimizeQuality"
+   fill-rule="evenodd"
+   clip-rule="evenodd"
+   viewBox="0 0 50 50"
+   version="1.1"
+   id="svg12863"
+   sodipodi:docname="WE.svg"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
+  <metadata
+     id="metadata12867">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="960"
+     inkscape:window-height="1017"
+     id="namedview12865"
+     showgrid="false"
+     showguides="false"
+     inkscape:zoom="1.7295106"
+     inkscape:cx="41.727425"
+     inkscape:cy="216.44851"
+     inkscape:window-x="952"
+     inkscape:window-y="-8"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="g13475" />
+  <defs
+     id="defs12857">
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient18986">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="0"
+         id="stop18982" />
+      <stop
+         style="stop-color:#999999;stop-opacity:1"
+         offset="1"
+         id="stop18984" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient18978">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="0"
+         id="stop18974" />
+      <stop
+         style="stop-color:#808080;stop-opacity:1"
+         offset="1"
+         id="stop18976" />
+    </linearGradient>
+    <linearGradient
+       id="0"
+       x1="21.405"
+       x2="77.64"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         stop-color="#fff"
+         id="stop12852" />
+      <stop
+         offset="1"
+         stop-color="#fff"
+         stop-opacity="0"
+         id="stop12854" />
+    </linearGradient>
+    <linearGradient
+       gradientTransform="matrix(0.18388585,0,0,0.14372393,52.70999,-34.229473)"
+       inkscape:collect="always"
+       xlink:href="#linearGradient15233"
+       id="linearGradient15235"
+       x1="263.8862"
+       y1="556.02753"
+       x2="226.60266"
+       y2="613.10144"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient15233">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop15229" />
+      <stop
+         style="stop-color:#808080;stop-opacity:1"
+         offset="1"
+         id="stop15231" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient18978"
+       id="linearGradient18980"
+       x1="99.346107"
+       y1="53.234913"
+       x2="78.265686"
+       y2="53.234913"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient18986"
+       id="linearGradient18988"
+       x1="103.51731"
+       y1="65.571739"
+       x2="80.967453"
+       y2="65.571739"
+       gradientUnits="userSpaceOnUse" />
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath5191">
+      <rect
+         style="opacity:1;fill:#d40000;fill-opacity:1;stroke:#000000;stroke-width:0.2045171;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
+         id="rect5193"
+         width="35.162529"
+         height="15.671"
+         x="7.2068729"
+         y="4.0289068"
+         clip-path="none" />
+    </clipPath>
+    <linearGradient
+       id="0-8"
+       x1="21.375999"
+       x2="77.639999"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         stop-color="#fff"
+         id="stop4571" />
+      <stop
+         offset="1"
+         stop-color="#fff"
+         stop-opacity="0"
+         id="stop4573" />
+    </linearGradient>
+  </defs>
+  <g
+     id="g13475"
+     transform="matrix(1.087113,0,0,1.087113,-73.92342,-28.092572)">
+    <g
+       id="g4360"
+       transform="matrix(0.91209554,0,0,0.8790237,7.9997623,6.8776245)"
+       style="stroke-width:1.42454326;stroke-miterlimit:4;stroke-dasharray:none">
+      <g
+         transform="matrix(-1,0,0,1,182.33976,-0.75050212)"
+         id="g18994"
+         style="stroke-width:1.42454326;stroke-miterlimit:4;stroke-dasharray:none">
+        <path
+           style="fill:url(#linearGradient18980);fill-opacity:1;stroke:#1f1a17;stroke-width:1.73954604;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+           d="m 101.65188,69.860643 c -8.735986,0.0568 -14.117214,0.14808 -22.788666,0.19069 0.03444,-1.96153 0.626084,-3.92305 1.717131,-5.88458 -3.660327,-5.97534 -2.711629,-9.46976 0.660435,-11.8724 1.643358,-2.511672 3.09135,-5.155635 5.415568,-8.465541 2.408402,-1.729975 5.368613,-3.27511 7.000615,-5.265155 0.999651,-2.012102 0.536145,-3.261803 -1.452958,-3.716578 -4.929266,0.392414 -2.586788,4.337045 -3.038003,6.916968 -8.157022,5.9081 -11.375898,-0.892949 -11.09531,-3.303627 0.866167,-0.425478 1.436706,0.424041 2.322856,0.892644 0.745737,-0.450725 1.324113,-0.600373 2.036018,-0.582929 1.279361,0.765191 1.000634,1.249092 1.395919,2.187032 -1.172713,-6.738948 0.45135,-11.146721 9.567302,-11.684957 5.781167,0.546187 8.561033,3.546411 9.238073,8.665756 -0.79017,0.516192 -1.6238,0.995882 -1.70912,1.658075 0.11979,2.1649 -1.042871,4.455102 -1.849206,6.710489 l 0.839225,0.503666 -0.18681,1.287886 c -0.14937,0.350239 -1.013511,-0.404227 -1.282174,-0.07299 -0.332596,0.410032 -0.549328,2.109829 -0.479463,2.409619 1.065533,-2.767772 3.623888,-3.864359 6.128528,-5.573506 1.13193,-1.312743 2.68829,-2.395172 2.72894,-1.721383 -0.38292,1.952979 -1.15417,5.034143 -2.68652,8.156665 0.12703,2.952026 0.73992,5.567583 0.22174,8.431036 -0.73303,4.050686 -2.87676,5.20466 -2.70412,10.13313 z"
+           id="path15217"
+           inkscape:connector-curvature="0"
+           sodipodi:nodetypes="ccccccccccccccccccsccccscc" />
+        <path
+           style="fill:url(#linearGradient15235);fill-opacity:1;stroke:#1f1a17;stroke-width:1.73954604;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+           d="m 95.673807,48.092246 c 1.042408,4.232607 2.16064,4.761207 3.672297,5.142667 6.828586,-9.427033 6.556516,-15.721988 4.453476,-17.881256 -2.08345,3.65474 -4.072731,9.989388 -8.125773,12.738589 z"
+           id="path15219"
+           inkscape:connector-curvature="0"
+           sodipodi:nodetypes="cccc" />
+        <ellipse
+           style="opacity:1;fill:#1f1a17;fill-opacity:1;stroke:#1f1a17;stroke-width:1.42454326;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
+           id="path15267"
+           cx="87.397079"
+           cy="49.458702"
+           rx="0.7429592"
+           ry="1.4328499" />
+        <path
+           style="fill:url(#linearGradient18988);fill-opacity:1;stroke:#1f1a17;stroke-width:1.73954604;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+           d="m 80.758294,56.749733 c -1.780779,3.16306 -4.348115,6.291688 -4.821424,12.443248 5.742335,-2.051055 13.154089,1.099485 17.23671,-0.135008 -2.50154,-4.0381 -1.208197,-3.908699 -2.189333,-8.984699"
+           id="path18972"
+           inkscape:connector-curvature="0"
+           sodipodi:nodetypes="cccc" />
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/client/public/images/pieces/Schess/wh.svg b/client/public/images/pieces/Schess/wh.svg
new file mode 100644 (file)
index 0000000..2b8b5e5
--- /dev/null
@@ -0,0 +1,157 @@
+<?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:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="177.17"
+   height="177.17"
+   shape-rendering="geometricPrecision"
+   image-rendering="optimizeQuality"
+   fill-rule="evenodd"
+   clip-rule="evenodd"
+   viewBox="0 0 50 50"
+   version="1.1"
+   id="svg12863"
+   sodipodi:docname="WH.svg"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
+  <metadata
+     id="metadata12867">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="958"
+     inkscape:window-height="1008"
+     id="namedview12865"
+     showgrid="false"
+     showguides="false"
+     inkscape:zoom="1.7295106"
+     inkscape:cx="31.332406"
+     inkscape:cy="107.19209"
+     inkscape:window-x="1912"
+     inkscape:window-y="-8"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg12863" />
+  <defs
+     id="defs12857">
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient13464">
+      <stop
+         style="stop-color:#808080;stop-opacity:1;"
+         offset="0"
+         id="stop13460" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="1"
+         id="stop13462" />
+    </linearGradient>
+    <linearGradient
+       id="0"
+       x1="21.405"
+       x2="77.64"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         stop-color="#fff"
+         id="stop12852" />
+      <stop
+         offset="1"
+         stop-color="#fff"
+         stop-opacity="0"
+         id="stop12854" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient13464"
+       id="linearGradient13468"
+       x1="115.58475"
+       y1="51.192822"
+       x2="87.865845"
+       y2="51.538971"
+       gradientUnits="userSpaceOnUse" />
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath5191">
+      <rect
+         style="opacity:1;fill:#d40000;fill-opacity:1;stroke:#000000;stroke-width:0.2045171;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
+         id="rect5193"
+         width="35.162529"
+         height="15.671"
+         x="7.2068729"
+         y="4.0289068"
+         clip-path="none" />
+    </clipPath>
+    <linearGradient
+       id="0-2"
+       x1="21.375999"
+       x2="77.639999"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         stop-color="#fff"
+         id="stop4571" />
+      <stop
+         offset="1"
+         stop-color="#fff"
+         stop-opacity="0"
+         id="stop4573" />
+    </linearGradient>
+  </defs>
+  <g
+     id="g13475"
+     transform="matrix(1.0539134,0,0,1.1187798,-70.902198,-28.281003)">
+    <path
+       sodipodi:nodetypes="cccccccccccccccccccc"
+       inkscape:connector-curvature="0"
+       id="path13430"
+       d="m 84.568171,35.093828 -6.217144,0.149811 c -6.203086,2.383935 -6.962587,5.934352 -4.793947,10.112228 -0.05331,-4.629564 3.609449,-3.313402 6.366959,-3.445648 9.559786,5.46999 4.25599,14.805717 -0.599244,18.426723 l 4.419419,0.449433 -0.524338,3.07112 4.269605,-2.92131 2.696594,3.520551 3.895081,-2.92131 1.573012,2.621691 2.022444,-2.696597 c 1.307039,1.013938 2.064854,2.354644 2.627738,3.526604 l 1.86659,-3.226981 c 1.23104,0.812023 1.87638,2.044599 2.8464,3.07112 v -4.119794 l 4.41942,2.621688 C 110.0094,46.435659 108.3116,35.260707 95.504357,31.573276 92.79365,31.513132 90.012856,31.228707 87.639293,32.247423 Z"
+       style="fill:url(#linearGradient13468);fill-opacity:1;stroke:#1f1a17;stroke-width:1.55939555;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <path
+       inkscape:connector-curvature="0"
+       id="path13432"
+       d="M 91.159846,44.531907 79.924039,41.910219"
+       style="fill:none;stroke:#1f1a17;stroke-width:1.55939555;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <path
+       sodipodi:nodetypes="cc"
+       inkscape:connector-curvature="0"
+       id="path13434"
+       d="m 83.103812,35.805085 c -0.02515,1.008854 0.490503,1.148881 1.112288,1.324152"
+       style="fill:none;stroke:#1f1a17;stroke-width:1.55939555;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <path
+       transform="rotate(-3.1672079)"
+       d="m 91.413755,41.973846 a 2.5158896,1.8273305 0 0 1 -1.307932,1.602928 2.5158896,1.8273305 0 0 1 -2.563889,-0.0637 2.5158896,1.8273305 0 0 1 -1.154078,-1.664092 l 2.510009,0.124859 z"
+       sodipodi:end="3.2099747"
+       sodipodi:start="0"
+       sodipodi:ry="1.8273305"
+       sodipodi:rx="2.5158896"
+       sodipodi:cy="41.973846"
+       sodipodi:cx="88.897865"
+       sodipodi:type="arc"
+       id="path13436"
+       style="opacity:1;fill:#1f1a17;fill-opacity:1;stroke:#1f1a17;stroke-width:1.69328892;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" />
+    <path
+       inkscape:connector-curvature="0"
+       id="path13438"
+       d="m 93.644067,36.864407 3.760592,-0.423729"
+       style="fill:#1f1a17;fill-opacity:1;stroke:#1f1a17;stroke-width:1.69324374;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+  </g>
+</svg>
index f51e8d0..52ec2c5 100644 (file)
@@ -191,9 +191,9 @@ export const ChessRules = class ChessRules {
     return V.CoordToColumn(coords.y) + (V.size.x - coords.x);
   }
 
     return V.CoordToColumn(coords.y) + (V.size.x - coords.x);
   }
 
-  // Path to pieces
+  // Path to pieces (standard ones in pieces/ folder)
   getPpath(b) {
   getPpath(b) {
-    return b; //usual pieces in pieces/ folder
+    return b;
   }
 
   // Path to promotion pieces (usually the same)
   }
 
   // Path to promotion pieces (usually the same)
@@ -1101,7 +1101,9 @@ export const ChessRules = class ChessRules {
     ) {
       const flagIdx = (move.start.y == this.castleFlags[c][0] ? 0 : 1);
       this.castleFlags[c][flagIdx] = V.size.y;
     ) {
       const flagIdx = (move.start.y == this.castleFlags[c][0] ? 0 : 1);
       this.castleFlags[c][flagIdx] = V.size.y;
-    } else if (
+    }
+    // NOTE: not "else if" because a rook could take an opposing rook
+    if (
       move.end.x == oppFirstRank && //we took opponent rook?
       this.castleFlags[oppCol].includes(move.end.y)
     ) {
       move.end.x == oppFirstRank && //we took opponent rook?
       this.castleFlags[oppCol].includes(move.end.y)
     ) {
index 90d7daf..f5139ce 100644 (file)
@@ -193,6 +193,7 @@ export const translations = {
   "Reverse captures": "Reverse captures",
   "Run forward": "Run forward",
   "Score a goal": "Score a goal",
   "Reverse captures": "Reverse captures",
   "Run forward": "Run forward",
   "Score a goal": "Score a goal",
+  "Seirawan-Harper Chess": "Seirawan-Harper Chess",
   "Shared pieces": "Shared pieces",
   "Shoot pieces": "Shoot pieces",
   "Squares disappear": "Squares disappear",
   "Shared pieces": "Shared pieces",
   "Shoot pieces": "Shoot pieces",
   "Squares disappear": "Squares disappear",
index 6894fca..57e85b7 100644 (file)
@@ -193,6 +193,7 @@ export const translations = {
   "Reverse captures": "Capturas invertidas",
   "Run forward": "Correr hacia adelante",
   "Score a goal": "Marcar una meta",
   "Reverse captures": "Capturas invertidas",
   "Run forward": "Correr hacia adelante",
   "Score a goal": "Marcar una meta",
+  "Seirawan-Harper Chess": "Ajedrez Seirawan-Harper",
   "Shared pieces": "Piezas compartidas",
   "Shoot pieces": "Tirar de las piezas",
   "Squares disappear": "Las casillas desaparecen",
   "Shared pieces": "Piezas compartidas",
   "Shoot pieces": "Tirar de las piezas",
   "Squares disappear": "Las casillas desaparecen",
index 02b168d..dc3329d 100644 (file)
@@ -193,6 +193,7 @@ export const translations = {
   "Reverse captures": "Captures inversées",
   "Run forward": "Courir vers l'avant",
   "Score a goal": "Marquer un but",
   "Reverse captures": "Captures inversées",
   "Run forward": "Courir vers l'avant",
   "Score a goal": "Marquer un but",
+  "Seirawan-Harper Chess": "Échecs Seirawan-Harper",
   "Shared pieces": "Pièces partagées",
   "Shoot pieces": "Tirez sur les pièces",
   "Squares disappear": "Les cases disparaissent",
   "Shared pieces": "Pièces partagées",
   "Shoot pieces": "Tirez sur les pièces",
   "Squares disappear": "Les cases disparaissent",
index 475a160..49005d8 100644 (file)
@@ -14,9 +14,9 @@ ul
 
 figure.diagram-container
   .diagram.diag12
 
 figure.diagram-container
   .diagram.diag12
-    | fen:rnbqkwbnr/ppppp1ppp/9/5p3/4a4/9/2N3N2/PPPPPPPPP/R1BQKWB1R:
+    | fen:rnbqkwnbr/ppppp1ppp/9/5p3/4a4/9/2N4N1/PPPPPPPPP/R1BQKW1BR:
   .diagram.diag22
   .diagram.diag22
-    | fen:rnbqkwbnr/ppppp1ppp/9/9/4s4/9/2N3N2/PPPPPPPPP/R1BQKWB1R:
+    | fen:rnbqkwnbr/ppppp1ppp/9/9/4s4/9/2N4N1/PPPPPPPPP/R1BQKW1BR:
   figcaption Left: before ...fxe5 (taking ball). Right: after ...fxe5.
 
 p.
   figcaption Left: before ...fxe5 (taking ball). Right: after ...fxe5.
 
 p.
index 68940c7..42922c4 100644 (file)
@@ -14,9 +14,9 @@ ul
 
 figure.diagram-container
   .diagram.diag12
 
 figure.diagram-container
   .diagram.diag12
-    | fen:rnbqkwbnr/ppppp1ppp/9/5p3/4a4/9/2N3N2/PPPPPPPPPP/R1BQKWB1R:
+    | fen:rnbqkwnbr/ppppp1ppp/9/5p3/4a4/9/2N4N1/PPPPPPPPPP/R1BQKW1BR:
   .diagram.diag22
   .diagram.diag22
-    | fen:rnbqkwbnr/ppppp1ppp/9/9/4s4/9/2N3N2/PPPPPPPPPP/R1BQKWB1R:
+    | fen:rnbqkwnbr/ppppp1ppp/9/9/4s4/9/2N4N1/PPPPPPPPPP/R1BQKW1BR:
   figcaption.
     Izquierda: antes de ...fxe5 (tomando la pelota).
     Derecha: después de ...fxe5.
   figcaption.
     Izquierda: antes de ...fxe5 (tomando la pelota).
     Derecha: después de ...fxe5.
index 9fae080..070021d 100644 (file)
@@ -14,9 +14,9 @@ ul
 
 figure.diagram-container
   .diagram.diag12
 
 figure.diagram-container
   .diagram.diag12
-    | fen:rnbqkwbnr/ppppp1ppp/9/5p3/4a4/9/2N3N2/PPPPPPPPP/R1BQKWB1R:
+    | fen:rnbqkwnbr/ppppp1ppp/9/5p3/4a4/9/2N4N1/PPPPPPPPP/R1BQKW1BR:
   .diagram.diag22
   .diagram.diag22
-    | fen:rnbqkwbnr/ppppp1ppp/9/9/4s4/9/2N3N2/PPPPPPPPP/R1BQKWB1R:
+    | fen:rnbqkwnbr/ppppp1ppp/9/9/4s4/9/2N4N1/PPPPPPPPP/R1BQKW1BR:
   figcaption Gauche : avant ...fxe5 (prenant le ballon). Droite : après ...fxe5.
 
 p.
   figcaption Gauche : avant ...fxe5 (prenant le ballon). Droite : après ...fxe5.
 
 p.
diff --git a/client/src/translations/rules/Schess/en.pug b/client/src/translations/rules/Schess/en.pug
new file mode 100644 (file)
index 0000000..de4435a
--- /dev/null
@@ -0,0 +1,40 @@
+p.boxed
+  | You have two new pieces in a pocket, which can appear after any
+  | first piece movement.
+
+p.
+  When a piece is moved for the first time, it is possible to place a new
+  piece at its initial square.
+  You have two pieces that can enter the game like this:
+ul
+  li The Hawk (H): moving like a bishop + knight.
+  li The Elephant (E): moving like a rook + knight.
+
+figure.diagram-container
+  .diagram
+    | fen:rnbqkbnr/pppppppp/8/8/8/2N5/PPPPPPPP/REBQKBNR:
+  figcaption.
+    Position after 1.Nc3/E. White moved his knight from b1 to c3 and placed
+    the elephant on b1.
+
+p.
+  After castling, a new piece can be put at the initial king square
+  (if not occupied), or at the initial rook square - but not both.
+
+p.
+  If a move let the king under check, then it is forbidden,
+  even if placing a pocket piece would have covered the check.
+
+h3 Source
+
+p
+  | Some explanations about the rules and a link to buy a physical S-Chess set
+  | on the 
+  a(href="http://www.seirawanchess.com/") Seirawan Chess page
+  | . This variant is playable on 
+  a(href="https://www.pychess.org/variant/seirawan") pychess-variants
+  | &nbsp;with an engine available for analysis. See also the 
+  a(href="https://en.wikipedia.org/wiki/Seirawan_chess") Wikipedia page
+  | .
+
+p Inventors: Yasser Seirawan and Bruce Harper (2008)
diff --git a/client/src/translations/rules/Schess/es.pug b/client/src/translations/rules/Schess/es.pug
new file mode 100644 (file)
index 0000000..ecac438
--- /dev/null
@@ -0,0 +1,42 @@
+p.boxed
+  | Tienes dos piezas en tu bolsillo, que pueden aparecer después
+  | cualquier movimiento inicial de una pieza.
+
+p.
+  Cuando una pieza se mueve por la primera vez, una pieza nueva
+  se puede colocar en su casilla inicial.
+  Tienes dos piezas que también pueden ingresar al juego:
+ul
+  li El Aguila (H): se mueve como un alfil + caballo.
+  li El Elefante (E): se mueve como una torre + caballo.
+
+figure.diagram-container
+  .diagram
+    | fen:rnbqkbnr/pppppppp/8/8/8/2N5/PPPPPPPP/REBQKBNR:
+  figcaption.
+    Posición después de 1.Nc3/E. Las blancas mueven su caballo de b1 a c3
+    y colocar el elefante en b1.
+
+p.
+  Después de haberse enrocado, se puede colocar una nueva pieza en la
+  casilla inicial del rey (si no está ocupado), o en el espacio inicial de
+  la torre, pero no en ambos.
+
+p.
+  Si un movimiento deja al rey en jaque, entonces está prohibido,
+  incluso si colocar una nueva pieza hubiera sido el jaque.
+
+h3 Fuente
+
+p
+  | Algunas explicaciones sobre las reglas, así como un enlace para comprar
+  | un conjunto de piezas de S-Chess en el
+  a(href="http://www.seirawanchess.com/") página Seirawan Chess
+  | . Esta variante se puede jugar en 
+  a(href="https://www.pychess.org/variant/seirawan") pychess-variantes
+  | &nbsp;con un módulo disponible para análisis. Ver también la 
+  a(href= "https://www.pousseurdebois.fr/variantes-du-jeu-dechecs/echecsseirawan/")
+  a(href="https://en.wikipedia.org/wiki/Seirawan_chess") página Wikipedia
+  | .
+
+p Inventores: Yasser Seirawan y Bruce Harper (2008)
diff --git a/client/src/translations/rules/Schess/fr.pug b/client/src/translations/rules/Schess/fr.pug
new file mode 100644 (file)
index 0000000..ed55d9f
--- /dev/null
@@ -0,0 +1,41 @@
+p.boxed
+  | Vous avez deux pièces en poche, qui peuvent apparaitre après
+  | n'importe quel déplacement initial d'une pièce.
+
+p.
+  Quand une pièce est déplacée pour la première fois, une nouvelle pièce
+  peut être placée sur sa case de départ.
+  Vous avez deux pièces pouvant entrer dans le jeu ainsi :
+ul
+  li L'Aigle (H) : se déplace comme un fou + cavalier.
+  li L'Éléphant (E) : se déplace comme une tour + cavalier.
+
+figure.diagram-container
+  .diagram
+    | fen:rnbqkbnr/pppppppp/8/8/8/2N5/PPPPPPPP/REBQKBNR:
+  figcaption.
+    Position après 1.Nc3/E. Les blancs déplacent leur cavalier de b1 à c3
+    et placent l'éléphant en b1.
+
+p.
+  Après avoir roqué, une nouvelle pièce peut être placée sur la case
+  initiale du roi (si elle n'est pas occupée), ou sur la case initiale de la
+  tour - mais pas sur les deux.
+
+p.
+  Si un coup laisse le roi en échec, alors il est interdit,
+  même si le placement d'une nouvelle pièce aurait paré l'échec.
+
+h3 Source
+
+p
+  | Quelques explications sur les règles ainsi qu'un lien pour acheter
+  | un jeu de pièces de S-Chess sur la 
+  a(href="http://www.seirawanchess.com/") page Seirawan Chess
+  | . Cette variante est jouable sur 
+  a(href="https://www.pychess.org/variant/seirawan") pychess-variants
+  | &nbsp;avec un module disponible pour l'analyse. Voir aussi 
+  a(href="https://www.pousseurdebois.fr/variantes-du-jeu-dechecs/echecsseirawan/")
+    | cette page.
+
+p Inventeurs : Yasser Seirawan et Bruce Harper (2008)
index cf50a80..5a23e9f 100644 (file)
@@ -129,7 +129,7 @@ export class BallRules extends ChessRules {
 
   static GenRandInitFen(randomness) {
     if (randomness == 0)
 
   static GenRandInitFen(randomness) {
     if (randomness == 0)
-      return "rnbqkwbnr/ppppppppp/9/9/4a4/9/9/PPPPPPPPP/RNBQKWBNR w 0 -";
+      return "rnbqkwnbr/ppppppppp/9/9/4a4/9/9/PPPPPPPPP/RNBQKWNBR w 0 -";
 
     let pieces = { w: new Array(9), b: new Array(9) };
     for (let c of ["w", "b"]) {
 
     let pieces = { w: new Array(9), b: new Array(9) };
     for (let c of ["w", "b"]) {
index a08f197..b66ac38 100644 (file)
@@ -234,4 +234,19 @@ export class CannibalRules extends ChessRules {
   static get SEARCH_DEPTH() {
     return 4;
   }
   static get SEARCH_DEPTH() {
     return 4;
   }
+
+  getNotation(move) {
+    let notation = super.getNotation(move);
+    const lastRank = (move.appear[0].c == "w" ? 0 : 7);
+    if (
+      move.end.x != lastRank &&
+      this.getPiece(move.start.x, move.start.y) == V.PAWN &&
+      move.vanish.length == 2 &&
+      move.appear[0].p != V.PAWN
+    ) {
+      // Fix "promotion" (transform indicator) from base_rules notation
+      notation = notation.slice(0, -2);
+    }
+    return notation;
+  }
 };
 };
index 882a32a..799c3e5 100644 (file)
@@ -71,8 +71,8 @@ export class CheckeredRules extends ChessRules {
   setFlags(fenflags) {
     super.setFlags(fenflags); //castleFlags
     this.pawnFlags = {
   setFlags(fenflags) {
     super.setFlags(fenflags); //castleFlags
     this.pawnFlags = {
-      w: [...Array(8).fill(true)], //pawns can move 2 squares?
-      b: [...Array(8).fill(true)]
+      w: [...Array(8)], //pawns can move 2 squares?
+      b: [...Array(8)]
     };
     const flags = fenflags.substr(4); //skip first 4 letters, for castle
     for (let c of ["w", "b"]) {
     };
     const flags = fenflags.substr(4); //skip first 4 letters, for castle
     for (let c of ["w", "b"]) {
@@ -402,19 +402,19 @@ export class CheckeredRules extends ChessRules {
 
   getFen() {
     const L = this.cmoves.length;
 
   getFen() {
     const L = this.cmoves.length;
-    const cmoveFen = !this.cmoves[L - 1]
-      ? "-"
-      : ChessRules.CoordsToSquare(this.cmoves[L - 1].start) +
-        ChessRules.CoordsToSquare(this.cmoves[L - 1].end);
+    const cmoveFen =
+      !this.cmoves[L - 1]
+        ? "-"
+        : ChessRules.CoordsToSquare(this.cmoves[L - 1].start) +
+          ChessRules.CoordsToSquare(this.cmoves[L - 1].end);
     return super.getFen() + " " + cmoveFen;
   }
 
   getFlagsFen() {
     let fen = super.getFlagsFen();
     // Add pawns flags
     return super.getFen() + " " + cmoveFen;
   }
 
   getFlagsFen() {
     let fen = super.getFlagsFen();
     // Add pawns flags
-    for (let c of ["w", "b"]) {
-      for (let i = 0; i < 8; i++) fen += this.pawnFlags[c][i] ? "1" : "0";
-    }
+    for (let c of ["w", "b"])
+      for (let i = 0; i < 8; i++) fen += (this.pawnFlags[c][i] ? "1" : "0");
     return fen;
   }
 
     return fen;
   }
 
diff --git a/client/src/variants/Schess.js b/client/src/variants/Schess.js
new file mode 100644 (file)
index 0000000..7cbb47a
--- /dev/null
@@ -0,0 +1,308 @@
+import { ChessRules, PiPo } from "@/base_rules";
+
+export class SchessRules extends ChessRules {
+  static get PawnSpecs() {
+    return Object.assign(
+      {},
+      ChessRules.PawnSpecs,
+      {
+        promotions:
+          ChessRules.PawnSpecs.promotions.concat([V.HAWK, V.ELEPHANT])
+      }
+    );
+  }
+
+  static get HAWK() {
+    return 'h';
+  }
+
+  static get ELEPHANT() {
+    return 'e';
+  }
+
+  static get PIECES() {
+    return ChessRules.PIECES.concat([V.HAWK, V.ELEPHANT]);
+  }
+
+  getPpath(b) {
+    if ([V.HAWK, V.ELEPHANT].includes(b[1])) return "Schess/" + b;
+    return b;
+  }
+
+  // TODO: maybe changes could be done to this method to show "empty"
+  // instead of a piece to not use a pocket piece...
+//  getPPpath(b) { }
+
+  static IsGoodFen(fen) {
+    if (!ChessRules.IsGoodFen(fen)) return false;
+    const fenParsed = V.ParseFen(fen);
+    // Check pocket state
+    if (!fenParsed.pocket || !fenParsed.pocket.match(/^[0-1]{4,4}$/))
+      return false;
+    return true;
+  }
+
+  static IsGoodFlags(flags) {
+    // 4 for castle + 16 for generators
+    return !!flags.match(/^[a-z]{4,4}[01]{16,16}$/);
+  }
+
+  setFlags(fenflags) {
+    super.setFlags(fenflags); //castleFlags
+    this.pieceFlags = {
+      w: [...Array(8)], //pawns can move 2 squares?
+      b: [...Array(8)]
+    };
+    const flags = fenflags.substr(4); //skip first 4 letters, for castle
+    for (let c of ["w", "b"]) {
+      for (let i = 0; i < 8; i++)
+        this.pieceFlags[c][i] = flags.charAt((c == "w" ? 0 : 8) + i) == "1";
+    }
+  }
+
+  aggregateFlags() {
+    return [this.castleFlags, this.pieceFlags];
+  }
+
+  disaggregateFlags(flags) {
+    this.castleFlags = flags[0];
+    this.pieceFlags = flags[1];
+  }
+
+  static ParseFen(fen) {
+    const fenParts = fen.split(" ");
+    return Object.assign(
+      ChessRules.ParseFen(fen),
+      { pocket: fenParts[5] }
+    );
+  }
+
+  static GenRandInitFen(randomness) {
+    return (
+      ChessRules.GenRandInitFen(randomness).slice(0, -2) +
+      // Add pieceFlags + pocket
+      "1111111111111111 - 1111"
+    );
+  }
+
+  getFen() {
+    return (
+      super.getFen() + " " +
+      this.getPocketFen()
+    );
+  }
+
+  getFenForRepeat() {
+    return (
+      super.getFenForRepeat() + "_" +
+      this.getPocketFen()
+    );
+  }
+
+  getFlagsFen() {
+    let fen = super.getFlagsFen();
+    // Add pieces flags
+    for (let c of ["w", "b"])
+      for (let i = 0; i < 8; i++) fen += (this.pieceFlags[c][i] ? "1" : "0");
+    return fen;
+  }
+
+  getPocketFen() {
+    let res = "";
+    for (let c of ["w", "b"])
+      res += this.pocket[c][V.HAWK] + this.pocket[c][V.ELEPHANT];
+    return res;
+  }
+
+  setOtherVariables(fen) {
+    super.setOtherVariables(fen);
+    const fenParsed = V.ParseFen(fen);
+    this.pocket = {
+      "w": {
+        h: parseInt(fenParsed.pocket[0]),
+        e: parseInt(fenParsed.pocket[1])
+      },
+      "b": {
+        h: parseInt(fenParsed.pocket[2]),
+        e: parseInt(fenParsed.pocket[3])
+      }
+    };
+  }
+
+  getPotentialMovesFrom([x, y]) {
+    let moves = undefined;
+    switch (this.getPiece(x, y)) {
+      case V.HAWK:
+        moves = this.getPotentialHawkMoves([x, y]);
+        break;
+      case V.ELEPHANT:
+        moves = this.getPotentialElephantMoves([x, y]);
+        break;
+      default:
+        moves = super.getPotentialMovesFrom([x, y]);
+    }
+    // Post-processing: add choices for hawk and elephant,
+    // except for moves letting the king under check.
+    const color = this.turn;
+    if (Object.values(this.pocket[color]).some(v => v > 0)) {
+      const firstRank = (color == "w" ? 7 : 0);
+      let pocketMoves = [];
+      moves.forEach(m => {
+        let inCheckAfter = false;
+        this.play(m);
+        if (this.underCheck(color)) inCheckAfter = true;
+        this.undo(m);
+        if (!inCheckAfter) {
+          for (let pp of ['h', 'e']) {
+            if (this.pocket[color][pp] > 0) {
+              if (
+                m.start.x == firstRank &&
+                this.pieceFlags[color][m.start.y] &&
+                (
+                  m.appear.length == 1 ||
+                  // Special castle case: is initial king square free?
+                  ![m.appear[0].y, m.appear[1].y].includes(m.vanish[0].y)
+                )
+              ) {
+                let pMove = JSON.parse(JSON.stringify(m));
+                // NOTE: unshift instead of push, for choices presentation
+                pMove.appear.unshift(new PiPo({
+                  p: pp,
+                  c: color,
+                  x: x,
+                  y: y
+                }));
+                pocketMoves.push(pMove);
+              }
+              if (
+                m.appear.length == 2 &&
+                ![m.appear[0].y, m.appear[1].y].includes(m.vanish[1].y)
+              ) {
+                // Special castle case: rook flag was necessarily on
+                let pMove = JSON.parse(JSON.stringify(m));
+                pMove.appear.unshift(new PiPo({
+                  p: pp,
+                  c: color,
+                  x: m.vanish[1].x,
+                  y: m.vanish[1].y
+                }));
+                pocketMoves.push(pMove);
+              }
+            }
+          }
+        }
+      });
+      // NOTE: the order matter, for presentation on screen
+      moves = moves.concat(pocketMoves);
+    }
+    return moves;
+  }
+
+  getPotentialHawkMoves(sq) {
+    return this.getSlideNJumpMoves(
+      sq,
+      V.steps[V.BISHOP].concat(V.steps[V.KNIGHT])
+    );
+  }
+
+  getPotentialElephantMoves(sq) {
+    return this.getSlideNJumpMoves(
+      sq,
+      V.steps[V.ROOK].concat(V.steps[V.KNIGHT])
+    );
+  }
+
+  isAttacked(sq, color) {
+    return (
+      super.isAttacked(sq, color) ||
+      this.isAttackedByHawk(sq, color) ||
+      this.isAttackedByElephant(sq, color)
+    );
+  }
+
+  isAttackedByHawk(sq, color) {
+    return this.isAttackedBySlideNJump(
+      sq,
+      color,
+      V.HAWK,
+      V.steps[V.BISHOP].concat(V.steps[V.KNIGHT])
+    );
+  }
+
+  isAttackedByElephant(sq, color) {
+    return this.isAttackedBySlideNJump(
+      sq,
+      color,
+      V.ELEPHANT,
+      V.steps[V.ROOK].concat(V.steps[V.KNIGHT])
+    );
+  }
+
+  prePlay(move) {
+    super.prePlay(move);
+    if (move.appear.length >= 2) {
+      if ([V.HAWK, V.ELEPHANT].includes(move.appear[0].p)) {
+        // A pocket piece is used
+        const color = this.turn;
+        this.pocket[color][move.appear[0].p] = 0;
+      }
+    }
+  }
+
+  postPlay(move) {
+    super.postPlay(move);
+    const color = move.vanish[0].c;
+    const oppCol = V.GetOppCol(color);
+    const firstRank = (color == 'w' ? 7 : 0);
+    const oppFirstRank = 7 - firstRank;
+    // Does this move turn off a piece init square flag?
+    if (move.start.x == firstRank) {
+      if (this.pieceFlags[color][move.start.y])
+        this.pieceFlags[color][move.start.y] = false;
+      // Special castle case:
+      if (move.appear.length >= 2) {
+        const L = move.appear.length;
+        if (move.appear[L-1].p == V.ROOK)
+          this.pieceFlags[color][move.vanish[1].y] = false;
+      }
+    }
+    if (move.end.x == oppFirstRank && this.pieceFlags[oppCol][move.end.y])
+      this.pieceFlags[oppCol][move.end.y] = false;
+  }
+
+  postUndo(move) {
+    super.postUndo(move);
+    if (move.appear.length >= 2) {
+      if ([V.HAWK, V.ELEPHANT].includes(move.appear[0].p)) {
+        // A pocket piece was used
+        const color = this.turn;
+        this.pocket[color][move.appear[0].p] = 1;
+      }
+    }
+  }
+
+  static get SEARCH_DEPTH() {
+    return 2;
+  }
+
+  static get VALUES() {
+    return Object.assign(
+      {},
+      ChessRules.VALUES,
+      { 'h': 5, 'e': 7 }
+    );
+  }
+
+  getNotation(move) {
+    if (
+      move.appear.length >= 2 &&
+      [V.HAWK, V.ELEPHANT].includes(move.appear[0].p)
+    ) {
+      const suffix = "/" + move.appear[0].p.toUpperCase();
+      let cmove = JSON.parse(JSON.stringify(move));
+      cmove.appear.shift();
+      return super.getNotation(cmove) + suffix;
+    }
+    return super.getNotation(move);
+  }
+};
index 9e82a24..ce30d65 100644 (file)
@@ -54,8 +54,50 @@ export class TwokingsRules extends CoregalRules {
   }
 
   static GenRandInitFen(randomness) {
   }
 
   static GenRandInitFen(randomness) {
-    const fen = CoregalRules.GenRandInitFen(randomness);
-    return fen.replace("q", "k").replace("Q", "K");
+    if (randomness == 0)
+      return "rnqkkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNQKKBNR w 0 adehadeh -";
+
+    const replaceBishop = (fen, first, ch1, ch2) => {
+      // Remove and re-add final part:
+      const suffix = fen.substr(-15);
+      fen = fen.slice(0, -15);
+      if (first) fen = fen.replace(ch1, ch2);
+      else {
+        fen =
+          fen.split("").reverse().join("")
+          .replace(ch1, ch2)
+          .split("").reverse().join("")
+      }
+      return fen + suffix;
+    };
+
+    const sameIndexReplace = (fen) => {
+      const first = (Math.random() < 0.5);
+      return replaceBishop(
+        replaceBishop(fen, first, 'B', 'Q'),
+        first,
+        'b',
+        'q'
+      );
+    };
+
+    const fen =
+      CoregalRules.GenRandInitFen(randomness)
+      .replace("q", "k").replace("Q", "K");
+    // Now replace a bishop by the queen,
+    // so that bishops are of different colors:
+    if (randomness == 1) return sameIndexReplace(fen);
+    const wOdd = fen.indexOf('B') % 2;
+    const bOdd = fen.indexOf('b') % 2;
+    // Since there are 7 slashes, different oddities means symmetric
+    if (wOdd != bOdd) return sameIndexReplace(fen);
+    const wFirst = (Math.random() < 0.5);
+    return replaceBishop(
+      replaceBishop(fen, wFirst, 'B', 'Q'),
+      !wFirst,
+      'b',
+      'q'
+    );
   }
 
   underCheck(color) {
   }
 
   underCheck(color) {
index 9bb913c..2863546 100644 (file)
@@ -80,6 +80,7 @@ main
             option(value="")
             option(
               v-for="p in Object.values(people)"
             option(value="")
             option(
               v-for="p in Object.values(people)"
+              v-if="!!p.name"
               :value="p.name"
             )
               | {{ p.name }}
               :value="p.name"
             )
               | {{ p.name }}
index a0d4c84..215a9b7 100644 (file)
@@ -41,6 +41,7 @@ insert or ignore into Variants (name,description) values
   ('Recycle', 'Reuse pieces'),
   ('Royalrace', 'Kings cross the 11x11 board'),
   ('Rugby', 'Transform an essay'),
   ('Recycle', 'Reuse pieces'),
   ('Royalrace', 'Kings cross the 11x11 board'),
   ('Rugby', 'Transform an essay'),
+  ('Schess', 'Seirawan-Harper Chess'),
   ('Shatranj', 'Ancient rules'),
   ('Suicide', 'Lose all pieces'),
   ('Suction', 'Attract opposite king'),
   ('Shatranj', 'Ancient rules'),
   ('Suicide', 'Lose all pieces'),
   ('Suction', 'Attract opposite king'),