Almost completed Empire Chess. Next is Synochess (+ rules translations)
authorBenjamin Auder <benjamin.auder@somewhere>
Sun, 13 Dec 2020 01:49:08 +0000 (02:49 +0100)
committerBenjamin Auder <benjamin.auder@somewhere>
Sun, 13 Dec 2020 01:49:08 +0000 (02:49 +0100)
21 files changed:
client/public/images/pieces/Empire/wc.svg [new file with mode: 0644]
client/public/images/pieces/Empire/wd.svg [new file with mode: 0644]
client/public/images/pieces/Empire/we.svg [new file with mode: 0644]
client/public/images/pieces/Empire/wk.svg [new file with mode: 0644]
client/public/images/pieces/Empire/wp.svg [new file with mode: 0644]
client/public/images/pieces/Empire/wq.svg [new file with mode: 0644]
client/public/images/pieces/Empire/ws.svg [new file with mode: 0644]
client/public/images/pieces/Empire/wt.svg [new file with mode: 0644]
client/public/variants/Empire/Board.png [new file with mode: 0644]
client/public/variants/Empire/EagleMoves.png [new file with mode: 0644]
client/src/translations/rules/Empire/en.pug [new file with mode: 0644]
client/src/translations/rules/Empire/es.pug [new file with mode: 0644]
client/src/translations/rules/Empire/fr.pug [new file with mode: 0644]
client/src/translations/rules/Synochess/en.pug [new file with mode: 0644]
client/src/translations/rules/Synochess/es.pug [new file with mode: 0644]
client/src/translations/rules/Synochess/fr.pug [new file with mode: 0644]
client/src/variants/Empire.js [new file with mode: 0644]
client/src/variants/Minixiangqi.js
client/src/variants/Orda.js
client/src/variants/Synochess.js [new file with mode: 0644]
client/src/variants/Xiangqi.js

diff --git a/client/public/images/pieces/Empire/wc.svg b/client/public/images/pieces/Empire/wc.svg
new file mode 100644 (file)
index 0000000..74ce101
--- /dev/null
@@ -0,0 +1,96 @@
+<?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="svg1688"
+   sodipodi:docname="gC.svg"
+   inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
+  <metadata
+     id="metadata1692">
+    <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="3360"
+     inkscape:window-height="1780"
+     id="namedview1690"
+     showgrid="false"
+     inkscape:zoom="2.0115246"
+     inkscape:cx="-184.12522"
+     inkscape:cy="103.48144"
+     inkscape:window-x="6708"
+     inkscape:window-y="1085"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg1688" />
+  <defs
+     id="defs1682">
+    <linearGradient
+       id="0"
+       x1="21.13"
+       y1="37.592"
+       x2="77.64"
+       y2="37.469"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         stop-color="#fff"
+         id="stop1677" />
+      <stop
+         offset="1"
+         stop-color="#fff"
+         stop-opacity="0"
+         id="stop1679" />
+    </linearGradient>
+    <inkscape:path-effect
+       effect="mirror_symmetry"
+       start_point="24.963604,10.991927"
+       end_point="24.963604,32.279336"
+       center_point="24.963604,21.635632"
+       id="path-effect940"
+       is_visible="true"
+       lpeversion="1"
+       mode="free"
+       discard_orig_path="false"
+       fuse_paths="false"
+       oposite_fuse="false"
+       split_items="false" />
+  </defs>
+  <path
+     fill="#1f1a17"
+     d="m 25.447,42.01 c -0.229,0.94 -0.517,1.592 -0.847,1.956 -0.33,0.364 -0.762,0.745 -1.312,1.143 -0.593,0.415 -1.295,0.762 -2.108,1.05 -0.813,0.288 -1.71,0.364 -2.701,0.212 l -6.968,-0.965 c -0.288,-0.034 -0.533,-0.034 -0.762,0 -0.22,0.034 -0.432,0.051 -0.635,0.051 -0.347,0 -0.787,0.076 -1.321,0.237 -0.542,0.152 -0.957,0.381 -1.253,0.677 L 5.135,42.425 c 0.296,-0.33 0.559,-0.559 0.787,-0.694 0.237,-0.127 0.508,-0.271 0.821,-0.415 0.957,-0.449 1.981,-0.72 3.073,-0.821 0.466,-0.034 0.923,-0.042 1.363,-0.025 0.449,0.017 0.914,0 1.397,-0.051 0.889,0.152 1.786,0.288 2.684,0.406 0.906,0.127 1.812,0.254 2.718,0.389 0.991,0 1.66,-0.102 2.01,-0.296 0.186,-0.102 0.474,-0.288 0.872,-0.55 0.398,-0.262 0.796,-0.652 1.194,-1.168 -0.881,-0.093 -1.77,-0.262 -2.684,-0.508 -0.906,-0.237 -1.71,-0.491 -2.404,-0.754 l 2.582,-6.401 C 16.511039,27.964832 14.601237,26.314325 9.8042785,23.754021 16.013282,19.060036 21.366031,11.218743 25.445053,6.4613751 30.517724,11.77428 36.834493,20.824678 41.221119,23.754021 37.413087,25.378214 35.124483,27.729831 31.351,31.537 l 2.582,6.401 c -0.728,0.263 -1.549,0.517 -2.455,0.754 -0.914,0.246 -1.787,0.415 -2.633,0.508 0.381,0.517 0.77,0.906 1.168,1.168 0.398,0.263 0.694,0.449 0.898,0.55 0.347,0.195 1.016,0.296 2.01,0.296 0.889,-0.136 1.786,-0.263 2.692,-0.389 0.898,-0.118 1.803,-0.254 2.718,-0.406 0.44,0.051 0.889,0.068 1.346,0.051 0.457,-0.017 0.923,-0.008 1.405,0.025 1.058,0.102 2.083,0.373 3.073,0.821 0.296,0.144 0.567,0.288 0.804,0.415 0.245,0.135 0.508,0.364 0.804,0.694 l -2.43,3.946 c -0.296,-0.296 -0.711,-0.525 -1.253,-0.677 -0.533,-0.161 -0.965,-0.237 -1.295,-0.237 -0.22,0 -0.44,-0.017 -0.66,-0.051 -0.22,-0.034 -0.474,-0.034 -0.754,0 l -6.951,0.965 c -0.991,0.152 -1.913,0.085 -2.76,-0.195 -0.855,-0.279 -1.558,-0.652 -2.1,-1.118 -0.542,-0.449 -0.982,-0.83 -1.304,-1.151 -0.322,-0.322 -0.593,-0.957 -0.804,-1.897"
+     id="path1684"
+     sodipodi:nodetypes="cscscccscccccccccccsccccccccccccccccsccccccsscccccc" />
+  <path
+     fill="url(#0)"
+     d="m 26.32,39.2 c 0,1.092 0.245,2.024 0.753,2.794 0.5,0.77 1.041,1.372 1.626,1.795 0.906,0.669 2.235,0.999 3.988,0.999 0.432,0 1.279,-0.093 2.532,-0.279 1.025,-0.161 1.854,-0.279 2.481,-0.356 0.627,-0.076 1.05,-0.135 1.27,-0.186 0.627,-0.085 1.287,-0.068 1.981,0.051 0.262,0.068 0.559,0.127 0.88,0.186 0.322,0.059 0.593,0.186 0.804,0.381 l 1.194,-1.93 c -0.677,-0.347 -1.397,-0.593 -2.159,-0.72 -1.253,-0.22 -2.354,-0.263 -3.302,-0.152 -0.279,0.034 -0.643,0.118 -1.101,0.245 -0.457,0.136 -1.067,0.263 -1.846,0.373 -1.676,0.271 -2.557,0.398 -2.659,0.398 -0.644,0 -1.202,-0.076 -1.685,-0.246 C 30.594,42.384 30.171,42.206 29.79,42.011 28.909,41.613 28.02,40.673 27.106,39.2 h -0.787 m -1.761,0 h -0.796 c -0.931,1.49 -1.812,2.43 -2.659,2.811 -0.398,0.195 -0.83,0.373 -1.312,0.542 -0.483,0.169 -1.033,0.246 -1.66,0.246 -0.119,0 -0.999,-0.127 -2.659,-0.398 -0.787,-0.11 -1.422,-0.237 -1.88,-0.373 -0.466,-0.127 -0.83,-0.212 -1.092,-0.245 -0.948,-0.11 -2.04,-0.068 -3.302,0.152 -0.762,0.127 -1.473,0.373 -2.134,0.72 l 1.194,1.93 c 0.195,-0.195 0.457,-0.322 0.779,-0.381 0.322,-0.059 0.618,-0.118 0.88,-0.186 0.694,-0.119 1.355,-0.136 1.981,-0.051 0.22,0.051 0.643,0.11 1.27,0.186 0.627,0.076 1.465,0.195 2.506,0.356 1.236,0.186 2.083,0.279 2.532,0.279 1.736,0 3.065,-0.33 3.988,-0.999 0.567,-0.423 1.101,-1.025 1.6,-1.795 0.508,-0.77 0.762,-1.702 0.762,-2.794 m 0.889,-9.347 c 1.6,0 3.141,0.127 4.614,0.373 3.092537,-2.299022 4.907366,-5.416477 8.355849,-6.446016 C 34.35129,19.45538 29.904994,13.619833 25.445,8.6589243 21.432065,13.577618 17.586816,18.994484 12.822373,23.655976 15.268129,25.009558 18.793584,27.36464 20.831,30.226 c 1.456,-0.246 2.997,-0.373 4.614,-0.373 m 0,4.513 c 1.939,0 3.793,0.195 5.579,0.576 l -1.185,-3.057 c -1.456,-0.229 -2.921,-0.347 -4.394,-0.347 -1.507,0 -2.98,0.119 -4.411,0.347 l -1.194,3.057 c 1.77,-0.381 3.641,-0.576 5.605,-0.576 m 0,3.473 c 1.126,0 2.218,-0.093 3.285,-0.279 1.067,-0.195 2.1,-0.423 3.09,-0.686 -1.939,-0.508 -4.064,-0.77 -6.375,-0.77 -2.345,0 -4.47,0.263 -6.375,0.77 0.957,0.263 1.973,0.491 3.048,0.686 1.075,0.186 2.184,0.279 3.327,0.279 M 24.556,23.505 22.49,23.48 c -0.559,0 -0.838,-0.279 -0.838,-0.847 0,-0.559 0.279,-0.838 0.838,-0.838 h 2.066 v -2.134 c 0,-0.576 0.296,-0.872 0.889,-0.872 0.576,0 0.872,0.296 0.872,0.872 v 2.134 h 2.134 c 0.542,0 0.813,0.279 0.813,0.838 0,0.567 -0.271,0.847 -0.813,0.847 h -2.134 v 2.032 c 0,0.601 -0.296,0.898 -0.872,0.898 -0.593,0 -0.889,-0.296 -0.889,-0.898 v -2.01"
+     id="path1686"
+     sodipodi:nodetypes="cccscccccccccccsccccccccsccccccsccscscccccccccccccsccccccscccccsscssscssscsssc"
+     style="fill:#ffdd55;fill-opacity:1" />
+</svg>
diff --git a/client/public/images/pieces/Empire/wd.svg b/client/public/images/pieces/Empire/wd.svg
new file mode 100644 (file)
index 0000000..d6b8d8b
--- /dev/null
@@ -0,0 +1,115 @@
+<?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="svg109"
+   sodipodi:docname="gD.svg"
+   inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
+  <metadata
+     id="metadata113">
+    <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="3840"
+     inkscape:window-height="2050"
+     id="namedview111"
+     showgrid="false"
+     inkscape:zoom="2.5540442"
+     inkscape:cx="427.2392"
+     inkscape:cy="177.80527"
+     inkscape:window-x="-12"
+     inkscape:window-y="-12"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg109" />
+  <defs
+     id="defs99">
+    <inkscape:path-effect
+       effect="mirror_symmetry"
+       start_point="24.963604,10.991927"
+       end_point="24.963604,32.279336"
+       center_point="24.963604,21.635632"
+       id="path-effect940"
+       is_visible="true"
+       lpeversion="1"
+       mode="free"
+       discard_orig_path="false"
+       fuse_paths="false"
+       oposite_fuse="false"
+       split_items="false" />
+    <linearGradient
+       id="0"
+       x1="21.376"
+       x2="77.64"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         stop-color="#fff"
+         id="stop94" />
+      <stop
+         offset="1"
+         stop-color="#fff"
+         stop-opacity="0"
+         id="stop96" />
+    </linearGradient>
+  </defs>
+  <g
+     fill="#1f1a17"
+     id="g105">
+    <path
+       d="m 11.03,37.744 -0.813,-4.64 C 10.1259,32.251198 10.229841,31.606945 9.7338674,31.301906 24.488291,28.886001 25.638298,28.239 39.9661,31.443633 39.861502,31.990427 39.763128,32.541529 39.685,33.104 l -0.796,4.665 1.643,6.121 c -0.83,0.745 -2.684,1.355 -5.554,1.837 -2.879,0.483 -6.206,0.72 -9.974,0.72 -3.835,0 -7.214,-0.254 -10.118,-0.754 C 11.974,45.185 10.145,44.55 9.4,43.796 l 1.634,-6.05"
+       id="path103"
+       sodipodi:nodetypes="ccccccccsccc" />
+  </g>
+  <path
+     fill="url(#0)"
+     d="m 12.546,36.228 c 3.141,-0.796 7.307,-1.194 12.505,-1.194 5.089,0 9.203,0.381 12.327,1.143 l 0.618,-3.649 c -8.499377,-1.517057 -17.806527,-2.147852 -26.07,0.026 l 0.618,3.675 m 25.298,4.411 -0.737,-2.845 c -3.277,-0.728 -7.332,-1.092 -12.158,-1.092 -4.809,0 -8.856,0.364 -12.133,1.092 l -0.787,2.87 c 3.158,-0.923 7.468,-1.389 12.945,-1.389 5.444,0 9.728,0.457 12.869,1.363 m 0.652,2.337 c -3.192,-1.287 -7.679,-1.939 -13.445,-1.939 -5.986,0 -10.516,0.66 -13.598,1.99 2.913,1.151 7.417,1.736 13.521,1.736 2.913,0 5.563,-0.161 7.959,-0.483 2.404,-0.322 4.25,-0.762 5.563,-1.304"
+     id="path107"
+     style="fill:#ffdd55"
+     sodipodi:nodetypes="csccccccsccsccscscc" />
+  <circle
+     style="fill:#ffdd55;stroke:#1f1a17;stroke-width:1.69329;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     id="path952"
+     cx="25"
+     cy="11.574585"
+     r="3.6187844" />
+  <path
+     style="fill:#ffdd55;stroke:#1f1a17;stroke-width:1.69328895;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+     d="M 11.067311,32.377002 7.2078011,20.074928 c 11.2317159,-6.688285 23.9087279,-6.5739 35.3944039,0.2344 l -3.742308,12.067674 c -9.395098,-2.465329 -18.708366,-3.389529 -27.792586,0 z"
+     id="path946"
+     sodipodi:nodetypes="ccccc" />
+  <path
+     style="fill:#ffdd55;stroke:#1f1a17;stroke-width:1.69329;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     d="M 11.067311,32.377003 C 8.7634184,26.460684 6.519369,24.950002 2.6096143,19.690627 4.853123,17.867788 6.9937585,16.680318 9.7781105,16.268466 c 3.9745945,5.25596 5.7997985,8.284538 7.5772595,13.875898 -1.006793,-5.967855 -0.777829,-9.067377 -3.369501,-14.48397 2.952598,-1.454735 4.075711,-1.690889 7.422667,-1.718933 2.429601,5.958967 3.425287,10.006398 3.554576,16.310146 0.0027,0.132479 -5.009127,0.279466 -7.459522,0.428844 -1.115361,0.06799 -6.437185,1.634599 -6.436279,1.696552 m 27.792586,0 c 2.303893,-5.916319 4.547942,-7.427001 8.457697,-12.686376 -2.243509,-1.822839 -4.384144,-3.010309 -7.168497,-3.422161 -3.974594,5.25596 -5.799798,8.284538 -7.577259,13.875898 1.006793,-5.967855 0.777829,-9.067377 3.369501,-14.48397 -2.952598,-1.454735 -4.075711,-1.690889 -7.422667,-1.718933 -2.429601,5.958967 -3.425287,10.006398 -3.554576,16.310146 -0.0027,0.132479 5.009127,0.279466 7.459522,0.428844 1.115361,0.06799 6.437185,1.634599 6.436279,1.696552"
+     id="path115"
+     sodipodi:nodetypes="ccccccssc"
+     inkscape:path-effect="#path-effect940"
+     inkscape:original-d="M 11.067311,32.377003 C 8.7634184,26.460684 6.519369,24.950002 2.6096143,19.690627 4.853123,17.867788 6.9937585,16.680318 9.7781105,16.268466 c 3.9745945,5.25596 5.7997985,8.284538 7.5772595,13.875898 -1.006793,-5.967855 -0.777829,-9.067377 -3.369501,-14.48397 2.952598,-1.454735 4.075711,-1.690889 7.422667,-1.718933 2.429601,5.958967 3.425287,10.006398 3.554576,16.310146 0.0027,0.132479 -5.009127,0.279466 -7.459522,0.428844 -1.115361,0.06799 -6.437185,1.634599 -6.436279,1.696552" />
+</svg>
diff --git a/client/public/images/pieces/Empire/we.svg b/client/public/images/pieces/Empire/we.svg
new file mode 100644 (file)
index 0000000..5a97716
--- /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="svg109"
+   sodipodi:docname="gE.svg"
+   inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
+  <metadata
+     id="metadata113">
+    <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="1679"
+     inkscape:window-height="1779"
+     id="namedview111"
+     showgrid="false"
+     inkscape:zoom="0.45149549"
+     inkscape:cx="-323.75502"
+     inkscape:cy="-0.56984743"
+     inkscape:window-x="8388"
+     inkscape:window-y="1097"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg109" />
+  <defs
+     id="defs99">
+    <inkscape:path-effect
+       effect="mirror_symmetry"
+       start_point="24.963604,10.991927"
+       end_point="24.963604,32.279336"
+       center_point="24.963604,21.635632"
+       id="path-effect940"
+       is_visible="true"
+       lpeversion="1"
+       mode="free"
+       discard_orig_path="false"
+       fuse_paths="false"
+       oposite_fuse="false"
+       split_items="false" />
+    <linearGradient
+       id="0"
+       x1="21.376"
+       x2="77.64"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         stop-color="#fff"
+         id="stop94" />
+      <stop
+         offset="1"
+         stop-color="#fff"
+         stop-opacity="0"
+         id="stop96" />
+    </linearGradient>
+  </defs>
+  <path
+     style="fill:#ffdd55;fill-opacity:1;stroke:#1f1a17;stroke-width:1.69328895;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     d="m 21.907796,8.2358869 c -0.86122,-2.1883398 -9.315775,0.1598078 -13.9875092,4.4413111 -0.52591,1.824894 -1.3133175,3.369897 -3.0785923,3.868239 -1.179644,3.319042 -0.086818,6.638087 0.602334,9.957129 1.0777195,-1.737182 2.5809413,-3.110015 4.55096,-4.083137 5.2551265,0.537969 9.9025435,1.018949 15.7275825,3.796601 l -6.960291,0.429805 -4.082478,0.987816 c -1.450439,0.916396 -4.071163,1.470184 -4.9897255,0.86846 0.08535,2.226331 3.7535045,3.407855 6.1274655,3.373007 3.257044,-1.727895 3.442889,-0.922619 4.922545,-1.958721 l 3.346293,0.214902 c 4.411142,1.768146 6.205452,3.180708 3.553903,6.8802 -0.832208,1.035275 -5.458257,1.502473 -6.286926,0.359979 0.511265,1.694316 0.97703,2.766924 3.264451,3.959331 l -3.548762,3.653338 23.785263,0.07163 -2.467197,-5.300919 3.990787,0.08477 c -2.853263,-0.674372 -5.191592,-8.705727 -7.435172,-13.527134 1.458199,1.039234 5.632294,-0.01479 5.378033,-1.081992 -3.3652,-1.717117 -6.723991,-5.194569 -10.260431,-8.501177 2.334781,0.255781 6.807646,-2.29194 4.578939,-6.272786 -0.593763,2.010555 -1.790474,2.650994 -5.018445,3.621259 -3.187387,0.680342 -7.892026,-3.809514 -11.713027,-5.8419121 z"
+     id="path981"
+     sodipodi:nodetypes="cccccccccccccccccccccccccc" />
+  <path
+     style="fill:none;fill-opacity:1;stroke:#1f1a17;stroke-width:1.12886;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     d="m 7.9202868,12.677198 c 2.4453062,0.151572 4.6992092,4.307622 4.2774242,6.240715 7.115641,0.868251 18.334532,3.402826 19.878631,9.319596 l -5.599535,2.616336"
+     id="path983"
+     sodipodi:nodetypes="cccc" />
+  <g
+     id="g1658"
+     transform="matrix(0.92585677,0.20183553,-0.63191424,1.3148673,62.758462,-1.3885936)"
+     inkscape:transform-center-x="-1.688102"
+     inkscape:transform-center-y="2.2435225">
+    <path
+       transform="matrix(0.99827924,-0.05863924,0.05205563,0.99864419,0,0)"
+       d="m -34.957206,15.022757 a 2.6520433,2.044029 0 0 1 -1.378713,1.793015 2.6520433,2.044029 0 0 1 -2.702642,-0.07125 2.6520433,2.044029 0 0 1 -1.216533,-1.861432 l 2.645845,0.139666 z"
+       sodipodi:end="3.2099747"
+       sodipodi:start="0"
+       sodipodi:ry="2.044029"
+       sodipodi:rx="2.6520433"
+       sodipodi:cy="15.022757"
+       sodipodi:cx="-37.609249"
+       sodipodi:type="arc"
+       id="path13436"
+       style="opacity:1;fill:#1f1a17;fill-opacity:1;stroke:#1f1a17;stroke-width:1.8387;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
+       sodipodi:arc-type="slice" />
+    <path
+       inkscape:connector-curvature="0"
+       id="path13438"
+       d="m -34.597186,17.104766 3.011734,-0.187452"
+       style="fill:#1f1a17;fill-opacity:1;stroke:#1f1a17;stroke-width:1.83863;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       sodipodi:nodetypes="cc" />
+  </g>
+</svg>
diff --git a/client/public/images/pieces/Empire/wk.svg b/client/public/images/pieces/Empire/wk.svg
new file mode 100644 (file)
index 0000000..8f885c2
--- /dev/null
@@ -0,0 +1,127 @@
+<?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="svg109"
+   sodipodi:docname="gK.svg"
+   inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
+  <metadata
+     id="metadata113">
+    <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="3840"
+     inkscape:window-height="2050"
+     id="namedview111"
+     showgrid="false"
+     inkscape:zoom="1.2770221"
+     inkscape:cx="-634.39273"
+     inkscape:cy="-0.53333776"
+     inkscape:window-x="-12"
+     inkscape:window-y="-12"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg109"
+     inkscape:document-rotation="0" />
+  <defs
+     id="defs99">
+    <inkscape:path-effect
+       effect="mirror_symmetry"
+       start_point="24.963604,10.991927"
+       end_point="24.963604,32.279336"
+       center_point="24.963604,21.635632"
+       id="path-effect940"
+       is_visible="true"
+       lpeversion="1"
+       mode="free"
+       discard_orig_path="false"
+       fuse_paths="false"
+       oposite_fuse="false"
+       split_items="false" />
+    <linearGradient
+       id="0"
+       x1="21.376"
+       x2="77.64"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         stop-color="#fff"
+         id="stop94" />
+      <stop
+         offset="1"
+         stop-color="#fff"
+         stop-opacity="0"
+         id="stop96" />
+    </linearGradient>
+  </defs>
+  <g
+     fill="#1f1a17"
+     id="g105">
+    <path
+       d="m 11.03,37.744 -0.813,-4.64 C 10.1259,32.251198 10.034508,32.036678 9.8706008,31.262839 24.625024,28.846934 25.638298,28.239 39.9661,31.443633 39.861502,31.990427 39.763128,32.541529 39.685,33.104 l -0.796,4.665 1.643,6.121 c -0.83,0.745 -2.684,1.355 -5.554,1.837 -2.879,0.483 -6.206,0.72 -9.974,0.72 -3.835,0 -7.214,-0.254 -10.118,-0.754 C 11.974,45.185 10.145,44.55 9.4,43.796 l 1.634,-6.05"
+       id="path103"
+       sodipodi:nodetypes="ccccccccsccc" />
+  </g>
+  <path
+     fill="url(#0)"
+     d="m 12.546,36.228 c 3.141,-0.796 7.307,-1.194 12.505,-1.194 5.089,0 9.203,0.381 12.327,1.143 l 0.618,-3.649 c -8.499377,-1.517057 -17.806527,-2.147852 -26.07,0.026 l 0.618,3.675 m 25.298,4.411 -0.737,-2.845 c -3.277,-0.728 -7.332,-1.092 -12.158,-1.092 -4.809,0 -8.856,0.364 -12.133,1.092 l -0.787,2.87 c 3.158,-0.923 7.468,-1.389 12.945,-1.389 5.444,0 9.728,0.457 12.869,1.363 m 0.652,2.337 c -3.192,-1.287 -7.679,-1.939 -13.445,-1.939 -5.986,0 -10.516,0.66 -13.598,1.99 2.913,1.151 7.417,1.736 13.521,1.736 2.913,0 5.563,-0.161 7.959,-0.483 2.404,-0.322 4.25,-0.762 5.563,-1.304"
+     id="path107"
+     style="fill:#ffdd55"
+     sodipodi:nodetypes="csccccccsccsccscscc" />
+  <path
+     style="fill:#ffdd55;stroke:#1f1a17;stroke-width:1.69329;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     d="M 13.056261,30.940538 10.85421,19.411945 C 12.69366,8.5800133 33.989457,5.9872159 39.066293,19.259604 L 36.981444,31.548273 C 27.586346,29.082944 21.919487,29.650456 13.056261,30.940538 Z"
+     id="path946"
+     sodipodi:nodetypes="ccccc" />
+  <path
+     d="M 25.859,10.077597 H 24.098 V 6.8265975 h -2.066 c -0.559,0 -0.838,-0.2710002 -0.838,-0.8210002 v -0.025001 c 0,-0.5419988 0.279,-0.8129987 0.838,-0.8129987 h 2.066 V 3.0595977 c 0,-0.584 0.296,-0.872 0.889,-0.872 0.576001,0 0.872,0.288 0.872,0.872 v 2.1079999 h 2.134001 c 0.541999,0 0.812999,0.2709999 0.812999,0.8130001 v 0.025001 c 0,0.55 -0.271,0.8210002 -0.812999,0.8210002 L 25.876,6.8515979 25.859,10.077598"
+     id="path3063"
+     style="fill:#1f1a17;stroke-width:1" />
+  <path
+     style="fill:#ffdd55;fill-opacity:1;stroke:#1f1a17;stroke-width:1.69329;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     d="M 10.841001,31.677729 8.3212011,6.0837864 18.029269,30.447129 c -2.17632,0.136657 -4.797208,1.138009 -7.188268,1.2306 z"
+     id="path3094"
+     sodipodi:nodetypes="cccc" />
+  <path
+     style="fill:#ffdd55;fill-opacity:1;stroke:#1f1a17;stroke-width:1.69329;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     d="m 39.129915,31.677802 2.5198,-25.5939422 -9.708068,24.3633422 c 2.17632,0.136657 4.797208,1.138009 7.188268,1.2306 z"
+     id="path3657"
+     sodipodi:nodetypes="cccc" />
+  <path
+     style="fill:none;stroke:#1f1a17;stroke-width:1.41107;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     d="m 24.905446,10.203663 c -4.753732,5.097873 -7.398643,11.180374 -5.247806,19.934459 0,0 4.502763,0.303866 4.392265,-0.08287 -2.971144,-6.511338 -0.787269,-13.494384 0.855541,-19.851589 z"
+     id="path3659"
+     sodipodi:nodetypes="cccc" />
+  <path
+     style="fill:none;stroke:#1f1a17;stroke-width:1.41107;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     d="m 25.276579,10.203663 c 4.472554,5.538114 7.968282,11.781352 5.247806,19.934459 0,0 -4.502763,0.303866 -4.392265,-0.08287 2.971144,-6.511338 0.787269,-13.494384 -0.855541,-19.851589 z"
+     id="path3661"
+     sodipodi:nodetypes="cccc" />
+</svg>
diff --git a/client/public/images/pieces/Empire/wp.svg b/client/public/images/pieces/Empire/wp.svg
new file mode 100644 (file)
index 0000000..89ce4af
--- /dev/null
@@ -0,0 +1,95 @@
+<?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="svg3691"
+   sodipodi:docname="gP.svg"
+   inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
+  <metadata
+     id="metadata3695">
+    <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="3840"
+     inkscape:window-height="2050"
+     id="namedview3693"
+     showgrid="false"
+     inkscape:zoom="5.6894509"
+     inkscape:cx="88.584999"
+     inkscape:cy="88.584999"
+     inkscape:window-x="-12"
+     inkscape:window-y="-12"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg3691" />
+  <defs
+     id="defs3685">
+    <linearGradient
+       id="0"
+       gradientUnits="userSpaceOnUse"
+       x1="21.13"
+       y1="37.35"
+       x2="77.76"
+       y2="37.469"
+       gradientTransform="matrix(1 0 0 .97324 0 1.243)">
+      <stop
+         stop-color="#fff"
+         id="stop3680" />
+      <stop
+         offset="1"
+         stop-color="#fff"
+         stop-opacity="0"
+         id="stop3682" />
+    </linearGradient>
+    <inkscape:path-effect
+       effect="mirror_symmetry"
+       start_point="24.963604,10.991927"
+       end_point="24.963604,32.279336"
+       center_point="24.963604,21.635632"
+       id="path-effect940"
+       is_visible="true"
+       lpeversion="1"
+       mode="free"
+       discard_orig_path="false"
+       fuse_paths="false"
+       oposite_fuse="false"
+       split_items="false" />
+  </defs>
+  <path
+     d="m25 46.45h-13.394c-.66-1.607-.991-3.288-.991-5.04 0-2.975.864-5.644 2.599-8.02 1.736-2.365 3.971-4.054 6.697-5.068-1.168-.527-2.125-1.327-2.862-2.398-.737-1.071-1.101-2.283-1.101-3.634 0-1.689.576-3.156 1.736-4.392 1.152-1.244 2.574-1.961 4.267-2.151-1.346-.981-2.02-2.282-2.02-3.889 0-1.351.491-2.513 1.482-3.477.982-.964 2.176-1.442 3.581-1.442 1.389 0 2.582.478 3.573 1.442.991.964 1.49 2.126 1.49 3.477 0 1.607-.669 2.909-2.02 3.889 1.693.19 3.116.906 4.267 2.151 1.16 1.236 1.736 2.703 1.736 4.392 0 1.351-.373 2.563-1.126 3.634-.753 1.071-1.71 1.87-2.862 2.398 2.726 1.014 4.961 2.703 6.697 5.068 1.736 2.373 2.599 5.04 2.599 8.02 0 1.739-.322 3.42-.965 5.04h-13.394"
+     fill="#1f1a17"
+     id="path3687" />
+  <path
+     d="m25 44.808h12.175c.347-1.154.525-2.291.525-3.403 0-2.513-.711-4.787-2.142-6.831-1.431-2.044-3.277-3.552-5.52-4.516-1.584-.62-1.643-.659-1.643-1.739 0-.849.559-1.475 1.668-1.879 1.532-1.047 2.303-2.431 2.303-4.153 0-1.244-.432-2.324-1.287-3.263-.864-.931-1.905-1.467-3.124-1.615-.999-.082-1.49-.626-1.49-1.64 0-.453.178-.873.542-1.261.898-.676 1.346-1.557 1.346-2.653 0-.898-.339-1.673-.999-2.316-.66-.643-1.448-.964-2.354-.964-.94 0-1.744.321-2.396.964-.652.643-.974 1.417-.974 2.316 0 1.079.44 1.961 1.338 2.653.364.354.542.775.542 1.261 0 1.014-.483 1.557-1.465 1.64-1.236.148-2.286.684-3.133 1.615-.855.939-1.279 2.02-1.279 3.263 0 1.722.77 3.106 2.303 4.153 1.109.412 1.668 1.046 1.668 1.879 0 1.079-.067 1.118-1.668 1.739-2.244.964-4.081 2.472-5.503 4.516-1.422 2.044-2.134 4.318-2.134 6.831 0 1.195.178 2.324.525 3.403h12.175"
+     fill="url(#0)"
+     id="path3689"
+     style="fill:#ffdd55;fill-opacity:1" />
+</svg>
diff --git a/client/public/images/pieces/Empire/wq.svg b/client/public/images/pieces/Empire/wq.svg
new file mode 100644 (file)
index 0000000..3034665
--- /dev/null
@@ -0,0 +1,99 @@
+<?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="svg2124"
+   sodipodi:docname="gQ.svg"
+   inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
+  <metadata
+     id="metadata2128">
+    <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="3840"
+     inkscape:window-height="2050"
+     id="namedview2126"
+     showgrid="false"
+     inkscape:zoom="5.6894509"
+     inkscape:cx="88.584999"
+     inkscape:cy="88.584999"
+     inkscape:window-x="-12"
+     inkscape:window-y="-12"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2124" />
+  <defs
+     id="defs2116">
+    <linearGradient
+       id="0"
+       x1="21.253"
+       y1="37.22"
+       x2="77.64"
+       y2="37.35"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         stop-color="#fff"
+         id="stop2111" />
+      <stop
+         offset="1"
+         stop-color="#fff"
+         stop-opacity="0"
+         id="stop2113" />
+    </linearGradient>
+    <inkscape:path-effect
+       effect="mirror_symmetry"
+       start_point="24.963604,10.991927"
+       end_point="24.963604,32.279336"
+       center_point="24.963604,21.635632"
+       id="path-effect940"
+       is_visible="true"
+       lpeversion="1"
+       mode="free"
+       discard_orig_path="false"
+       fuse_paths="false"
+       oposite_fuse="false"
+       split_items="false" />
+  </defs>
+  <g
+     stroke="#1f1a17"
+     stroke-width=".076"
+     id="g2122">
+    <path
+       fill="#1f1a17"
+       d="m44.541 14.723c-.94 0-1.744-.33-2.405-.982-.66-.652-.991-1.448-.991-2.396 0-.923.33-1.719.991-2.388.66-.677 1.465-1.01 2.405-1.01.931 0 1.727.33 2.388 1.01.66.669.991 1.465.991 2.388 0 .948-.33 1.744-.991 2.396-.66.652-1.456.982-2.388.982zm-4.31 29.22c-.813.711-2.633 1.304-5.461 1.786-2.828.474-6.087.72-9.77.72-3.751 0-7.05-.254-9.898-.745-2.845-.499-4.64-1.118-5.385-1.863l1.566-5.952-.694-3.895-2.184-3.793-2.108-15.426 1.211-.474 6.799 11.455.152-13.64 1.685-.296 5.182 13.716 2.777-14.757h1.719l2.777 14.707 5.131-13.665 1.71.296.152 13.64 6.824-11.481 1.16.542-2.057 15.359-2.21 3.793-.694 3.946 1.617 6.03zm-25.696-31.953c-.948 0-1.753-.322-2.413-.974-.66-.652-.991-1.456-.991-2.396 0-.923.33-1.719.991-2.379.66-.66 1.465-.991 2.413-.991.923 0 1.719.33 2.379.991.66.66.991 1.456.991 2.379 0 .94-.33 1.744-.991 2.396-.66.652-1.456.974-2.379.974zm-9.136 2.735c-.94 0-1.736-.33-2.388-.982-.652-.652-.982-1.448-.982-2.396 0-.923.33-1.719.982-2.388.652-.677 1.448-1.01 2.388-1.01.948 0 1.744.33 2.413 1.01.66.669.991 1.465.991 2.388 0 .948-.33 1.744-.991 2.396-.669.652-1.465.982-2.413.982zm19.55-3.971c-.94 0-1.744-.33-2.396-.991-.652-.66-.974-1.465-.974-2.405 0-.931.322-1.727.974-2.388.652-.66 1.456-.991 2.396-.991.923 0 1.727.33 2.396.991.669.66.999 1.456.999 2.388 0 .94-.33 1.744-.999 2.405-.669.66-1.473.991-2.396.991zm10.414 1.236c-.94 0-1.736-.322-2.388-.974-.652-.652-.982-1.456-.982-2.396 0-.923.33-1.719.982-2.379.652-.66 1.448-.991 2.388-.991.948 0 1.753.33 2.413.991.66.66.991 1.456.991 2.379 0 .94-.33 1.744-.991 2.396-.66.652-1.465.974-2.413.974z"
+       id="path2118" />
+    <path
+       fill="url(#0)"
+       d="m38.22 43.04c-3.02-1.253-7.417-1.88-13.166-1.88-5.876 0-10.312.643-13.327 1.93 2.896 1.143 7.315 1.71 13.25 1.71 2.845 0 5.444-.152 7.798-.466 2.362-.313 4.174-.745 5.444-1.295zm-13.267-34.03c1.109 0 1.66-.559 1.66-1.659 0-1.092-.55-1.643-1.66-1.643-1.092 0-1.634.55-1.634 1.643 0 1.101.542 1.659 1.634 1.659zm12.624 24.977c-3.192-.813-7.366-1.211-12.522-1.211-5.292 0-9.517.406-12.675 1.236l.373 2.379c3.217-.762 7.324-1.143 12.302-1.143 4.944 0 8.975.373 12.1 1.118l.423-2.379zm.618-1.49l1.617-2.853c-.796.322-1.609.474-2.43.474-2.218 0-3.988-.897-5.309-2.701-.991.821-2.1 1.236-3.327 1.236-1.583 0-2.853-.618-3.793-1.863-1.058 1.16-2.32 1.744-3.793 1.744-1.194 0-2.286-.406-3.277-1.219-1.389 1.77-3.183 2.65-5.385 2.65-.838 0-1.676-.152-2.506-.466l1.736 2.972c3.209-.923 7.62-1.389 13.225-1.389 5.706 0 10.118.474 13.242 1.414zm-11.11-5.927l-2.108-12.133-2.108 11.989c.051-.034.161-.119.347-.254.381-.745.957-1.118 1.736-1.118.847 0 1.389.372 1.634 1.118.102.102.271.237.5.398zm6.867.474v-11.489l-4.089 11.261c.313-.11.576-.262.796-.44.33-.415.779-.627 1.338-.627.66 0 1.194.296 1.592.872.042.068.102.136.169.212.068.076.136.144.195.212zm-13.936-.347l-4.064-11.142v11.337c.042-.068.119-.144.22-.245.33-.694.872-1.041 1.634-1.041.627 0 1.143.262 1.541.796.449.195.669.296.669.296zm-6.299 1.389l-5.334-9.203 1.363 8.382c.94.66 1.863.991 2.752.991.347 0 .754-.059 1.219-.169zm22.394.119c.381.119.804.178 1.27.178 1.01 0 1.947-.313 2.828-.94l1.363-8.585-5.461 9.347zm1.49 12.556l-.745-2.802c-3.243-.711-7.205-1.067-11.904-1.067-4.648 0-8.611.356-11.879 1.067l-.771 2.828c3.073-.931 7.298-1.389 12.675-1.389 5.241 0 9.449.449 12.624 1.363zm-23.06-30.514c1.084 0 1.634-.542 1.634-1.634 0-1.092-.55-1.634-1.634-1.634-1.109 0-1.668.542-1.668 1.634 0 1.092.559 1.634 1.668 1.634zm20.828 0c1.109 0 1.668-.542 1.668-1.634 0-1.092-.559-1.634-1.668-1.634-1.084 0-1.634.542-1.634 1.634 0 1.092.55 1.634 1.634 1.634zm-29.964 2.735c1.109 0 1.668-.55 1.668-1.643 0-1.109-.559-1.659-1.668-1.659-1.084 0-1.634.55-1.634 1.659 0 1.092.55 1.643 1.634 1.643zm39.14 0c1.092 0 1.642-.55 1.642-1.643 0-1.109-.55-1.659-1.642-1.659-1.101 0-1.66.55-1.66 1.659 0 1.092.559 1.643 1.66 1.643z"
+       id="path2120"
+       style="fill:#ffdd55;fill-opacity:1" />
+  </g>
+</svg>
diff --git a/client/public/images/pieces/Empire/ws.svg b/client/public/images/pieces/Empire/ws.svg
new file mode 100644 (file)
index 0000000..edefbef
--- /dev/null
@@ -0,0 +1,88 @@
+<?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"
+   inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"
+   sodipodi:docname="gS.svg"
+   id="svg4260"
+   version="1.1"
+   viewBox="0 0 50 50"
+   clip-rule="evenodd"
+   fill-rule="evenodd"
+   image-rendering="optimizeQuality"
+   shape-rendering="geometricPrecision"
+   height="177.17"
+   width="177.17">
+  <metadata
+     id="metadata4266">
+    <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>
+  <defs
+     id="defs4264">
+    <inkscape:path-effect
+       effect="mirror_symmetry"
+       start_point="-103.61098,-3.3341898"
+       end_point="-103.61098,147.39645"
+       center_point="-103.61098,72.03113"
+       id="path-effect4256"
+       is_visible="true"
+       lpeversion="1"
+       mode="free"
+       discard_orig_path="false"
+       fuse_paths="true"
+       oposite_fuse="false"
+       split_items="false" />
+    <inkscape:path-effect
+       effect="mirror_symmetry"
+       start_point="24.963604,10.991927"
+       end_point="24.963604,32.279336"
+       center_point="24.963604,21.635632"
+       id="path-effect940"
+       is_visible="true"
+       lpeversion="1"
+       mode="free"
+       discard_orig_path="false"
+       fuse_paths="false"
+       oposite_fuse="false"
+       split_items="false" />
+  </defs>
+  <sodipodi:namedview
+     inkscape:current-layer="svg4260"
+     inkscape:window-maximized="1"
+     inkscape:window-y="1085"
+     inkscape:window-x="6708"
+     inkscape:cy="84.642152"
+     inkscape:cx="141.3325"
+     inkscape:zoom="6.9285849"
+     showgrid="false"
+     id="namedview4262"
+     inkscape:window-height="1780"
+     inkscape:window-width="3360"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0"
+     guidetolerance="10"
+     gridtolerance="10"
+     objecttolerance="10"
+     borderopacity="1"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     inkscape:document-rotation="0" />
+  <path
+     id="path2176-6"
+     style="fill:#ffdd55;fill-opacity:1;stroke:#000000;stroke-width:1.69328895;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
+     d="M 25.000001,6.2475591 C 23.200034,15.549591 11.577004,24.029711 8.0288377,26.95148 14.360789,26.549197 19.354139,25.335848 21.5291,25.353044 20.503337,38.890575 11.088252,36.163899 8.8189178,44.791394 c 4.6896962,0 10.4144202,-0.02612 16.1810832,-0.05107 5.766661,0.02495 11.491387,0.05107 16.181082,0.05107 -2.347504,-8.393109 -11.684419,-5.900819 -12.710182,-19.43835 2.174961,-0.0172 7.168312,1.196153 13.500262,1.598436 C 38.422998,24.029711 26.799967,15.549591 25.000001,6.2475591 Z"
+     sodipodi:nodetypes="ccccccccc" />
+</svg>
diff --git a/client/public/images/pieces/Empire/wt.svg b/client/public/images/pieces/Empire/wt.svg
new file mode 100644 (file)
index 0000000..6800102
--- /dev/null
@@ -0,0 +1,125 @@
+<?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="svg1722"
+   sodipodi:docname="gT.svg"
+   inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
+  <metadata
+     id="metadata1726">
+    <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="3840"
+     inkscape:window-height="2050"
+     id="namedview1724"
+     showgrid="false"
+     inkscape:zoom="2.0115246"
+     inkscape:cx="58.806731"
+     inkscape:cy="230.32027"
+     inkscape:window-x="-12"
+     inkscape:window-y="-12"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg1722" />
+  <defs
+     id="defs1716">
+    <linearGradient
+       id="0"
+       x1="21.376"
+       x2="77.64"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         stop-color="#fff"
+         id="stop1711" />
+      <stop
+         offset="1"
+         stop-color="#fff"
+         stop-opacity="0"
+         id="stop1713" />
+    </linearGradient>
+    <inkscape:path-effect
+       effect="mirror_symmetry"
+       start_point="24.963604,10.991927"
+       end_point="24.963604,32.279336"
+       center_point="24.963604,21.635632"
+       id="path-effect940"
+       is_visible="true"
+       lpeversion="1"
+       mode="free"
+       discard_orig_path="false"
+       fuse_paths="false"
+       oposite_fuse="false"
+       split_items="false" />
+  </defs>
+  <g
+     id="g2346"
+     transform="translate(-47.294865,-0.59711957)"
+     style="fill:#ffdd55;fill-opacity:1">
+    <path
+       style="fill:#ffdd55;stroke:#1f1a17;stroke-width:1.69329;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1"
+       d="M 77.01174,6.6646411 H 57.922216 V 43.633418 H 87.464014 C 84.800606,33.069099 80.963403,19.989506 77.01174,6.6646411 Z"
+       id="path1728"
+       sodipodi:nodetypes="ccccc" />
+    <circle
+       style="fill:#ffdd55;fill-opacity:1;stroke:#1f1a17;stroke-width:1.69329;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="circle2293"
+       cx="85.307617"
+       cy="41.959423"
+       r="4.2410712" />
+    <path
+       style="fill:#ffdd55;fill-opacity:1;stroke:#1f1a17;stroke-width:1.69329;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 77.01174,6.6646411 V 43.898808"
+       id="path2295"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:#ffdd55;fill-opacity:1;stroke:#1f1a17;stroke-width:1.69329;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 58.21581,25.298871 H 82.676576"
+       id="path2297"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:#ffdd55;fill-opacity:1;stroke:#1f1a17;stroke-width:1.69329;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 57.922214,43.633419 77.02705,25.654604"
+       id="path2299"
+       sodipodi:nodetypes="cc" />
+    <circle
+       style="fill:#ffdd55;fill-opacity:1;stroke:#1f1a17;stroke-width:1.69329;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="path2291"
+       cx="59.282112"
+       cy="41.959423"
+       r="4.2410712" />
+    <path
+       style="fill:#ffdd55;fill-opacity:1;stroke:#1f1a17;stroke-width:1.69329;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 57.922214,6.6837255 77.02705,25.654604"
+       id="path2303"
+       sodipodi:nodetypes="cc" />
+  </g>
+</svg>
diff --git a/client/public/variants/Empire/Board.png b/client/public/variants/Empire/Board.png
new file mode 100644 (file)
index 0000000..efbfec8
--- /dev/null
@@ -0,0 +1 @@
+#$# git-fat 759292776cfaf7e3ed788fe32d14b99c138fb211                34156
diff --git a/client/public/variants/Empire/EagleMoves.png b/client/public/variants/Empire/EagleMoves.png
new file mode 100644 (file)
index 0000000..0f264b9
--- /dev/null
@@ -0,0 +1 @@
+#$# git-fat 471867cda344bda2feee24069e7eb8f1af3029c3                15689
diff --git a/client/src/translations/rules/Empire/en.pug b/client/src/translations/rules/Empire/en.pug
new file mode 100644 (file)
index 0000000..d0fbaa6
--- /dev/null
@@ -0,0 +1,118 @@
+p.boxed
+  | The player in first has a different set of pieces,
+  | moving generally like a queen but capturing (almost) as usual.
+
+figure
+  img.img-center(src="/variants/Empire/Board.png")
+  figcaption.text-center Initial deterministic setup.
+
+p.
+  Empire Chess is a chess variant designed in 2020 by Couch Tomato, the third
+  asymmetric game. This game pits the army of the "Empire" (gold) against the
+  original chess army (the "Kingdom", black). The Empire's unique feature is
+  that its pieces move like queens but attack differently.
+
+h3 General Rules
+
+ol
+  li The Empire (gold) always moves first.
+  li The Empire cannot castle.
+  li.
+    As the Empire's pawns start on the third rank, they do not have the
+    option to move two spaces or be captured by en passant. Kingdom pawns
+    retain the ability to move two spaces initially and to be captured via
+    en passant.
+  li Pawns on either side can only promote to a queen.
+  li.
+    An additional method of victory is available: called campmate.
+    Campmate is achieved by moving one's king into the final rank
+    without being check.
+  li Stalemate and repetition are both losses.
+  li.
+    Facing kings &mdash; The King and Kaiser (Imperial King) may not face
+    each other on a file or rank, similar to Xiangqi.
+
+h3 Imperial Pieces
+
+p.
+  There are five new units unique to the Empire: 2 Siege Towers, 2 Eagles,
+  2 Cardinals, 1 Duke, and 2 Soldiers. The bottom rank are all stronger than
+  their Kingdom counterparts with the exception of the Duke.
+
+ul
+  li.
+    Kaiser (K) &mdash; The Imperial king is called the Kaiser and has a
+    different symbol, but is essentially the same as the Kingdom's King,
+    also using the same abbreviation (K) &mdash; the change is purely
+    aesthetic and thematic.
+  li.
+    Soldier (S) &mdash; The Soldiers are the two pawn-like pieces replacing
+    the two middle pawns. These act like promoted soldiers in Xiangqi and
+    can move one square orthogonally in any direction except backwards.
+
+p.
+  The remaining pieces are divergent pieces, pieces that move differently
+  than they attack (such as pawns). Imperial pieces all move as queens,
+  but attack like their Kingdom counterpart except for the Duke.
+
+ul
+  li.
+    Siege Tower (T) &mdash; The Siege Tower, or Tower for short, moves like a
+    Queen but attacks like a Rook.
+  li Eagle (E) &mdash; The Eagle moves like a Queen but attacks like a Knight.
+  li.
+    Cardinal (C) &mdash; The Cardinal moves like a Queen
+    but attacks like a Bishop.
+  li Duke (D) &mdash; The Duke moves like a Queen but attacks like a King.
+
+figure
+  img.img-center(src="/variants/Empire/EagleMoves.png")
+  figcaption.text-center Eagle's moves (green) & captures (red).
+
+h3 Piece valuation
+
+p The following simplified values are used by the bot:
+
+table
+  tr
+    th Kingdom piece
+    th Value
+    th Imperial piece
+    th Value
+  tr
+    td Pawn
+    td 1
+    td Pawn
+    td 1
+  tr
+    td Queen
+    td 9
+    td Duke
+    td 4
+  tr
+    td Bishop
+    td 3
+    td Cardinal
+    td 4
+  tr
+    td Knight
+    td 3
+    td Eagle
+    td 7
+  tr
+    td Rook
+    td 5
+    td Siege Tower
+    td 7
+  tr
+    td Soldier
+    td 2
+    td -
+    td -
+
+h3 More information
+
+p
+  | See 
+  a(href="https://www.pychess.org/variant/empirechess") Empire Chess
+  | &nbsp;on pychess-variants, where you can also play this variant.
diff --git a/client/src/translations/rules/Empire/es.pug b/client/src/translations/rules/Empire/es.pug
new file mode 100644 (file)
index 0000000..21203ba
--- /dev/null
@@ -0,0 +1 @@
+p.boxed TODO
diff --git a/client/src/translations/rules/Empire/fr.pug b/client/src/translations/rules/Empire/fr.pug
new file mode 100644 (file)
index 0000000..21203ba
--- /dev/null
@@ -0,0 +1 @@
+p.boxed TODO
diff --git a/client/src/translations/rules/Synochess/en.pug b/client/src/translations/rules/Synochess/en.pug
new file mode 100644 (file)
index 0000000..21203ba
--- /dev/null
@@ -0,0 +1 @@
+p.boxed TODO
diff --git a/client/src/translations/rules/Synochess/es.pug b/client/src/translations/rules/Synochess/es.pug
new file mode 100644 (file)
index 0000000..21203ba
--- /dev/null
@@ -0,0 +1 @@
+p.boxed TODO
diff --git a/client/src/translations/rules/Synochess/fr.pug b/client/src/translations/rules/Synochess/fr.pug
new file mode 100644 (file)
index 0000000..21203ba
--- /dev/null
@@ -0,0 +1 @@
+p.boxed TODO
diff --git a/client/src/variants/Empire.js b/client/src/variants/Empire.js
new file mode 100644 (file)
index 0000000..2ce8493
--- /dev/null
@@ -0,0 +1,436 @@
+import { ChessRules } from "@/base_rules";
+
+export class EmpireRules extends ChessRules {
+
+  static get PawnSpecs() {
+    return Object.assign(
+      {},
+      ChessRules.PawnSpecs,
+      { promotions: [V.QUEEN] }
+    );
+  }
+
+  static get LoseOnRepetition() {
+    return true;
+  }
+
+  static IsGoodFlags(flags) {
+    // Only black can castle
+    return !!flags.match(/^[a-z]{2,2}$/);
+  }
+
+  getPpath(b) {
+    return (b[0] == 'w' ? "Empire/" : "") + b;
+  }
+
+  static GenRandInitFen(randomness) {
+    if (randomness == 0)
+      return "rnbqkbnr/pppppppp/8/8/8/PPPSSPPP/8/TECDKCET w 0 ah -";
+
+    // Mapping kingdom --> empire:
+    const piecesMap = {
+      'R': 'T',
+      'N': 'E',
+      'B': 'C',
+      'Q': 'D',
+      'K': 'K'
+    };
+
+    const baseFen = ChessRules.GenRandInitFen(randomness);
+    return (
+      baseFen.substr(0, 24) + "PPPSSPPP/8/" +
+      baseFen.substr(35, 8).split('').map(p => piecesMap[p]).join('') +
+      baseFen.substr(43, 5) + baseFen.substr(50)
+    );
+  }
+
+  getFlagsFen() {
+    return this.castleFlags['b'].map(V.CoordToColumn).join("");
+  }
+
+  setFlags(fenflags) {
+    this.castleFlags = { 'b': [-1, -1] };
+    for (let i = 0; i < 2; i++)
+      this.castleFlags['b'][i] = V.ColumnToCoord(fenflags.charAt(i));
+  }
+
+  static get TOWER() {
+    return 't';
+  }
+  static get EAGLE() {
+    return 'e';
+  }
+  static get CARDINAL() {
+    return 'c';
+  }
+  static get DUKE() {
+    return 'd';
+  }
+  static get SOLDIER() {
+    return 's';
+  }
+  // Kaiser is technically a King, so let's keep things simple.
+
+  static get PIECES() {
+    return ChessRules.PIECES.concat(
+      [V.TOWER, V.EAGLE, V.CARDINAL, V.DUKE, V.SOLDIER]);
+  }
+
+  getPotentialMovesFrom(sq) {
+    let moves = [];
+    const piece = this.getPiece(sq[0], sq[1]);
+    switch (piece) {
+      case V.TOWER:
+        moves = this.getPotentialTowerMoves(sq);
+        break;
+      case V.EAGLE:
+        moves = this.getPotentialEagleMoves(sq);
+        break;
+      case V.CARDINAL:
+        moves = this.getPotentialCardinalMoves(sq);
+        break;
+      case V.DUKE:
+        moves = this.getPotentialDukeMoves(sq);
+        break;
+      case V.SOLDIER:
+        moves = this.getPotentialSoldierMoves(sq);
+        break;
+      default:
+        moves = super.getPotentialMovesFrom(sq);
+    }
+    if (
+      piece != V.KING &&
+      this.kingPos['w'][0] != this.kingPos['b'][0] &&
+      this.kingPos['w'][1] != this.kingPos['b'][1]
+    ) {
+      return moves;
+    }
+    // TODO: factor two next "if" into one (rank/column...)
+    if (this.kingPos['w'][1] == this.kingPos['b'][1]) {
+      const colKing = this.kingPos['w'][1];
+      let intercept = 0; //count intercepting pieces
+      let [kingPos1, kingPos2] = [this.kingPos['w'][0], this.kingPos['b'][0]];
+      if (kingPos1 > kingPos2) [kingPos1, kingPos2] = [kingPos2, kingPos1];
+      for (let i = kingPos1 + 1; i < kingPos2; i++) {
+        if (this.board[i][colKing] != V.EMPTY) intercept++;
+      }
+      if (intercept >= 2) return moves;
+      // intercept == 1 (0 is impossible):
+      // Any move not removing intercept is OK
+      return moves.filter(m => {
+        return (
+          // From another column?
+          m.start.y != colKing ||
+          // From behind a king? (including kings themselves!)
+          m.start.x <= kingPos1 ||
+          m.start.x >= kingPos2 ||
+          // Intercept piece moving: must remain in-between
+          (
+            m.end.y == colKing &&
+            m.end.x > kingPos1 &&
+            m.end.x < kingPos2
+          )
+        );
+      });
+    }
+    if (this.kingPos['w'][0] == this.kingPos['b'][0]) {
+      const rowKing = this.kingPos['w'][0];
+      let intercept = 0; //count intercepting pieces
+      let [kingPos1, kingPos2] = [this.kingPos['w'][1], this.kingPos['b'][1]];
+      if (kingPos1 > kingPos2) [kingPos1, kingPos2] = [kingPos2, kingPos1];
+      for (let i = kingPos1 + 1; i < kingPos2; i++) {
+        if (this.board[rowKing][i] != V.EMPTY) intercept++;
+      }
+      if (intercept >= 2) return moves;
+      // intercept == 1 (0 is impossible):
+      // Any move not removing intercept is OK
+      return moves.filter(m => {
+        return (
+          // From another row?
+          m.start.x != rowKing ||
+          // From "behind" a king? (including kings themselves!)
+          m.start.y <= kingPos1 ||
+          m.start.y >= kingPos2 ||
+          // Intercept piece moving: must remain in-between
+          (
+            m.end.x == rowKing &&
+            m.end.y > kingPos1 &&
+            m.end.y < kingPos2
+          )
+        );
+      });
+    }
+    // piece == king: check only if move.end.y == enemy king column,
+    // or if move.end.x == enemy king rank.
+    const color = this.getColor(sq[0], sq[1]);
+    const oppCol = V.GetOppCol(color);
+    // check == -1 if (row, or col) unchecked, 1 if checked and occupied,
+    //          0 if checked and clear
+    let check = [-1, -1];
+    return moves.filter(m => {
+      if (
+        m.end.y != this.kingPos[oppCol][1] &&
+        m.end.x != this.kingPos[oppCol][0]
+      ) {
+        return true;
+      }
+      // TODO: factor two next "if"...
+      if (m.end.x == this.kingPos[oppCol][0]) {
+        if (check[0] < 0) {
+          // Do the check:
+          check[0] = 0;
+          let [kingPos1, kingPos2] =
+            [this.kingPos[color][1], this.kingPos[oppCol][1]];
+          if (kingPos1 > kingPos2) [kingPos1, kingPos2] = [kingPos2, kingPos1];
+          for (let i = kingPos1 + 1; i < kingPos2; i++) {
+            if (this.board[m.end.x][i] != V.EMPTY) {
+              check[0]++;
+              break;
+            }
+          }
+          return check[0] == 1;
+        }
+        // Check already done:
+        return check[0] == 1;
+      }
+      //if (m.end.y == this.kingPos[oppCol][1]) //true...
+      if (check[1] < 0) {
+        // Do the check:
+        check[1] = 0;
+        let [kingPos1, kingPos2] =
+          [this.kingPos[color][0], this.kingPos[oppCol][0]];
+        if (kingPos1 > kingPos2) [kingPos1, kingPos2] = [kingPos2, kingPos1];
+        for (let i = kingPos1 + 1; i < kingPos2; i++) {
+          if (this.board[i][m.end.y] != V.EMPTY) {
+            check[1]++;
+            break;
+          }
+        }
+        return check[1] == 1;
+      }
+      // Check already done:
+      return check[1] == 1;
+    });
+  }
+
+  getSlideNJumpMoves_([x, y], steps, oneStep) {
+    let moves = [];
+    outerLoop: for (let step of steps) {
+      const s = step.s;
+      let i = x + s[0];
+      let j = y + s[1];
+      while (V.OnBoard(i, j) && this.board[i][j] == V.EMPTY) {
+        if (!step.onlyTake) moves.push(this.getBasicMove([x, y], [i, j]));
+        // NOTE: (bad) HACK here, since onlyTake is true only for Eagle
+        // capturing moves, which are oneStep...
+        if (!!oneStep || !!step.onlyTake) continue outerLoop;
+        i += s[0];
+        j += s[1];
+      }
+      if (V.OnBoard(i, j) && this.canTake([x, y], [i, j]) && !step.onlyMove)
+        moves.push(this.getBasicMove([x, y], [i, j]));
+    }
+    return moves;
+  }
+
+  static get steps() {
+    return (
+      Object.assign(
+        {
+          t: [
+            { s: [-1, 0] },
+            { s: [1, 0] },
+            { s: [0, -1] },
+            { s: [0, 1] },
+            { s: [-1, -1], onlyMove: true },
+            { s: [-1, 1], onlyMove: true },
+            { s: [1, -1], onlyMove: true },
+            { s: [1, 1], onlyMove: true }
+          ],
+          c: [
+            { s: [-1, 0], onlyMove: true },
+            { s: [1, 0], onlyMove: true },
+            { s: [0, -1], onlyMove: true },
+            { s: [0, 1], onlyMove: true },
+            { s: [-1, -1] },
+            { s: [-1, 1] },
+            { s: [1, -1] },
+            { s: [1, 1] }
+          ],
+          e: [
+            { s: [-1, 0], onlyMove: true },
+            { s: [1, 0], onlyMove: true },
+            { s: [0, -1], onlyMove: true },
+            { s: [0, 1], onlyMove: true },
+            { s: [-1, -1], onlyMove: true },
+            { s: [-1, 1], onlyMove: true },
+            { s: [1, -1], onlyMove: true },
+            { s: [1, 1], onlyMove: true },
+            { s: [-2, -1], onlyTake: true },
+            { s: [-2, 1], onlyTake: true },
+            { s: [-1, -2], onlyTake: true },
+            { s: [-1, 2], onlyTake: true },
+            { s: [1, -2], onlyTake: true },
+            { s: [1, 2], onlyTake: true },
+            { s: [2, -1], onlyTake: true },
+            { s: [2, 1], onlyTake: true }
+          ]
+        },
+        ChessRules.steps
+      )
+    );
+  }
+
+  getPotentialTowerMoves(sq) {
+    return this.getSlideNJumpMoves_(sq, V.steps[V.TOWER]);
+  }
+
+  getPotentialCardinalMoves(sq) {
+    return this.getSlideNJumpMoves_(sq, V.steps[V.CARDINAL]);
+  }
+
+  getPotentialEagleMoves(sq) {
+    return this.getSlideNJumpMoves_(sq, V.steps[V.EAGLE]);
+  }
+
+  getPotentialDukeMoves([x, y]) {
+    // Anything to capture around? mark other steps to explore after
+    let steps = [];
+    const oppCol = V.GetOppCol(this.getColor(x, y));
+    let moves = [];
+    for (let s of V.steps[V.ROOK].concat(V.steps[V.BISHOP])) {
+      const [i, j] = [x + s[0], y + s[1]];
+      if (
+        V.OnBoard(i, j) &&
+        this.board[i][j] != V.EMPTY &&
+        this.getColor(i, j) == oppCol
+      ) {
+        moves.push(super.getBasicMove([x, y], [i, j]));
+      }
+      else steps.push({ s: s, onlyMove: true });
+    }
+    if (steps.length > 0) {
+      const noncapturingMoves = this.getSlideNJumpMoves_([x, y], steps);
+      Array.prototype.push.apply(moves, noncapturingMoves);
+    }
+    return moves;
+  }
+
+  getPotentialKingMoves([x, y]) {
+    if (this.getColor(x, y) == 'b') return super.getPotentialKingMoves([x, y]);
+    // Empire doesn't castle:
+    return super.getSlideNJumpMoves(
+      [x, y],
+      V.steps[V.ROOK].concat(V.steps[V.BISHOP]),
+      "oneStep"
+    );
+  }
+
+  getPotentialSoldierMoves([x, y]) {
+    const c = this.getColor(x, y);
+    const shiftX = (c == 'w' ? -1 : 1);
+    const lastRank = (c == 'w' && x == 0 || c == 'b' && x == 9);
+    let steps = [];
+    if (!lastRank) steps.push([shiftX, 0]);
+    if (y > 0) steps.push([0, -1]);
+    if (y < 9) steps.push([0, 1]);
+    return super.getSlideNJumpMoves([x, y], steps, "oneStep");
+  }
+
+  isAttacked(sq, color) {
+    if (color == 'b') return super.isAttacked(sq, color);
+    // Empire: only pawn and king (+ queen if promotion) in common:
+    return (
+      super.isAttackedByPawn(sq, color) ||
+      this.isAttackedByTower(sq, color) ||
+      this.isAttackedByEagle(sq, color) ||
+      this.isAttackedByCardinal(sq, color) ||
+      this.isAttackedByDuke(sq, color) ||
+      this.isAttackedBySoldier(sq, color) ||
+      super.isAttackedByKing(sq, color) ||
+      super.isAttackedByQueen(sq, color)
+    );
+  }
+
+  isAttackedByTower(sq, color) {
+    return super.isAttackedBySlideNJump(sq, color, V.TOWER, V.steps[V.ROOK]);
+  }
+
+  isAttackedByEagle(sq, color) {
+    return super.isAttackedBySlideNJump(
+      sq, color, V.EAGLE, V.steps[V.KNIGHT], "oneStep");
+  }
+
+  isAttackedByCardinal(sq, color) {
+    return super.isAttackedBySlideNJump(
+      sq, color, V.CARDINAL, V.steps[V.BISHOP]);
+  }
+
+  isAttackedByDuke(sq, color) {
+    return (
+      super.isAttackedBySlideNJump(
+        sq, color, V.DUKE,
+        V.steps[V.ROOK].concat(V.steps[V.BISHOP]), "oneStep"
+      )
+    );
+  }
+
+  isAttackedBySoldier([x, y], color) {
+    const shiftX = (color == 'w' ? 1 : -1); //shift from king
+    return super.isAttackedBySlideNJump(
+      [x, y], color, V.SOLDIER, [[shiftX, 0], [0, 1], [0, -1]], "oneStep");
+  }
+
+  updateCastleFlags(move, piece) {
+    // Only black can castle:
+    const firstRank = 0;
+    if (piece == V.KING && move.appear[0].c == 'b')
+      this.castleFlags['b'] = [8, 8];
+    else if (
+      move.start.x == firstRank &&
+      this.castleFlags['b'].includes(move.start.y)
+    ) {
+      const flagIdx = (move.start.y == this.castleFlags['b'][0] ? 0 : 1);
+      this.castleFlags['b'][flagIdx] = 8;
+    }
+    else if (
+      move.end.x == firstRank &&
+      this.castleFlags['b'].includes(move.end.y)
+    ) {
+      const flagIdx = (move.end.y == this.castleFlags['b'][0] ? 0 : 1);
+      this.castleFlags['b'][flagIdx] = 8;
+    }
+  }
+
+  getCurrentScore() {
+    // Turn has changed:
+    const color = V.GetOppCol(this.turn);
+    const lastRank = (color == 'w' ? 0 : 7);
+    if (this.kingPos[color][0] == lastRank)
+      // The opposing edge is reached!
+      return color == "w" ? "1-0" : "0-1";
+    if (this.atLeastOneMove()) return "*";
+    // Game over
+    const oppCol = this.turn;
+    return (oppCol == "w" ? "0-1" : "1-0");
+  }
+
+  static get VALUES() {
+    return Object.assign(
+      {},
+      ChessRules.VALUES,
+      {
+        t: 7,
+        e: 7,
+        c: 4,
+        d: 4,
+        s: 2
+      }
+    );
+  }
+
+  static get SEARCH_DEPTH() {
+    return 2;
+  }
+
+};
index 34e7d19..f467e2d 100644 (file)
@@ -74,6 +74,10 @@ export class MinixiangqiRules extends XiangqiRules {
     return evaluation;
   }
 
+  static get SEARCH_DEPTH() {
+    return 3;
+  }
+
   // Also no randomization here
   static GenRandInitFen() {
     return "rcnkncr/p1ppp1p/7/7/7/P1PPP1P/RCNKNCR w 0";
index 308ae2f..1fd5c1d 100644 (file)
@@ -37,58 +37,11 @@ export class OrdaRules extends ChessRules {
       'k': 'k'
     };
 
-    let pieces = { w: new Array(8), b: new Array(8) };
-    let flags = "";
-    // Shuffle pieces on first (and last rank if randomness == 2)
-    for (let c of ["w", "b"]) {
-      if (c == 'b' && randomness == 1) {
-        pieces['b'] = pieces['w'].map(p => piecesMap[p]);
-        break;
-      }
-
-      // TODO: same code as in base_rules. Should extract and factorize?
-
-      let positions = ArrayFun.range(8);
-
-      let randIndex = 2 * randInt(4);
-      const bishop1Pos = positions[randIndex];
-      let randIndex_tmp = 2 * randInt(4) + 1;
-      const bishop2Pos = positions[randIndex_tmp];
-      positions.splice(Math.max(randIndex, randIndex_tmp), 1);
-      positions.splice(Math.min(randIndex, randIndex_tmp), 1);
-
-      randIndex = randInt(6);
-      const knight1Pos = positions[randIndex];
-      positions.splice(randIndex, 1);
-      randIndex = randInt(5);
-      const knight2Pos = positions[randIndex];
-      positions.splice(randIndex, 1);
-
-      randIndex = randInt(4);
-      const queenPos = positions[randIndex];
-      positions.splice(randIndex, 1);
-
-      const rook1Pos = positions[0];
-      const kingPos = positions[1];
-      const rook2Pos = positions[2];
-
-      pieces[c][rook1Pos] = "r";
-      pieces[c][knight1Pos] = "n";
-      pieces[c][bishop1Pos] = "b";
-      pieces[c][queenPos] = "q";
-      pieces[c][kingPos] = "k";
-      pieces[c][bishop2Pos] = "b";
-      pieces[c][knight2Pos] = "n";
-      pieces[c][rook2Pos] = "r";
-      if (c == 'b') pieces[c] = pieces[c].map(p => piecesMap[p]);
-      else flags = V.CoordToColumn(rook1Pos) + V.CoordToColumn(rook2Pos);
-    }
-    // Add turn + flags + enpassant
+    const baseFen = ChessRules.GenRandInitFen(randomness);
     return (
-      pieces["b"].join("") +
-      "/8/pppppppp/8/8/8/PPPPPPPP/" +
-      pieces["w"].join("").toUpperCase() +
-      " w 0 " + flags + " -"
+      baseFen.substr(0, 8).split('').map(p => piecesMap[p]).join('') +
+      // Skip 3 first rows + black castle flags
+      "/8/pppppppp" + baseFen.substr(19, 31) + " -"
     );
   }
 
@@ -186,24 +139,8 @@ export class OrdaRules extends ChessRules {
     return onlyMoves.concat(onlyTakes);
   }
 
-  getPotentialLancerMoves(sq) {
-    const onlyMoves = this.getSlideNJumpMoves(
-      sq,
-      V.steps[V.KNIGHT],
-      "oneStep",
-      { onlyMove: true }
-    );
-    const onlyTakes = this.getSlideNJumpMoves(
-      sq,
-      V.steps[V.ROOK],
-      null,
-      { onlyTake: true }
-    );
-    return onlyMoves.concat(onlyTakes);
-  }
-
   getPotentialKheshigMoves(sq) {
-    return this.getSlideNJumpMoves(
+    return super.getSlideNJumpMoves(
       sq,
       V.steps[V.KNIGHT].concat(V.steps[V.ROOK]).concat(V.steps[V.BISHOP]),
       "oneStep"
@@ -211,7 +148,7 @@ export class OrdaRules extends ChessRules {
   }
 
   getPotentialYurtMoves(sq) {
-    return this.getSlideNJumpMoves(
+    return super.getSlideNJumpMoves(
       sq,
       V.steps[V.BISHOP].concat([ [1, 0] ]),
       "oneStep"
@@ -221,7 +158,7 @@ export class OrdaRules extends ChessRules {
   getPotentialKingMoves([x, y]) {
     if (this.getColor(x, y) == 'w') return super.getPotentialKingMoves([x, y]);
     // Horde doesn't castle:
-    return this.getSlideNJumpMoves(
+    return super.getSlideNJumpMoves(
       [x, y],
       V.steps[V.ROOK].concat(V.steps[V.BISHOP]),
       "oneStep"
diff --git a/client/src/variants/Synochess.js b/client/src/variants/Synochess.js
new file mode 100644 (file)
index 0000000..b802110
--- /dev/null
@@ -0,0 +1,7 @@
+import { ChessRules } from "@/base_rules";
+
+export class SynochessRules extends ChessRules {
+
+  // TODO
+
+};
index 1b49ced..5deed64 100644 (file)
@@ -259,17 +259,8 @@ export class XiangqiRules extends ChessRules {
   isAttackedByPawn([x, y], color) {
     // The pawn necessarily crossed the river (attack on king)
     const shiftX = (color == 'w' ? 1 : -1); //shift from king
-    for (let s of [[shiftX, 0], [0, 1], [0, -1]]) {
-      const [i, j] = [x + s[0], y + s[1]];
-      if (
-        this.board[i][j] != V.EMPTY &&
-        this.getColor(i, j) == color &&
-        this.getPiece(i, j) == V.PAWN
-      ) {
-        return true;
-      }
-    }
-    return false;
+    return super.isAttackedBySlideNJump(
+      [x, y], color, V.PAWN, [[shiftX, 0], [0, 1], [0, -1]], "oneStep");
   }
 
   knightStepsFromBishopStep(step) {
@@ -369,6 +360,10 @@ export class XiangqiRules extends ChessRules {
     return evaluation;
   }
 
+  static get SEARCH_DEPTH() {
+    return 2;
+  }
+
   static GenRandInitFen() {
     // No randomization here (TODO?)
     return "rneakaenr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNEAKAENR w 0";