From 7e107b8f9dc9a4e7d9676fd2c48ba19f6cfc1661 Mon Sep 17 00:00:00 2001
From: Benjamin Auder <benjamin.auder@somewhere>
Date: Fri, 11 Dec 2020 01:04:40 +0100
Subject: [PATCH] Add Xiangqi

---
 client/package-lock.json                      |   6 +-
 client/public/images/pieces/Shogi/LICENSE     |   2 +-
 client/public/images/pieces/Xiangqi/SOURCE    |   2 +
 client/public/images/pieces/Xiangqi/ba.svg    | 253 +++++++++++++
 client/public/images/pieces/Xiangqi/bc.svg    | 266 +++++++++++++
 client/public/images/pieces/Xiangqi/be.svg    | 210 +++++++++++
 client/public/images/pieces/Xiangqi/bk.svg    | 283 ++++++++++++++
 client/public/images/pieces/Xiangqi/bn.svg    | 229 ++++++++++++
 client/public/images/pieces/Xiangqi/bp.svg    | 215 +++++++++++
 client/public/images/pieces/Xiangqi/br.svg    | 293 +++++++++++++++
 client/public/images/pieces/Xiangqi/wa.svg    | 257 +++++++++++++
 client/public/images/pieces/Xiangqi/wc.svg    | 322 ++++++++++++++++
 client/public/images/pieces/Xiangqi/we.svg    | 244 ++++++++++++
 client/public/images/pieces/Xiangqi/wk.svg    | 291 +++++++++++++++
 client/public/images/pieces/Xiangqi/wn.svg    | 285 ++++++++++++++
 client/public/images/pieces/Xiangqi/wp.svg    | 271 ++++++++++++++
 client/public/images/pieces/Xiangqi/wr.svg    | 353 ++++++++++++++++++
 client/public/variants/Xiangqi/Boards.png     |   1 +
 .../variants/Xiangqi/ElephantDiagram.png      |   1 +
 .../public/variants/Xiangqi/HorseDiagram.png  |   1 +
 client/src/translations/en.js                 |   3 +-
 client/src/translations/es.js                 |   3 +-
 client/src/translations/fr.js                 |   3 +-
 client/src/translations/rules/Xiangqi/en.pug  |  66 ++++
 client/src/translations/rules/Xiangqi/es.pug  |  68 ++++
 client/src/translations/rules/Xiangqi/fr.pug  |  68 ++++
 client/src/variants/Xiangqi.js                | 301 +++++++++++++++
 server/db/populate.sql                        |   3 +-
 28 files changed, 4292 insertions(+), 8 deletions(-)
 create mode 100644 client/public/images/pieces/Xiangqi/SOURCE
 create mode 100644 client/public/images/pieces/Xiangqi/ba.svg
 create mode 100644 client/public/images/pieces/Xiangqi/bc.svg
 create mode 100644 client/public/images/pieces/Xiangqi/be.svg
 create mode 100644 client/public/images/pieces/Xiangqi/bk.svg
 create mode 100644 client/public/images/pieces/Xiangqi/bn.svg
 create mode 100644 client/public/images/pieces/Xiangqi/bp.svg
 create mode 100644 client/public/images/pieces/Xiangqi/br.svg
 create mode 100644 client/public/images/pieces/Xiangqi/wa.svg
 create mode 100644 client/public/images/pieces/Xiangqi/wc.svg
 create mode 100644 client/public/images/pieces/Xiangqi/we.svg
 create mode 100644 client/public/images/pieces/Xiangqi/wk.svg
 create mode 100644 client/public/images/pieces/Xiangqi/wn.svg
 create mode 100644 client/public/images/pieces/Xiangqi/wp.svg
 create mode 100644 client/public/images/pieces/Xiangqi/wr.svg
 create mode 100644 client/public/variants/Xiangqi/Boards.png
 create mode 100644 client/public/variants/Xiangqi/ElephantDiagram.png
 create mode 100644 client/public/variants/Xiangqi/HorseDiagram.png
 create mode 100644 client/src/translations/rules/Xiangqi/en.pug
 create mode 100644 client/src/translations/rules/Xiangqi/es.pug
 create mode 100644 client/src/translations/rules/Xiangqi/fr.pug
 create mode 100644 client/src/variants/Xiangqi.js

diff --git a/client/package-lock.json b/client/package-lock.json
index 22ed9bc4..355a62e0 100644
--- a/client/package-lock.json
+++ b/client/package-lock.json
@@ -897,9 +897,9 @@
           }
         },
         "vue-loader-v16": {
-          "version": "npm:vue-loader@16.0.0-rc.1",
-          "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.0.0-rc.1.tgz",
-          "integrity": "sha512-yR+BS90EOXTNieasf8ce9J3TFCpm2DGqoqdbtiwQ33hon3FyIznLX7sKavAq1VmfBnOeV6It0Htg4aniv8ph1g==",
+          "version": "npm:vue-loader@16.1.1",
+          "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.1.1.tgz",
+          "integrity": "sha512-wz/+HFg/3SBayHWAlZXARcnDTl3VOChrfW9YnxvAweiuyKX/7IGx1ad/4yJHmwhgWlOVYMAbTiI7GV8G33PfGQ==",
           "dev": true,
           "optional": true,
           "requires": {
diff --git a/client/public/images/pieces/Shogi/LICENSE b/client/public/images/pieces/Shogi/LICENSE
index 997500b0..3bdba9d5 100644
--- a/client/public/images/pieces/Shogi/LICENSE
+++ b/client/public/images/pieces/Shogi/LICENSE
@@ -1,2 +1,2 @@
-Permission of author (Daniel Lee) --> TODO: ask him.
+Permission of author (Daniel Lee).
 Pieces also in use on pychess-variants.
diff --git a/client/public/images/pieces/Xiangqi/SOURCE b/client/public/images/pieces/Xiangqi/SOURCE
new file mode 100644
index 00000000..856214a3
--- /dev/null
+++ b/client/public/images/pieces/Xiangqi/SOURCE
@@ -0,0 +1,2 @@
+https://github.com/gbtami/pychess-variants/tree/master/static/images/pieces/xiangqi
+(With author's permission).
diff --git a/client/public/images/pieces/Xiangqi/ba.svg b/client/public/images/pieces/Xiangqi/ba.svg
new file mode 100644
index 00000000..55f99256
--- /dev/null
+++ b/client/public/images/pieces/Xiangqi/ba.svg
@@ -0,0 +1,253 @@
+<?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="92"
+   height="92"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
+   sodipodi:docname="black_advisor.svg">
+  <metadata
+     id="metadata12">
+    <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="defs10">
+    <filter
+       height="1.5"
+       width="1.5"
+       y="0"
+       x="0"
+       id="f1"
+       color-interpolation-filters="sRGB">
+      <feOffset
+         id="feOffset3123"
+         dy="1"
+         dx="1"
+         in="SourceAlpha"
+         result="offOut" />
+      <feGaussianBlur
+         id="feGaussianBlur3125"
+         stdDeviation="1"
+         in="offOut"
+         result="blurOut" />
+      <!--
+      <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
+-->
+    </filter>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad2">
+      <stop
+         id="stop3118"
+         style="stop-color:rgb(32,32,32);stop-opacity:0.3"
+         offset="30%" />
+      <stop
+         id="stop3120"
+         style="stop-color:rgb(255,255,255);stop-opacity:0.3"
+         offset="100%" />
+    </linearGradient>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad3">
+      <stop
+         id="stop3113"
+         style="stop-color:rgb(255,255,255);stop-opacity:0.6"
+         offset="10%" />
+      <stop
+         id="stop3115"
+         style="stop-color:rgb(50,30,20);stop-opacity:0.3"
+         offset="60%" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#grad3"
+       id="linearGradient3169"
+       x1="10.900002"
+       y1="4.9000015"
+       x2="10.900002"
+       y2="83.099998"
+       gradientUnits="userSpaceOnUse" />
+  </defs>
+  <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="1001"
+     id="namedview8"
+     showgrid="false"
+     inkscape:zoom="2.6222222"
+     inkscape:cx="16.344934"
+     inkscape:cy="51.395055"
+     inkscape:window-x="1913"
+     inkscape:window-y="0"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <g
+     id="use4"
+     transform="translate(-4,2)">
+    <circle
+       d="M 89,49 C 89,70.539105 71.539105,88 50,88 28.460895,88 11,70.539105 11,49 11,27.460895 28.460895,10 50,10 71.539105,10 89,27.460895 89,49 z"
+       style="opacity:0.3;fill:#000000;filter:url(#f1)"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="49"
+       sodipodi:cx="50"
+       cx="50"
+       cy="49"
+       r="39"
+       id="circle3159" />
+    <circle
+       d="M 89,44 C 89,65.539105 71.539105,83 50,83 28.460895,83 11,65.539105 11,44 11,22.460895 28.460895,5 50,5 71.539105,5 89,22.460895 89,44 z"
+       style="fill:#302010"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="44"
+       sodipodi:cx="50"
+       cx="50"
+       cy="44"
+       r="39"
+       id="circle3161" />
+    <circle
+       d="M 89.099998,44 C 89.099998,65.594333 71.594333,83.099998 50,83.099998 28.405667,83.099998 10.900002,65.594333 10.900002,44 10.900002,22.405667 28.405667,4.9000015 50,4.9000015 71.594333,4.9000015 89.099998,22.405667 89.099998,44 z"
+       style="fill:url(#linearGradient3169)"
+       sodipodi:ry="39.099998"
+       sodipodi:rx="39.099998"
+       sodipodi:cy="44"
+       sodipodi:cx="50"
+       cx="50"
+       cy="44"
+       r="39.099998"
+       id="circle3163" />
+    <circle
+       d="M 89,44 C 89,65.539105 71.539105,83 50,83 28.460895,83 11,65.539105 11,44 11,22.460895 28.460895,5 50,5 71.539105,5 89,22.460895 89,44 z"
+       style="fill:none;stroke:#442211;stroke-width:1"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="44"
+       sodipodi:cx="50"
+       cx="50"
+       cy="44"
+       r="39"
+       id="circle3165" />
+    <circle
+       d="M 84.049999,44 C 84.049999,62.805295 68.805295,78.049999 50,78.049999 31.194705,78.049999 15.950001,62.805295 15.950001,44 15.950001,25.194705 31.194705,9.9500008 50,9.9500008 68.805295,9.9500008 84.049999,25.194705 84.049999,44 z"
+       style="fill:#483420"
+       sodipodi:ry="34.049999"
+       sodipodi:rx="34.049999"
+       sodipodi:cy="44"
+       sodipodi:cx="50"
+       cx="50"
+       cy="44"
+       r="34.049999"
+       id="circle3167" />
+  </g>
+  <g
+     style="display:inline"
+     id="g16676"
+     transform="matrix(1.0851597,0,0,1.0851597,-4.2380512,0.28870138)">
+    <path
+       sodipodi:nodetypes="cccccccccccc"
+       inkscape:connector-curvature="0"
+       id="path7039"
+       d="M 46.314318,54.9317 C 42.356998,54.834892 38.28061,55.053577 33.042662,54.572582 29.08398,51.239218 24.163206,34.895196 26.264735,27.515155 l 2.242968,5.073731 c 0.904414,-1.286503 4.443742,-3.043957 5.826002,-0.651772 3.063224,-2.067575 3.965642,-1.47325 6.167862,-0.446321 2.326036,-1.963969 3.759013,-1.686422 5.584723,-0.208555 2.435106,-1.540839 2.91277,-2.315498 5.969919,-0.234576 1.393794,-1.805529 5.348995,-1.238852 6.514895,0.63516 0.72922,-1.449764 3.882256,-1.601314 5.129111,0.705381 l 2.779908,-5.008547 c 1.69577,7.471841 -3.140965,24.150404 -6.983188,27.080935"
+       style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.05248582;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <path
+       sodipodi:nodetypes="ccccccc"
+       inkscape:connector-curvature="0"
+       id="path7043"
+       d="m 33.042662,54.221383 c -0.04538,3.440549 0.535511,6.221829 1.46304,9.662379 4.266942,1.897027 7.563074,2.10954 11.478298,2.199874 3.915225,-0.07254 8.300478,-0.65405 11.865019,-2.300217 0.92753,-3.44055 1.712825,-6.121487 1.667438,-9.562036 l -13.213668,0.452419 z"
+       style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.56941742;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <path
+       sodipodi:nodetypes="cc"
+       inkscape:connector-curvature="0"
+       id="path7051"
+       d="m 34.248108,31.144819 c 0.161876,7.627342 2.186141,16.283659 4.225636,23.508654"
+       style="fill:none;stroke:#483420;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <path
+       sodipodi:nodetypes="cc"
+       inkscape:connector-curvature="0"
+       id="path7053"
+       d="M 58.487159,30.379647 C 57.905091,37.947181 56.903213,47.41971 54.483762,54.462278"
+       style="fill:none;stroke:#483420;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <path
+       sodipodi:nodetypes="cc"
+       inkscape:connector-curvature="0"
+       id="path7088"
+       d="M 52.145463,29.521685 C 51.563396,37.089219 51.450918,46.10004 49.382667,53.242951"
+       style="fill:none;stroke:#483420;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <path
+       style="fill:none;stroke:#483420;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="m 40.524586,30.501832 c 0.161876,7.627343 0.823654,15.521191 2.863149,22.746186"
+       id="path7090"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       sodipodi:nodetypes="cc"
+       inkscape:connector-curvature="0"
+       id="path7092"
+       d="M 46.225032,53.395931 46.124215,30.697163"
+       style="fill:none;stroke:#483420;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <path
+       style="fill:none;stroke:#483420;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 32.779521,55.723468 C 43.040852,53.07175 52.284118,54.00966 60.026058,55.823812"
+       id="path7094"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       sodipodi:nodetypes="cc"
+       inkscape:connector-curvature="0"
+       id="path7096"
+       d="m 33.649764,63.258142 c 9.702633,-2.248555 17.829672,-1.559126 24.853754,-0.200528"
+       style="fill:none;stroke:#483420;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <circle
+       r="1.4591321"
+       cy="58.035988"
+       cx="46.108307"
+       id="path7098"
+       style="opacity:1;fill:#483420;fill-opacity:1;stroke:#483420;stroke-width:0.56941742;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" />
+    <path
+       sodipodi:nodetypes="cc"
+       inkscape:connector-curvature="0"
+       id="path7051-0"
+       d="m 29.471433,30.206797 c -1.317204,7.565714 2.169353,17.040115 4.945284,24.295795"
+       style="display:inline;fill:none;stroke:#483420;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <path
+       style="display:inline;fill:none;stroke:#483420;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="m 63.310845,30.432888 c 1.317204,7.565714 -2.544353,16.790115 -5.320284,24.045795"
+       id="path7645"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+  </g>
+</svg>
diff --git a/client/public/images/pieces/Xiangqi/bc.svg b/client/public/images/pieces/Xiangqi/bc.svg
new file mode 100644
index 00000000..a5e02fac
--- /dev/null
+++ b/client/public/images/pieces/Xiangqi/bc.svg
@@ -0,0 +1,266 @@
+<?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="92"
+   height="92"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
+   sodipodi:docname="black_cannon.svg">
+  <metadata
+     id="metadata12">
+    <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>
+  <defs
+     id="defs10">
+    <filter
+       height="1.5"
+       width="1.5"
+       y="0"
+       x="0"
+       id="f1"
+       color-interpolation-filters="sRGB">
+      <feOffset
+         id="feOffset3123"
+         dy="1"
+         dx="1"
+         in="SourceAlpha"
+         result="offOut" />
+      <feGaussianBlur
+         id="feGaussianBlur3125"
+         stdDeviation="1"
+         in="offOut"
+         result="blurOut" />
+      <!--
+      <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
+-->
+    </filter>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad2">
+      <stop
+         id="stop3118"
+         style="stop-color:rgb(32,32,32);stop-opacity:0.3"
+         offset="30%" />
+      <stop
+         id="stop3120"
+         style="stop-color:rgb(255,255,255);stop-opacity:0.3"
+         offset="100%" />
+    </linearGradient>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad3">
+      <stop
+         id="stop3113"
+         style="stop-color:rgb(255,255,255);stop-opacity:0.6"
+         offset="10%" />
+      <stop
+         id="stop3115"
+         style="stop-color:rgb(50,30,20);stop-opacity:0.3"
+         offset="60%" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#grad3"
+       id="linearGradient3169"
+       x1="10.900002"
+       y1="4.9000015"
+       x2="10.900002"
+       y2="83.099998"
+       gradientUnits="userSpaceOnUse" />
+  </defs>
+  <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="namedview8"
+     showgrid="false"
+     inkscape:zoom="5.2444445"
+     inkscape:cx="52.975914"
+     inkscape:cy="61.119606"
+     inkscape:window-x="1913"
+     inkscape:window-y="0"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <g
+     id="use4"
+     transform="translate(-4,2)">
+    <circle
+       style="opacity:0.3;fill:#000000;filter:url(#f1)"
+       cx="50"
+       cy="49"
+       r="39"
+       id="circle3159"
+       d="M 89,49 C 89,70.539105 71.539105,88 50,88 28.460895,88 11,70.539105 11,49 11,27.460895 28.460895,10 50,10 71.539105,10 89,27.460895 89,49 z"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="49"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:#302010"
+       cx="50"
+       cy="44"
+       r="39"
+       id="circle3161"
+       d="M 89,44 C 89,65.539105 71.539105,83 50,83 28.460895,83 11,65.539105 11,44 11,22.460895 28.460895,5 50,5 71.539105,5 89,22.460895 89,44 z"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:url(#linearGradient3169)"
+       cx="50"
+       cy="44"
+       r="39.099998"
+       id="circle3163"
+       d="M 89.099998,44 C 89.099998,65.594333 71.594333,83.099998 50,83.099998 28.405667,83.099998 10.900002,65.594333 10.900002,44 10.900002,22.405667 28.405667,4.9000015 50,4.9000015 71.594333,4.9000015 89.099998,22.405667 89.099998,44 z"
+       sodipodi:ry="39.099998"
+       sodipodi:rx="39.099998"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:none;stroke:#442211;stroke-width:1"
+       cx="50"
+       cy="44"
+       r="39"
+       id="circle3165"
+       d="M 89,44 C 89,65.539105 71.539105,83 50,83 28.460895,83 11,65.539105 11,44 11,22.460895 28.460895,5 50,5 71.539105,5 89,22.460895 89,44 z"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:#483420"
+       cx="50"
+       cy="44"
+       r="34.049999"
+       id="circle3167"
+       d="M 84.049999,44 C 84.049999,62.805295 68.805295,78.049999 50,78.049999 31.194705,78.049999 15.950001,62.805295 15.950001,44 15.950001,25.194705 31.194705,9.9500008 50,9.9500008 68.805295,9.9500008 84.049999,25.194705 84.049999,44 z"
+       sodipodi:ry="34.049999"
+       sodipodi:rx="34.049999"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+  </g>
+  <g
+     transform="translate(-1.3482964,1.6647936)"
+     style="display:inline"
+     id="g18015">
+    <g
+       transform="translate(1.36549,2.250535)"
+       style="display:inline"
+       id="g19066">
+      <g
+         transform="matrix(-1.0339627,0,0,1.0339627,888.34584,-245.90707)"
+         id="g5204">
+        <g
+           id="g4916"
+           transform="matrix(0.42429161,0,0,0.35530383,319.4593,167.8082)">
+          <g
+             transform="matrix(0.91849155,-0.04088349,0.02866942,0.91849155,95.269582,54.832886)"
+             id="g873">
+            <path
+               sodipodi:nodetypes="ccccccccc"
+               inkscape:connector-curvature="0"
+               style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2.65330386;stroke-miterlimit:10"
+               d="m 1213.6335,288.03625 -92.5944,36.18456 c 0,0 -8.0242,8.93392 -2.8931,21.42532 l 0.063,0.30499 0.063,0.30498 c 4.9395,12.5585 16.4998,12.34665 16.4998,12.34665 37.098,-28.13428 66.1489,-38.4485 87.024,-50.31774 -0.192,-4.06467 -1.8458,-7.47907 -2.8249,-11.1936 -1.3824,-3.19489 -2.9322,-6.31529 -5.3374,-9.05516 z"
+               id="path47" />
+            <ellipse
+               style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:3.00610209;stroke-miterlimit:10"
+               id="circle53"
+               cy="677.90155"
+               cx="1017.132"
+               stroke-miterlimit="10"
+               rx="3.753881"
+               ry="3.6617434"
+               transform="matrix(0.95110508,-0.30886749,0.22204229,0.97503704,0,0)" />
+          </g>
+          <path
+             sodipodi:nodetypes="cccccc"
+             inkscape:connector-curvature="0"
+             id="rect875"
+             d="m 1188.053,314.76933 -0.1997,22.82133 -37.6537,4.53206 c -16.1431,26.71247 -25.0217,28.93186 -41.2475,19.47896 18.33,-6.79184 27.9258,-27.84095 38.5459,-46.51534 z"
+             style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#483420;stroke-width:1.83159566;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" />
+          <ellipse
+             cx="-1207.3654"
+             cy="214.17735"
+             rx="27.158773"
+             ry="32.340363"
+             transform="matrix(-0.99442868,-0.10541155,-0.07412913,0.99724865,0,0)"
+             id="path869"
+             style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#483420;stroke-width:1.99324226;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" />
+          <ellipse
+             ry="21.17234"
+             rx="17.729818"
+             cy="340.7244"
+             cx="1184.762"
+             id="path890"
+             style="opacity:1;fill:#483420;fill-opacity:1;stroke:#483420;stroke-width:2.05792236;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" />
+          <rect
+             transform="matrix(-0.62961158,0.77691007,0.65434208,0.75619868,0,0)"
+             y="1132.5303"
+             x="-684.76074"
+             height="41.437584"
+             width="2.9200215"
+             id="rect892-1"
+             style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2.22107673;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" />
+          <rect
+             style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2.2210741;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
+             id="rect909"
+             width="2.9027057"
+             height="41.684681"
+             x="-1155.4326"
+             y="-703.56848"
+             transform="matrix(-0.65516628,-0.75548471,-0.62877406,0.77758805,0,0)" />
+          <rect
+             style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2.2037704;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
+             id="rect911"
+             width="3.156975"
+             height="37.732437"
+             x="343.79016"
+             y="1165.2843"
+             transform="matrix(0.0023305,0.99999728,0.99999448,-0.00332335,0,0)" />
+          <rect
+             transform="matrix(-0.99998924,0.00463819,0.00325253,0.99999471,0,0)"
+             y="323.77573"
+             x="-1184.9684"
+             height="45.058598"
+             width="2.6436777"
+             id="rect913"
+             style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2.20377064;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" />
+        </g>
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/client/public/images/pieces/Xiangqi/be.svg b/client/public/images/pieces/Xiangqi/be.svg
new file mode 100644
index 00000000..979069fd
--- /dev/null
+++ b/client/public/images/pieces/Xiangqi/be.svg
@@ -0,0 +1,210 @@
+<?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="92"
+   height="92"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
+   sodipodi:docname="black_elephant.svg">
+  <metadata
+     id="metadata12">
+    <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="defs10">
+    <filter
+       height="1.5"
+       width="1.5"
+       y="0"
+       x="0"
+       id="f1"
+       color-interpolation-filters="sRGB">
+      <feOffset
+         id="feOffset3123"
+         dy="1"
+         dx="1"
+         in="SourceAlpha"
+         result="offOut" />
+      <feGaussianBlur
+         id="feGaussianBlur3125"
+         stdDeviation="1"
+         in="offOut"
+         result="blurOut" />
+      <!--
+      <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
+-->
+    </filter>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad2">
+      <stop
+         id="stop3118"
+         style="stop-color:rgb(32,32,32);stop-opacity:0.3"
+         offset="30%" />
+      <stop
+         id="stop3120"
+         style="stop-color:rgb(255,255,255);stop-opacity:0.3"
+         offset="100%" />
+    </linearGradient>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad3">
+      <stop
+         id="stop3113"
+         style="stop-color:rgb(255,255,255);stop-opacity:0.6"
+         offset="10%" />
+      <stop
+         id="stop3115"
+         style="stop-color:rgb(50,30,20);stop-opacity:0.3"
+         offset="60%" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#grad3"
+       id="linearGradient3169"
+       x1="10.900002"
+       y1="4.9000015"
+       x2="10.900002"
+       y2="83.099998"
+       gradientUnits="userSpaceOnUse" />
+  </defs>
+  <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="1001"
+     id="namedview8"
+     showgrid="false"
+     inkscape:zoom="5.2444446"
+     inkscape:cx="47.544315"
+     inkscape:cy="25.387654"
+     inkscape:window-x="1913"
+     inkscape:window-y="0"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="g5374"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <g
+     id="use4"
+     transform="translate(-4,2)">
+    <circle
+       d="M 89,49 C 89,70.539105 71.539105,88 50,88 28.460895,88 11,70.539105 11,49 11,27.460895 28.460895,10 50,10 71.539105,10 89,27.460895 89,49 z"
+       style="opacity:0.3;fill:#000000;filter:url(#f1)"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="49"
+       sodipodi:cx="50"
+       cx="50"
+       cy="49"
+       r="39"
+       id="circle3159" />
+    <circle
+       d="M 89,44 C 89,65.539105 71.539105,83 50,83 28.460895,83 11,65.539105 11,44 11,22.460895 28.460895,5 50,5 71.539105,5 89,22.460895 89,44 z"
+       style="fill:#302010"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="44"
+       sodipodi:cx="50"
+       cx="50"
+       cy="44"
+       r="39"
+       id="circle3161" />
+    <circle
+       d="M 89.099998,44 C 89.099998,65.594333 71.594333,83.099998 50,83.099998 28.405667,83.099998 10.900002,65.594333 10.900002,44 10.900002,22.405667 28.405667,4.9000015 50,4.9000015 71.594333,4.9000015 89.099998,22.405667 89.099998,44 z"
+       style="fill:url(#linearGradient3169)"
+       sodipodi:ry="39.099998"
+       sodipodi:rx="39.099998"
+       sodipodi:cy="44"
+       sodipodi:cx="50"
+       cx="50"
+       cy="44"
+       r="39.099998"
+       id="circle3163" />
+    <circle
+       d="M 89,44 C 89,65.539105 71.539105,83 50,83 28.460895,83 11,65.539105 11,44 11,22.460895 28.460895,5 50,5 71.539105,5 89,22.460895 89,44 z"
+       style="fill:none;stroke:#442211;stroke-width:1"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="44"
+       sodipodi:cx="50"
+       cx="50"
+       cy="44"
+       r="39"
+       id="circle3165" />
+    <circle
+       d="M 84.049999,44 C 84.049999,62.805295 68.805295,78.049999 50,78.049999 31.194705,78.049999 15.950001,62.805295 15.950001,44 15.950001,25.194705 31.194705,9.9500008 50,9.9500008 68.805295,9.9500008 84.049999,25.194705 84.049999,44 z"
+       style="fill:#483420"
+       sodipodi:ry="34.049999"
+       sodipodi:rx="34.049999"
+       sodipodi:cy="44"
+       sodipodi:cx="50"
+       cx="50"
+       cy="44"
+       r="34.049999"
+       id="circle3167" />
+  </g>
+  <g
+     style="display:inline"
+     id="g5374"
+     transform="matrix(1.170336,0,0,1.170336,-53.510217,8.0350211)">
+    <g
+       transform="translate(-35.93211,25.375953)"
+       style="opacity:1"
+       id="g5357">
+      <path
+         style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m 125.66609,-2.121176 -3.2,5 -0.6,2.1 c -0.0945,1.5296586 0.15617,2.8292194 0.6,4 l -0.2,2.099999 c -1.09796,3.097738 -2.35981,6.067197 -2.60001,9.5 0.12511,0.773672 0.40427,1.44388 1.3,1.7 11.23011,-0.424319 16.82956,-5.233235 20.30001,-11.7 l 0.2,-2.099999 c -2.10707,-8.89280401 -8.15113,-13.4502442 -16.2,-15.8 -4.40015,-0.5317426 -7.59668,1.3815851 -10.20001,4.5 -2.59354,2.64077835 -4.39616,5.9439949 -5.3,10 -0.89646,1.6487885 -1.64452,1.9405129 -2.4,2.3 -2.28978,-0.6407124 -3.03862,-1.6262894 -2.5,-2.9 0.35259,-1.8089896 3.48816,-3.3504905 5.5,-5 1.59764,-2.6483718 2.34637,-5.1951958 -0.6,-7.3 -8.75831,-2.0518262 -7.05798,4.7061225 -5.2,6.20000004 1.23982,-0.5457366 2.00197,-1.22280981 2.4,-2.00000004 -0.25951,-0.4357328 -0.98217,-0.8162564 0,-1.4 0.5387,0.045976 0.81918,0.2856122 1,0.6 0,1 0.50403,1.1455069 -3.6,4 -2.41796,1.1605474 -2.59331,2.9892138 -3.5,4.6 -1.668162,8.737445 1.94976,11.358136 6.5,12.899999 0.86488,-0.721198 1.12021,-1.741094 1.5,-2.7 1.29573,0.281592 2.51468,0.385517 4.3,1.8 0.43333,-0.4 0.86667,-0.8 1.3,-1.2 l 1.1,0.5 -0.9,0.5 c -0.61971,0.861505 -1.43108,1.608021 -2.5,2.2 l 2.4,0.3 c 1.087,-0.403589 1.93334,-1.017048 2.7,-1.7 l 1.3,-0.4 c 1.21385,-2.971538 2.39138,-5.952154 2.9,-9.099999 -0.0806,-0.9844358 -0.10227,-1.7702685 -0.7,-4.5 l 0.7,-2.3 z"
+         id="path5349"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccc" />
+      <path
+         style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m 109.56608,17.578823 c -1.32838,4.066443 -4.04985,6.321863 -6.6,8.8 -0.20576,0.304421 0.14574,0.397532 1,0.3 3.90473,-1.863513 6.85963,-4.360243 8.1,-8 -0.78642,-0.41302 -1.31194,-1.08384 -2.5,-1.1 z"
+         id="path5353"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="ccccc" />
+    </g>
+    <path
+       sodipodi:nodetypes="ccccccc"
+       inkscape:connector-curvature="0"
+       id="path5363"
+       d="m 79.63397,30.638747 c -0.68176,-0.252758 -0.87046,0.286775 -1.2,0.6 0.0622,0.385834 -0.13002,0.560848 0.6,1.5 0.63484,0.221654 1.42189,0.04926 2.2,-0.1 0.84331,0.145013 1.30379,0.481437 1.8,0.8 -0.0628,-0.684154 -0.45126,-1.226866 -1,-1.7 z"
+       style="fill:#483420;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       sodipodi:nodetypes="ccccc"
+       inkscape:connector-curvature="0"
+       id="path5365"
+       d="m 80.03397,29.438747 c -0.82212,0.100251 -1.34347,0.435691 -1.7,0.9 0.31963,-0.0098 0.65496,-0.02748 1.1,-0.1 0.812,-0.717231 1.30759,-0.282359 1.9,-0.2 -0.34309,-0.230079 -0.76634,-0.433443 -1.3,-0.6 z"
+       style="fill:#483420;fill-opacity:1;stroke:none;stroke-width:1.00157475;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+  </g>
+</svg>
diff --git a/client/public/images/pieces/Xiangqi/bk.svg b/client/public/images/pieces/Xiangqi/bk.svg
new file mode 100644
index 00000000..2fe58f9c
--- /dev/null
+++ b/client/public/images/pieces/Xiangqi/bk.svg
@@ -0,0 +1,283 @@
+<?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="92"
+   height="92"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
+   sodipodi:docname="black_king.svg">
+  <metadata
+     id="metadata12">
+    <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="defs10">
+    <filter
+       height="1.5"
+       width="1.5"
+       y="0"
+       x="0"
+       id="f1"
+       color-interpolation-filters="sRGB">
+      <feOffset
+         id="feOffset3123"
+         dy="1"
+         dx="1"
+         in="SourceAlpha"
+         result="offOut" />
+      <feGaussianBlur
+         id="feGaussianBlur3125"
+         stdDeviation="1"
+         in="offOut"
+         result="blurOut" />
+      <!--
+      <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
+-->
+    </filter>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad2">
+      <stop
+         id="stop3118"
+         style="stop-color:rgb(32,32,32);stop-opacity:0.3"
+         offset="30%" />
+      <stop
+         id="stop3120"
+         style="stop-color:rgb(255,255,255);stop-opacity:0.3"
+         offset="100%" />
+    </linearGradient>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad3">
+      <stop
+         id="stop3113"
+         style="stop-color:rgb(255,255,255);stop-opacity:0.6"
+         offset="10%" />
+      <stop
+         id="stop3115"
+         style="stop-color:rgb(50,30,20);stop-opacity:0.3"
+         offset="60%" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#grad3"
+       id="linearGradient3169"
+       x1="10.900002"
+       y1="4.9000015"
+       x2="10.900002"
+       y2="83.099998"
+       gradientUnits="userSpaceOnUse" />
+  </defs>
+  <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="1001"
+     id="namedview8"
+     showgrid="false"
+     inkscape:zoom="1.8541911"
+     inkscape:cx="-63.719933"
+     inkscape:cy="48.867604"
+     inkscape:window-x="1913"
+     inkscape:window-y="0"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <g
+     id="use4"
+     transform="translate(-4,2)">
+    <circle
+       d="M 89,49 C 89,70.539105 71.539105,88 50,88 28.460895,88 11,70.539105 11,49 11,27.460895 28.460895,10 50,10 71.539105,10 89,27.460895 89,49 z"
+       style="opacity:0.3;fill:#000000;filter:url(#f1)"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="49"
+       sodipodi:cx="50"
+       cx="50"
+       cy="49"
+       r="39"
+       id="circle3159" />
+    <circle
+       d="M 89,44 C 89,65.539105 71.539105,83 50,83 28.460895,83 11,65.539105 11,44 11,22.460895 28.460895,5 50,5 71.539105,5 89,22.460895 89,44 z"
+       style="fill:#302010"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="44"
+       sodipodi:cx="50"
+       cx="50"
+       cy="44"
+       r="39"
+       id="circle3161" />
+    <circle
+       d="M 89.099998,44 C 89.099998,65.594333 71.594333,83.099998 50,83.099998 28.405667,83.099998 10.900002,65.594333 10.900002,44 10.900002,22.405667 28.405667,4.9000015 50,4.9000015 71.594333,4.9000015 89.099998,22.405667 89.099998,44 z"
+       style="fill:url(#linearGradient3169)"
+       sodipodi:ry="39.099998"
+       sodipodi:rx="39.099998"
+       sodipodi:cy="44"
+       sodipodi:cx="50"
+       cx="50"
+       cy="44"
+       r="39.099998"
+       id="circle3163" />
+    <circle
+       d="M 89,44 C 89,65.539105 71.539105,83 50,83 28.460895,83 11,65.539105 11,44 11,22.460895 28.460895,5 50,5 71.539105,5 89,22.460895 89,44 z"
+       style="fill:none;stroke:#442211;stroke-width:1"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="44"
+       sodipodi:cx="50"
+       cx="50"
+       cy="44"
+       r="39"
+       id="circle3165" />
+    <circle
+       d="M 84.049999,44 C 84.049999,62.805295 68.805295,78.049999 50,78.049999 31.194705,78.049999 15.950001,62.805295 15.950001,44 15.950001,25.194705 31.194705,9.9500008 50,9.9500008 68.805295,9.9500008 84.049999,25.194705 84.049999,44 z"
+       style="fill:#483420"
+       sodipodi:ry="34.049999"
+       sodipodi:rx="34.049999"
+       sodipodi:cy="44"
+       sodipodi:cx="50"
+       cx="50"
+       cy="44"
+       r="34.049999"
+       id="circle3167" />
+  </g>
+  <g
+     id="g14133"
+     transform="matrix(1.0139593,0,0,1.0139593,-6.1015451,-5.4271428)">
+    <path
+       style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.15365481;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="m 51.359744,64.137284 c -4.337713,-0.10611 -8.805939,0.1336 -14.547379,-0.39363 -3.058483,-4.3653 -7.669835,-20.160519 -6.59342,-27.568229 8.133658,-4.95419 36.964481,-6.25835 41.572966,0.16499 1.076415,7.4077 -2.923901,22.915189 -5.982386,27.280479"
+       id="path7039-4"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.624152;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="m 36.812365,63.358694 c -0.04975,3.77127 0.586986,6.81989 1.603673,10.59116 4.677097,2.07938 8.290066,2.31232 12.581636,2.41134 4.291572,-0.0795 9.098353,-0.71692 13.005531,-2.52132 1.016687,-3.77127 1.877469,-6.70991 1.827718,-10.48118 l -14.483816,0.49591 z"
+       id="path7043-9"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccccc" />
+    <path
+       style="display:inline;fill:none;stroke:#483420;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="m 36.152435,64.820494 c 10.116218,-2.68441 21.010358,-2.6855 30.279356,0.055"
+       id="path7068-2"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="display:inline;fill:none;stroke:#483420;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 55.628615,42.156505 53.3517,53.941154"
+       id="path7088-8"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       sodipodi:nodetypes="cc"
+       inkscape:connector-curvature="0"
+       id="path7090-7"
+       d="m 47.005327,42.754975 1.715994,10.872389"
+       style="display:inline;fill:none;stroke:#483420;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <path
+       style="display:inline;fill:none;stroke:#483420;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="m 37.477824,73.419214 c 10.635287,-2.46469 19.543529,-1.70899 27.242793,-0.2198"
+       id="path7096-3"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <ellipse
+       ry="2.5287778"
+       rx="2.4187896"
+       style="display:inline;opacity:1;fill:#483420;fill-opacity:1;stroke:#483420;stroke-width:0.96514052;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
+       id="path7098-0"
+       cx="51.023945"
+       cy="67.205116" />
+    <path
+       style="display:inline;fill:none;stroke:#483420;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="m 29.883219,35.881575 c 3.031645,8.87729 6.222505,6.09111 6.910112,7.23293 0.798314,2.55026 4.120375,19.604439 4.120375,19.604439 l 0.164982,0.82491"
+       id="path8714-5"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccc" />
+    <path
+       sodipodi:nodetypes="cccc"
+       inkscape:connector-curvature="0"
+       id="path8716-9"
+       d="m 72.201896,35.570485 c -3.031645,8.87729 -5.522544,6.01334 -6.210152,7.15515 -0.798314,2.55026 -4.820335,19.682209 -4.820335,19.682209 l -0.164982,0.82491"
+       style="display:inline;fill:none;stroke:#483420;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <path
+       style="display:inline;fill:none;stroke:#483420;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="m 36.808619,42.970585 c 5.355804,-5.07573 7.816328,-1.15585 10.503881,-0.32996 2.151414,-1.93708 4.337824,-4.08726 8.4727,-0.24195 2.914409,-2.83934 7.470518,-2.8371 10.2803,0.24195"
+       id="path8718-6"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccc" />
+    <path
+       style="display:inline;fill:none;stroke:#483420;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="m 42.596868,62.901714 c 0.329506,-2.36495 -0.59859,-6.18345 4.970044,-7.0772 1.838323,-4.4565 4.858416,-4.7748 7.115771,0 2.925394,1.34592 4.570542,0.65162 4.807702,7.04488"
+       id="path8722-9"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccc" />
+    <path
+       style="display:inline;fill:none;stroke:#483420;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="m 28.636349,39.736975 c 0.453129,1.38959 1.885764,5.10389 3.477975,4.08568 0.817175,1.59851 1.706522,1.97032 2.736363,1.08377 -0.81768,1.34753 -0.863608,2.50192 0.604935,3.40964 -0.186761,1.75485 -0.585476,3.103729 0.9349,4.289539 -0.533899,2.11747 -0.187173,3.05934 0.962398,4.15206 -0.757651,1.24616 -0.523948,3.26969 0.907403,3.93208 -0.285562,1.18136 -0.829693,2.57144 1.814806,2.8322"
+       id="path8751-3"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccc" />
+    <path
+       sodipodi:nodetypes="cccccccc"
+       inkscape:connector-curvature="0"
+       id="path8754-2"
+       d="m 74.132165,39.637885 c -0.453129,1.38958 -1.885764,5.10388 -3.477975,4.08567 -0.817175,1.59852 -1.706522,1.97032 -2.736363,1.08378 0.81768,1.34752 0.863608,2.50191 -0.604935,3.40963 0.186761,1.75485 0.585476,3.103739 -0.9349,4.289549 0.533899,2.11747 0.187173,3.05933 -0.962398,4.15205 0.757651,1.24617 0.523948,3.26969 -0.907403,3.93208 0.285562,1.18136 0.829693,2.57145 -1.814806,2.8322"
+       style="display:inline;fill:none;stroke:#483420;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <path
+       style="display:inline;fill:none;stroke:#483420;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="m 38.347182,72.757924 3.033165,-5.36637 2.955391,4.23866 2.243636,-4.36199 2.394466,4.25907"
+       id="path8756-6"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       sodipodi:nodetypes="ccccc"
+       inkscape:connector-curvature="0"
+       id="path8759-3"
+       d="m 38.036089,70.138324 c -4.001746,6.97033 2.190618,-3.38314 3.227598,-5.32748 l 2.828116,3.88163 2.538252,-4.23161 2.085326,3.85214"
+       style="display:inline;fill:none;stroke:#483420;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <path
+       sodipodi:nodetypes="ccccc"
+       inkscape:connector-curvature="0"
+       id="path8761-9"
+       d="m 63.996206,72.627584 -2.856388,-5.18959 -2.867003,4.06188 -2.449865,-4.47197 -2.683184,4.35531"
+       style="display:inline;fill:none;stroke:#483420;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <path
+       style="display:inline;fill:none;stroke:#483420;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="m 64.572465,70.138324 c 4.001745,6.97033 -2.307279,-3.30537 -3.344259,-5.24971 l -2.799844,3.80386 -2.449864,-4.23161 -2.649015,3.8109"
+       id="path8763-1"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+  </g>
+</svg>
diff --git a/client/public/images/pieces/Xiangqi/bn.svg b/client/public/images/pieces/Xiangqi/bn.svg
new file mode 100644
index 00000000..c67d236c
--- /dev/null
+++ b/client/public/images/pieces/Xiangqi/bn.svg
@@ -0,0 +1,229 @@
+<?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="92"
+   height="92"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
+   sodipodi:docname="black_horse.svg">
+  <metadata
+     id="metadata12">
+    <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="defs10">
+    <filter
+       height="1.5"
+       width="1.5"
+       y="0"
+       x="0"
+       id="f1"
+       color-interpolation-filters="sRGB">
+      <feOffset
+         id="feOffset3123"
+         dy="1"
+         dx="1"
+         in="SourceAlpha"
+         result="offOut" />
+      <feGaussianBlur
+         id="feGaussianBlur3125"
+         stdDeviation="1"
+         in="offOut"
+         result="blurOut" />
+      <!--
+      <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
+-->
+    </filter>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad2">
+      <stop
+         id="stop3118"
+         style="stop-color:rgb(32,32,32);stop-opacity:0.3"
+         offset="30%" />
+      <stop
+         id="stop3120"
+         style="stop-color:rgb(255,255,255);stop-opacity:0.3"
+         offset="100%" />
+    </linearGradient>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad3">
+      <stop
+         id="stop3113"
+         style="stop-color:rgb(255,255,255);stop-opacity:0.6"
+         offset="10%" />
+      <stop
+         id="stop3115"
+         style="stop-color:rgb(50,30,20);stop-opacity:0.3"
+         offset="60%" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#grad3"
+       id="linearGradient3169"
+       x1="10.900002"
+       y1="4.9000015"
+       x2="10.900002"
+       y2="83.099998"
+       gradientUnits="userSpaceOnUse" />
+  </defs>
+  <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="1001"
+     id="namedview8"
+     showgrid="false"
+     inkscape:zoom="5.2444445"
+     inkscape:cx="14.157847"
+     inkscape:cy="37.262397"
+     inkscape:window-x="1913"
+     inkscape:window-y="0"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <g
+     id="use4"
+     transform="translate(-4,2)">
+    <circle
+       style="opacity:0.3;fill:#000000;filter:url(#f1)"
+       cx="50"
+       cy="49"
+       r="39"
+       id="circle3159"
+       d="M 89,49 C 89,70.539105 71.539105,88 50,88 28.460895,88 11,70.539105 11,49 11,27.460895 28.460895,10 50,10 71.539105,10 89,27.460895 89,49 z"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="49"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:#302010"
+       cx="50"
+       cy="44"
+       r="39"
+       id="circle3161"
+       d="M 89,44 C 89,65.539105 71.539105,83 50,83 28.460895,83 11,65.539105 11,44 11,22.460895 28.460895,5 50,5 71.539105,5 89,22.460895 89,44 z"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:url(#linearGradient3169)"
+       cx="50"
+       cy="44"
+       r="39.099998"
+       id="circle3163"
+       d="M 89.099998,44 C 89.099998,65.594333 71.594333,83.099998 50,83.099998 28.405667,83.099998 10.900002,65.594333 10.900002,44 10.900002,22.405667 28.405667,4.9000015 50,4.9000015 71.594333,4.9000015 89.099998,22.405667 89.099998,44 z"
+       sodipodi:ry="39.099998"
+       sodipodi:rx="39.099998"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:none;stroke:#442211;stroke-width:1"
+       cx="50"
+       cy="44"
+       r="39"
+       id="circle3165"
+       d="M 89,44 C 89,65.539105 71.539105,83 50,83 28.460895,83 11,65.539105 11,44 11,22.460895 28.460895,5 50,5 71.539105,5 89,22.460895 89,44 z"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:#483420"
+       cx="50"
+       cy="44"
+       r="34.049999"
+       id="circle3167"
+       d="M 84.049999,44 C 84.049999,62.805295 68.805295,78.049999 50,78.049999 31.194705,78.049999 15.950001,62.805295 15.950001,44 15.950001,25.194705 31.194705,9.9500008 50,9.9500008 68.805295,9.9500008 84.049999,25.194705 84.049999,44 z"
+       sodipodi:ry="34.049999"
+       sodipodi:rx="34.049999"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+  </g>
+  <g
+     style="display:inline"
+     id="g10283"
+     transform="matrix(0.96565541,0,0,0.96565541,123.49829,2.823745)">
+    <g
+       transform="matrix(1.6119947,0,0,1.6119947,-51.297818,-45.558668)"
+       id="g4496"
+       style="display:inline">
+      <path
+         style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.19975252;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         d="m -20.363965,43.589358 c -0.0276,-1.46313 -0.713126,-2.145608 -1.299776,-3.329198 -0.571744,1.388345 -1.389781,2.98152 -1.051241,4.192856 -0.64554,-0.302018 -1.29108,0.196403 -1.93662,0.50794 -4.172427,6.925057 -3.872501,6.543133 -7.74648,9.703329 -0.41274,1.0845 -0.66256,1.961621 0.0587,3.579812 0.36665,0.484202 2.0734,1.323734 3.37442,1.496479 0.37959,0.533363 0.0389,0.715844 0.0293,0.850939 0.57883,0.586855 0.84987,0.352113 1.46713,0.528169 1.64825,-1.771306 3.2607,-3.327849 4.75353,-4.166667 1.95618,-0.980405 3.91236,-0.564172 5.86854,-0.704225 1.456321,0.21705 2.389217,-0.81096 2.481038,-0.822807 -0.7034,1.107585 -1.211128,2.439303 -3.126578,3.698394 -1.18159,-0.284668 -1.84361,-0.179659 -2.4061,0 -4.23123,3.229653 -5.76905,8.997115 -5.75117,11.326292 5.708582,2.230783 11.7045,1.157214 17.7229999,-0.176057 -1.599,-1.233028 -1.55432,-2.671516 -1.9953,-4.049296 -0.3933899,-3.368319 0.386688,-3.431093 0.88028,-6.57277 0.34933,-6.266657 -0.432697,-11.619231 -5.5252069,-14.931742 -0.91599,-0.402395 -2.781791,-0.345578 -3.748111,-0.295054 0.0658,-1.508632 -0.62168,-2.655508 -0.98402,-4.021428 -0.008,-0.0078 -1.465491,2.090218 -1.163721,2.744109 -0.07401,0.08009 0.206841,0.429509 0.09838,0.440925 z"
+         id="path4426"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cccccccccccccccccccccccc" />
+      <path
+         style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.09243207;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         d="m -19.406506,41.091703 c 14.3383277,-1.44366 14.6623349,12.941854 12.9102306,22.786351 -0.3727255,2.094222 0.5431423,3.922119 0.4131333,5.516454 -4.3778739,-1.27574 -3.261783,-4.989674 -2.1272975,-9.89572 0.1816486,-7.188013 -0.4354701,-13.936194 -8.2870824,-15.80692 -0.538977,-0.05014 -1.697034,0.233285 -2.238074,0.223765 -1.184158,0.0502 -0.854474,-2.06219 -0.67091,-2.823934 z"
+         id="path4428"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cscccccc" />
+      <ellipse
+         style="opacity:1;fill:#483420;fill-opacity:1;stroke:#483420;stroke-width:0.09785748;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
+         id="path4461"
+         cx="-22.465561"
+         cy="49.837406"
+         rx="0.96838528"
+         ry="1.0133952" />
+      <path
+         style="fill:none;fill-opacity:1;stroke:#483420;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m -24.006062,50.908416 c 1.03577,-0.831732 -0.63174,-2.617565 3.11033,-2.494132"
+         id="path4463"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cc" />
+      <path
+         style="fill:#483420;fill-opacity:1;stroke:#483420;stroke-width:0.93052417;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         d="m -29.234621,60.161919 c 0.95231,-0.642849 1.758922,-1.427453 2.394037,-2.268554"
+         id="path4489"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cc" />
+    </g>
+    <path
+       sodipodi:nodetypes="cccsc"
+       inkscape:connector-curvature="0"
+       id="path5410"
+       d="m -102.89655,45.661554 c -0.18838,1.060968 0.035,1.786052 0.60673,2.494349 0.8387,0.540409 1.66987,1.091355 2.662885,1.415711 0,0 0.554672,-0.395936 0.432413,-0.412667 -1.076438,-0.14731 -2.933168,-0.973326 -3.702028,-3.497393 z"
+       style="display:inline;fill:#483420;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       sodipodi:nodetypes="ccccscc"
+       inkscape:connector-curvature="0"
+       id="path5412"
+       d="m -100.49552,45.624567 c -0.36265,0.193491 -0.6895,0.422791 -0.73888,0.929555 0.21409,0.310494 0.55658,0.428382 1.0249,0.357521 0.314135,-0.297622 0.655486,-0.56803 0.786545,-1.048729 0,0 -0.619705,-1.191737 -0.619705,-1.048729 0,0.143009 0.0238,0.786547 0.0238,0.786547 z"
+       style="display:inline;fill:#483420;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+  </g>
+</svg>
diff --git a/client/public/images/pieces/Xiangqi/bp.svg b/client/public/images/pieces/Xiangqi/bp.svg
new file mode 100644
index 00000000..6855745a
--- /dev/null
+++ b/client/public/images/pieces/Xiangqi/bp.svg
@@ -0,0 +1,215 @@
+<?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="92"
+   height="92"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
+   sodipodi:docname="black_pawn.svg">
+  <metadata
+     id="metadata12">
+    <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>
+  <defs
+     id="defs10">
+    <filter
+       height="1.5"
+       width="1.5"
+       y="0"
+       x="0"
+       id="f1"
+       color-interpolation-filters="sRGB">
+      <feOffset
+         id="feOffset3123"
+         dy="1"
+         dx="1"
+         in="SourceAlpha"
+         result="offOut" />
+      <feGaussianBlur
+         id="feGaussianBlur3125"
+         stdDeviation="1"
+         in="offOut"
+         result="blurOut" />
+      <!--
+      <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
+-->
+    </filter>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad2">
+      <stop
+         id="stop3118"
+         style="stop-color:rgb(32,32,32);stop-opacity:0.3"
+         offset="30%" />
+      <stop
+         id="stop3120"
+         style="stop-color:rgb(255,255,255);stop-opacity:0.3"
+         offset="100%" />
+    </linearGradient>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad3">
+      <stop
+         id="stop3113"
+         style="stop-color:rgb(255,255,255);stop-opacity:0.6"
+         offset="10%" />
+      <stop
+         id="stop3115"
+         style="stop-color:rgb(50,30,20);stop-opacity:0.3"
+         offset="60%" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#grad3"
+       id="linearGradient3169"
+       x1="10.900002"
+       y1="4.9000015"
+       x2="10.900002"
+       y2="83.099998"
+       gradientUnits="userSpaceOnUse" />
+  </defs>
+  <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="namedview8"
+     showgrid="false"
+     inkscape:zoom="2.6222222"
+     inkscape:cx="33.237365"
+     inkscape:cy="34.669105"
+     inkscape:window-x="1913"
+     inkscape:window-y="0"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <g
+     id="use4"
+     transform="translate(-4,2)">
+    <circle
+       style="opacity:0.3;fill:#000000;filter:url(#f1)"
+       cx="50"
+       cy="49"
+       r="39"
+       id="circle3159"
+       d="M 89,49 C 89,70.539105 71.539105,88 50,88 28.460895,88 11,70.539105 11,49 11,27.460895 28.460895,10 50,10 71.539105,10 89,27.460895 89,49 z"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="49"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:#302010"
+       cx="50"
+       cy="44"
+       r="39"
+       id="circle3161"
+       d="M 89,44 C 89,65.539105 71.539105,83 50,83 28.460895,83 11,65.539105 11,44 11,22.460895 28.460895,5 50,5 71.539105,5 89,22.460895 89,44 z"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:url(#linearGradient3169)"
+       cx="50"
+       cy="44"
+       r="39.099998"
+       id="circle3163"
+       d="M 89.099998,44 C 89.099998,65.594333 71.594333,83.099998 50,83.099998 28.405667,83.099998 10.900002,65.594333 10.900002,44 10.900002,22.405667 28.405667,4.9000015 50,4.9000015 71.594333,4.9000015 89.099998,22.405667 89.099998,44 z"
+       sodipodi:ry="39.099998"
+       sodipodi:rx="39.099998"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:none;stroke:#442211;stroke-width:1"
+       cx="50"
+       cy="44"
+       r="39"
+       id="circle3165"
+       d="M 89,44 C 89,65.539105 71.539105,83 50,83 28.460895,83 11,65.539105 11,44 11,22.460895 28.460895,5 50,5 71.539105,5 89,22.460895 89,44 z"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:#483420"
+       cx="50"
+       cy="44"
+       r="34.049999"
+       id="circle3167"
+       d="M 84.049999,44 C 84.049999,62.805295 68.805295,78.049999 50,78.049999 31.194705,78.049999 15.950001,62.805295 15.950001,44 15.950001,25.194705 31.194705,9.9500008 50,9.9500008 68.805295,9.9500008 84.049999,25.194705 84.049999,44 z"
+       sodipodi:ry="34.049999"
+       sodipodi:rx="34.049999"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+  </g>
+  <g
+     transform="translate(0.02103906,1.7456904)"
+     style="display:inline;fill:#ffffff;stroke:#ffffff"
+     id="g9866">
+    <g
+       style="display:inline;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.31294143;stroke-miterlimit:4;stroke-dasharray:none;paint-order:stroke fill markers"
+       transform="matrix(0.73170801,0,0,0.89061254,62.585414,-13.581686)"
+       id="g2182-3">
+      <g
+         style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.31294143;stroke-miterlimit:4;stroke-dasharray:none"
+         id="g2180-9"
+         transform="translate(0.4695196,-1.5015006)">
+        <path
+           style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.31294143;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
+           d="m -22.715841,41.496901 c -6.709808,7.383569 -10.663816,12.802391 -14.029253,18.972935 9.833495,-1.692893 19.278926,-2.323037 27.646001,0 -2.69856,-4.464975 -7.002481,-10.253202 -13.616748,-18.972935 z"
+           id="path2176-6"
+           inkscape:connector-curvature="0"
+           sodipodi:nodetypes="cccc" />
+        <path
+           sodipodi:nodetypes="cccccccc"
+           inkscape:connector-curvature="0"
+           id="path2178-9"
+           d="m -26.817667,60.896469 c 1.31085,8.861829 -3.645845,14.386908 -11.545204,19.081976 -5.236973,2.010186 -7.708873,4.499726 -7.614698,9.332185 12.369865,3.211336 31.696805,2.290793 45.67493078,-0.116941 -0.002369,-3.821858 -2.08387088,-9.351048 -7.28998228,-9.958106 -10.3223275,-4.971535 -10.9033515,-10.063579 -11.0201045,-18.30082 -3.173543,-0.438952 -5.925438,-0.207767 -8.204942,-0.03829 z"
+           style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.31294143;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
+      </g>
+    </g>
+    <path
+       sodipodi:nodetypes="ccccc"
+       inkscape:connector-curvature="0"
+       id="path6140"
+       d="m 37.364676,36.197364 -1.389805,2.974841 2.603272,-0.615322 c -0.516847,-0.05328 -1.134816,0.02931 -1.651663,-0.18539 -0.03118,-0.693179 0.308827,-1.521087 0.438196,-2.174129 z"
+       style="fill:#ffffff;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       sodipodi:nodetypes="cccccc"
+       inkscape:connector-curvature="0"
+       id="path6146"
+       d="m 42.066862,48.315182 c -0.970796,1.874384 -4.188748,6.060346 -7.208317,7.995683 -3.889337,1.575798 -5.791152,4.885757 -5.571735,8.311361 l 0.881332,0.37813 c -0.117629,-2.366189 0.54481,-4.864987 2.662886,-6.640362 3.833557,-2.202021 8.236266,-5.603108 9.235834,-10.044812 z"
+       style="fill:#ffffff;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+  </g>
+</svg>
diff --git a/client/public/images/pieces/Xiangqi/br.svg b/client/public/images/pieces/Xiangqi/br.svg
new file mode 100644
index 00000000..d78fe56e
--- /dev/null
+++ b/client/public/images/pieces/Xiangqi/br.svg
@@ -0,0 +1,293 @@
+<?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="92"
+   height="92"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
+   sodipodi:docname="black_chariot.svg">
+  <metadata
+     id="metadata12">
+    <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="defs10">
+    <filter
+       height="1.5"
+       width="1.5"
+       y="0"
+       x="0"
+       id="f1"
+       color-interpolation-filters="sRGB">
+      <feOffset
+         id="feOffset3123"
+         dy="1"
+         dx="1"
+         in="SourceAlpha"
+         result="offOut" />
+      <feGaussianBlur
+         id="feGaussianBlur3125"
+         stdDeviation="1"
+         in="offOut"
+         result="blurOut" />
+      <!--
+      <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
+-->
+    </filter>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad2">
+      <stop
+         id="stop3118"
+         style="stop-color:rgb(32,32,32);stop-opacity:0.3"
+         offset="30%" />
+      <stop
+         id="stop3120"
+         style="stop-color:rgb(255,255,255);stop-opacity:0.3"
+         offset="100%" />
+    </linearGradient>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad3">
+      <stop
+         id="stop3113"
+         style="stop-color:rgb(255,255,255);stop-opacity:0.6"
+         offset="10%" />
+      <stop
+         id="stop3115"
+         style="stop-color:rgb(50,30,20);stop-opacity:0.3"
+         offset="60%" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#grad3"
+       id="linearGradient3169"
+       x1="10.900002"
+       y1="4.9000015"
+       x2="10.900002"
+       y2="83.099998"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5290"
+       id="linearGradient5306"
+       gradientUnits="userSpaceOnUse"
+       x1="22.018419"
+       y1="47.282806"
+       x2="75.110641"
+       y2="47.282806" />
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient5290">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop5286" />
+      <stop
+         style="stop-color:#4d4d4d;stop-opacity:1"
+         offset="1"
+         id="stop5288" />
+    </linearGradient>
+  </defs>
+  <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="1001"
+     id="namedview8"
+     showgrid="false"
+     inkscape:zoom="1.8541911"
+     inkscape:cx="-35.663236"
+     inkscape:cy="-3.0857141"
+     inkscape:window-x="1913"
+     inkscape:window-y="0"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <g
+     id="use4"
+     transform="translate(-4,2)">
+    <circle
+       style="opacity:0.3;fill:#000000;filter:url(#f1)"
+       cx="50"
+       cy="49"
+       r="39"
+       id="circle3159"
+       d="M 89,49 C 89,70.539105 71.539105,88 50,88 28.460895,88 11,70.539105 11,49 11,27.460895 28.460895,10 50,10 71.539105,10 89,27.460895 89,49 z"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="49"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:#302010"
+       cx="50"
+       cy="44"
+       r="39"
+       id="circle3161"
+       d="M 89,44 C 89,65.539105 71.539105,83 50,83 28.460895,83 11,65.539105 11,44 11,22.460895 28.460895,5 50,5 71.539105,5 89,22.460895 89,44 z"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:url(#linearGradient3169)"
+       cx="50"
+       cy="44"
+       r="39.099998"
+       id="circle3163"
+       d="M 89.099998,44 C 89.099998,65.594333 71.594333,83.099998 50,83.099998 28.405667,83.099998 10.900002,65.594333 10.900002,44 10.900002,22.405667 28.405667,4.9000015 50,4.9000015 71.594333,4.9000015 89.099998,22.405667 89.099998,44 z"
+       sodipodi:ry="39.099998"
+       sodipodi:rx="39.099998"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:none;stroke:#442211;stroke-width:1"
+       cx="50"
+       cy="44"
+       r="39"
+       id="circle3165"
+       d="M 89,44 C 89,65.539105 71.539105,83 50,83 28.460895,83 11,65.539105 11,44 11,22.460895 28.460895,5 50,5 71.539105,5 89,22.460895 89,44 z"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:#483420"
+       cx="50"
+       cy="44"
+       r="34.049999"
+       id="circle3167"
+       d="M 84.049999,44 C 84.049999,62.805295 68.805295,78.049999 50,78.049999 31.194705,78.049999 15.950001,62.805295 15.950001,44 15.950001,25.194705 31.194705,9.9500008 50,9.9500008 68.805295,9.9500008 84.049999,25.194705 84.049999,44 z"
+       sodipodi:ry="34.049999"
+       sodipodi:rx="34.049999"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+  </g>
+  <g
+     style="display:inline"
+     id="g18181"
+     transform="translate(4.4814075e-7,1.1908339)">
+    <path
+       style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="m 24.659465,26.904975 c 12.079888,0.82929 16.235222,0.778634 20.790704,0.762712 l -0.115084,18.315683 1.15722,-0.03443 0.229866,-18.28125 C 59.504821,27.7557 65.492444,27.481526 69.355506,26.904978 53.15633,21.719733 37.356437,21.6211 24.659465,26.904975 Z"
+       id="path5517"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccccc" />
+    <path
+       inkscape:connector-curvature="0"
+       style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.12982513;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
+       d="M 50.044649,37.78537 A 16.761462,16.761462 0 0 1 66.805279,54.545996 16.761462,16.761462 0 0 1 50.044649,71.309166 16.761462,16.761462 0 0 1 33.281485,54.545996 16.761462,16.761462 0 0 1 50.044649,37.78537 Z m 0,2.515362 a 14.247242,14.247242 0 0 0 -14.247802,14.245264 14.247242,14.247242 0 0 0 14.247802,14.2478 14.247242,14.247242 0 0 0 14.2478,-14.2478 14.247242,14.247242 0 0 0 -14.2478,-14.245264 z"
+       id="path5173" />
+    <path
+       style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.29825127px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="M 30.340966,50.544723 C 29.240607,48.961402 28.288371,46.424541 27.319045,44.57917 l -4.114171,-0.07619 c -0.572036,0.863469 -0.801476,1.726938 -0.228571,2.590407 l 3.047542,0.228566 c 0.679011,2.273621 1.630084,4.00315 2.590413,5.714133 l 4.508653,0.16831 c 0.108315,-1.15859 -0.02335,-0.80349 0.360831,-2.611896 -1.235017,0.05123 -1.925316,0.02215 -3.142776,-0.04778 z"
+       id="path5176"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccc" />
+    <path
+       style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.29825127px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="m 64.677261,28.842398 c 0.03917,5.884009 0.265917,11.78969 0.115055,16.956669 -4.797619,-5.826791 -6.000532,-6.87719 -14.110332,-8.400876 0.266048,-2.019106 5.124498,-8.160352 8.096482,-8.825452 z"
+       id="path5178"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="m 64.670174,53.149166 c -0.21864,-1.896417 -1.639002,-5.533526 -3.730067,-8.463135 -2.31979,-3.250055 -8.120538,-4.6395 -10.524676,-4.587544 -1.072241,2.513709 -2.372868,5.80951 -10.146798,6.630961 0,0.631156 -0.06417,3.053966 -0.07197,4.001862 -1.007086,0.06729 -2.60815,0.118058 -3.694251,0.04705 -0.198372,0.686616 -0.359385,2.050886 -0.327775,2.418476 9.184798,0.18599 19.417583,0.025 28.495537,-0.0477 z"
+       id="path5248"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="csccccccc" />
+    <path
+       style="display:inline;fill:#483420;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="m 41.764847,47.194434 -0.905721,0.04767 v 3.146187 l 0.619704,-0.572034 z"
+       id="path5414"
+       inkscape:connector-curvature="0" />
+    <path
+       style="display:inline;fill:#483420;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="m 50.86972,40.330027 c -0.179509,1.048729 -0.909708,2.097458 -1.716102,3.146187 0.930784,-0.834786 1.629443,-1.620091 2.441718,-3.165932 z"
+       id="path5416"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccc" />
+    <path
+       style="display:inline;fill:#483420;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="m 51.402262,37.11403 c 0.282885,-1.227948 2.298384,-3.281929 3.185678,-4.268113 -0.482432,1.120674 -2.342435,3.234241 -2.235675,4.472754 z"
+       id="path5418"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccc" />
+    <path
+       style="display:inline;fill:none;stroke:#483420;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 50.631372,52.897426 57.151519,41.40668"
+       id="path5420"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="display:inline;fill:#000000;stroke:#483420;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 49.747793,52.962446 49.612964,40.687669"
+       id="path5437"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       sodipodi:type="star"
+       style="display:inline;opacity:1;fill:url(#linearGradient5306);fill-opacity:1;stroke:#ffffff;stroke-width:0.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
+       id="path5165"
+       sodipodi:sides="12"
+       sodipodi:cx="198.1891"
+       sodipodi:cy="38.199802"
+       sodipodi:r1="10.981865"
+       sodipodi:r2="0.10981865"
+       sodipodi:arg1="0.82281385"
+       sodipodi:arg2="1.0846132"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="m 205.65854,46.250197 -7.41812,-7.953301 2.39221,10.609472 -2.44764,-10.596824 -3.23301,10.384179 3.17869,-10.400935 -7.99196,7.376453 7.9533,-7.418125 -10.60947,2.392212 10.59682,-2.447634 -10.38418,-3.233019 10.40094,3.178699 -7.37646,-7.991966 7.41813,7.953301 -2.39221,-10.609472 2.44763,10.596824 3.23302,-10.384179 -3.1787,10.400935 7.99197,-7.376453 -7.9533,7.418125 10.60947,-2.392213 -10.59683,2.447634 10.38418,3.233019 -10.40093,-3.178698 z"
+       transform="matrix(-1.3208656,0.32230963,0.32230963,1.3208656,299.72684,-59.778699)" />
+    <path
+       style="display:inline;fill:none;stroke:#483420;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="m 51.490574,53.331596 11.393108,-6.84261"
+       id="path5471"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="display:inline;fill:none;stroke:#483420;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 49.008493,53.363606 44.715382,45.91596 v 0.06741"
+       id="path5473"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccc" />
+    <path
+       style="display:inline;fill:none;stroke:#483420;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 47.243438,53.331596 39.692976,49.151872"
+       id="path5475"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>
diff --git a/client/public/images/pieces/Xiangqi/wa.svg b/client/public/images/pieces/Xiangqi/wa.svg
new file mode 100644
index 00000000..2fcb3d9a
--- /dev/null
+++ b/client/public/images/pieces/Xiangqi/wa.svg
@@ -0,0 +1,257 @@
+<?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="92"
+   height="92"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
+   sodipodi:docname="red_advisor.svg">
+  <metadata
+     id="metadata12">
+    <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="defs10">
+    <filter
+       height="1.5"
+       width="1.5"
+       y="0"
+       x="0"
+       id="f1"
+       color-interpolation-filters="sRGB">
+      <feOffset
+         id="feOffset3039"
+         dy="0"
+         dx="1"
+         in="SourceAlpha"
+         result="offOut" />
+      <feGaussianBlur
+         id="feGaussianBlur3041"
+         stdDeviation="1"
+         in="offOut"
+         result="blurOut" />
+      <!--
+      <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
+-->
+    </filter>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad1">
+      <stop
+         id="stop3034"
+         style="stop-color:rgb(255,255,255);stop-opacity:0.6"
+         offset="20%" />
+      <stop
+         id="stop3036"
+         style="stop-color:rgb(220,0,0);stop-opacity:0.5"
+         offset="50%" />
+    </linearGradient>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad0">
+      <stop
+         id="stop3029"
+         style="stop-color:rgb(0,0,0);stop-opacity:0.3"
+         offset="20%" />
+      <stop
+         id="stop3031"
+         style="stop-color:rgb(0,0,0);stop-opacity:0.6"
+         offset="100%" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#grad1"
+       id="linearGradient3085"
+       x1="10.900002"
+       y1="4.9000015"
+       x2="10.900002"
+       y2="83.099998"
+       gradientUnits="userSpaceOnUse" />
+  </defs>
+  <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="namedview8"
+     showgrid="false"
+     inkscape:zoom="0.92709555"
+     inkscape:cx="-153.76317"
+     inkscape:cy="257.99054"
+     inkscape:window-x="2872"
+     inkscape:window-y="-8"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <g
+     id="use4"
+     transform="translate(-4,2)">
+    <circle
+       style="opacity:0.5;fill:#000000;filter:url(#f1)"
+       cx="50"
+       cy="49.5"
+       r="39"
+       id="circle3075"
+       d="m 89,49.5 c 0,21.539105 -17.460895,39 -39,39 -21.539105,0 -39,-17.460895 -39,-39 0,-21.539105 17.460895,-39 39,-39 21.539105,0 39,17.460895 39,39 z"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="49.5"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:#ee2211"
+       cx="50"
+       cy="44"
+       r="39"
+       id="circle3077"
+       d="M 89,44 C 89,65.539105 71.539105,83 50,83 28.460895,83 11,65.539105 11,44 11,22.460895 28.460895,5 50,5 71.539105,5 89,22.460895 89,44 z"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:url(#linearGradient3085)"
+       cx="50"
+       cy="44"
+       r="39.099998"
+       id="circle3079"
+       d="M 89.099998,44 C 89.099998,65.594333 71.594333,83.099998 50,83.099998 28.405667,83.099998 10.900002,65.594333 10.900002,44 10.900002,22.405667 28.405667,4.9000015 50,4.9000015 71.594333,4.9000015 89.099998,22.405667 89.099998,44 z"
+       sodipodi:ry="39.099998"
+       sodipodi:rx="39.099998"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:none;stroke:#aa0000;stroke-width:1"
+       cx="50"
+       cy="44"
+       r="39.099998"
+       id="circle3081"
+       d="M 89.099998,44 C 89.099998,65.594333 71.594333,83.099998 50,83.099998 28.405667,83.099998 10.900002,65.594333 10.900002,44 10.900002,22.405667 28.405667,4.9000015 50,4.9000015 71.594333,4.9000015 89.099998,22.405667 89.099998,44 z"
+       sodipodi:ry="39.099998"
+       sodipodi:rx="39.099998"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:#ee2211"
+       cx="50"
+       cy="44"
+       r="33.5"
+       id="circle3083"
+       d="M 83.5,44 C 83.5,62.501539 68.501539,77.5 50,77.5 31.498461,77.5 16.5,62.501539 16.5,44 16.5,25.498461 31.498461,10.5 50,10.5 68.501539,10.5 83.5,25.498461 83.5,44 z"
+       sodipodi:ry="33.5"
+       sodipodi:rx="33.5"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+  </g>
+  <g
+     style="font-size:42px;font-weight:normal;text-anchor:middle;fill:#ffffff;stroke:#ffffff;stroke-width:1.25;font-family:'WenQuanYi Micro Hei, Arial'"
+     id="text6"
+     transform="translate(-4,2)" />
+  <g
+     style="display:inline"
+     id="g16676"
+     transform="matrix(1.0851597,0,0,1.0851597,-4.2380512,0.28870138)">
+    <path
+       sodipodi:nodetypes="cccccccccccc"
+       inkscape:connector-curvature="0"
+       id="path7039"
+       d="M 46.314318,54.9317 C 42.356998,54.834892 38.28061,55.053577 33.042662,54.572582 29.08398,51.239218 24.163206,34.895196 26.264735,27.515155 l 2.242968,5.073731 c 0.904414,-1.286503 4.443742,-3.043957 5.826002,-0.651772 3.063224,-2.067575 3.965642,-1.47325 6.167862,-0.446321 2.326036,-1.963969 3.759013,-1.686422 5.584723,-0.208555 2.435106,-1.540839 2.91277,-2.315498 5.969919,-0.234576 1.393794,-1.805529 5.348995,-1.238852 6.514895,0.63516 0.72922,-1.449764 3.882256,-1.601314 5.129111,0.705381 l 2.779908,-5.008547 c 1.69577,7.471841 -3.140965,24.150404 -6.983188,27.080935"
+       style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.05248582;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <path
+       sodipodi:nodetypes="ccccccc"
+       inkscape:connector-curvature="0"
+       id="path7043"
+       d="m 33.042662,54.221383 c -0.04538,3.440549 0.535511,6.221829 1.46304,9.662379 4.266942,1.897027 7.563074,2.10954 11.478298,2.199874 3.915225,-0.07254 8.300478,-0.65405 11.865019,-2.300217 0.92753,-3.44055 1.712825,-6.121487 1.667438,-9.562036 l -13.213668,0.452419 z"
+       style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.56941742;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <path
+       sodipodi:nodetypes="cc"
+       inkscape:connector-curvature="0"
+       id="path7051"
+       d="m 34.248108,31.144819 c 0.161876,7.627342 2.186141,16.283659 4.225636,23.508654"
+       style="fill:none;stroke:#ee2211;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <path
+       sodipodi:nodetypes="cc"
+       inkscape:connector-curvature="0"
+       id="path7053"
+       d="M 58.487159,30.379647 C 57.905091,37.947181 56.903213,47.41971 54.483762,54.462278"
+       style="fill:none;stroke:#ee2211;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <path
+       sodipodi:nodetypes="cc"
+       inkscape:connector-curvature="0"
+       id="path7088"
+       d="M 52.145463,29.521685 C 51.563396,37.089219 51.450918,46.10004 49.382667,53.242951"
+       style="fill:none;stroke:#ee2211;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <path
+       style="fill:none;stroke:#ee2211;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="m 40.524586,30.501832 c 0.161876,7.627343 0.823654,15.521191 2.863149,22.746186"
+       id="path7090"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       sodipodi:nodetypes="cc"
+       inkscape:connector-curvature="0"
+       id="path7092"
+       d="M 46.225032,53.395931 46.124215,30.697163"
+       style="fill:none;stroke:#ee2211;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <path
+       style="fill:none;stroke:#ee2211;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 32.779521,55.723468 C 43.040852,53.07175 52.284118,54.00966 60.026058,55.823812"
+       id="path7094"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       sodipodi:nodetypes="cc"
+       inkscape:connector-curvature="0"
+       id="path7096"
+       d="m 33.649764,63.258142 c 9.702633,-2.248555 17.829672,-1.559126 24.853754,-0.200528"
+       style="fill:none;stroke:#ee2211;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <circle
+       r="1.4591321"
+       cy="58.035988"
+       cx="46.108307"
+       id="path7098"
+       style="opacity:1;fill:#ee2211;fill-opacity:1;stroke:#ee2211;stroke-width:0.56941742;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" />
+    <path
+       sodipodi:nodetypes="cc"
+       inkscape:connector-curvature="0"
+       id="path7051-0"
+       d="m 29.471433,30.206797 c -1.317204,7.565714 2.169353,17.040115 4.945284,24.295795"
+       style="display:inline;fill:none;stroke:#ee2211;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <path
+       style="display:inline;fill:none;stroke:#ee2211;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="m 63.310845,30.432888 c 1.317204,7.565714 -2.544353,16.790115 -5.320284,24.045795"
+       id="path7645"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+  </g>
+</svg>
diff --git a/client/public/images/pieces/Xiangqi/wc.svg b/client/public/images/pieces/Xiangqi/wc.svg
new file mode 100644
index 00000000..a5c1e58a
--- /dev/null
+++ b/client/public/images/pieces/Xiangqi/wc.svg
@@ -0,0 +1,322 @@
+<?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="92"
+   height="92"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
+   sodipodi:docname="red_cannon.svg">
+  <metadata
+     id="metadata12">
+    <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>
+  <defs
+     id="defs10">
+    <filter
+       height="1.5"
+       width="1.5"
+       y="0"
+       x="0"
+       id="f1"
+       color-interpolation-filters="sRGB">
+      <feOffset
+         id="feOffset3039"
+         dy="0"
+         dx="1"
+         in="SourceAlpha"
+         result="offOut" />
+      <feGaussianBlur
+         id="feGaussianBlur3041"
+         stdDeviation="1"
+         in="offOut"
+         result="blurOut" />
+      <!--
+      <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
+-->
+    </filter>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad1">
+      <stop
+         id="stop3034"
+         style="stop-color:rgb(255,255,255);stop-opacity:0.6"
+         offset="20%" />
+      <stop
+         id="stop3036"
+         style="stop-color:rgb(220,0,0);stop-opacity:0.5"
+         offset="50%" />
+    </linearGradient>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad0">
+      <stop
+         id="stop3029"
+         style="stop-color:rgb(0,0,0);stop-opacity:0.3"
+         offset="20%" />
+      <stop
+         id="stop3031"
+         style="stop-color:rgb(0,0,0);stop-opacity:0.6"
+         offset="100%" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#grad1"
+       id="linearGradient3085"
+       x1="10.900002"
+       y1="4.9000015"
+       x2="10.900002"
+       y2="83.099998"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="linearGradient11421">
+      <stop
+         id="stop11417"
+         style="stop-color:#c83737;stop-opacity:1"
+         offset="20%" />
+      <stop
+         id="stop11419"
+         style="stop-color:#de8787;stop-opacity:1"
+         offset="100%" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient5398"
+       x1="0"
+       y1="0"
+       x2="0"
+       y2="1">
+      <stop
+         offset="20%"
+         style="stop-color:#c83737;stop-opacity:1"
+         id="stop5394" />
+      <stop
+         offset="100%"
+         style="stop-color:#cf8080;stop-opacity:1"
+         id="stop5396" />
+    </linearGradient>
+    <filter
+       style="color-interpolation-filters:sRGB"
+       height="1.5"
+       width="1.5"
+       y="0"
+       x="0"
+       id="f1-4">
+      <feOffset
+         id="feOffset3039-4"
+         dy="0"
+         dx="1"
+         in="SourceAlpha"
+         result="offOut" />
+      <feGaussianBlur
+         id="feGaussianBlur3041-4"
+         stdDeviation="1"
+         in="offOut"
+         result="blurOut" />
+      <!--
+      <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
+-->
+    </filter>
+  </defs>
+  <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="namedview8"
+     showgrid="false"
+     inkscape:zoom="1.3111111"
+     inkscape:cx="69.872122"
+     inkscape:cy="109.91822"
+     inkscape:window-x="2872"
+     inkscape:window-y="-8"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <g
+     id="use4"
+     transform="translate(-4,2)">
+    <circle
+       style="opacity:0.5;fill:#000000;filter:url(#f1)"
+       cx="50"
+       cy="49.5"
+       r="39"
+       id="circle3075"
+       d="m 89,49.5 c 0,21.539105 -17.460895,39 -39,39 -21.539105,0 -39,-17.460895 -39,-39 0,-21.539105 17.460895,-39 39,-39 21.539105,0 39,17.460895 39,39 z"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="49.5"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:#ee2211"
+       cx="50"
+       cy="44"
+       r="39"
+       id="circle3077"
+       d="M 89,44 C 89,65.539105 71.539105,83 50,83 28.460895,83 11,65.539105 11,44 11,22.460895 28.460895,5 50,5 71.539105,5 89,22.460895 89,44 z"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:url(#linearGradient3085)"
+       cx="50"
+       cy="44"
+       r="39.099998"
+       id="circle3079"
+       d="M 89.099998,44 C 89.099998,65.594333 71.594333,83.099998 50,83.099998 28.405667,83.099998 10.900002,65.594333 10.900002,44 10.900002,22.405667 28.405667,4.9000015 50,4.9000015 71.594333,4.9000015 89.099998,22.405667 89.099998,44 z"
+       sodipodi:ry="39.099998"
+       sodipodi:rx="39.099998"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:none;stroke:#aa0000;stroke-width:1"
+       cx="50"
+       cy="44"
+       r="39.099998"
+       id="circle3081"
+       d="M 89.099998,44 C 89.099998,65.594333 71.594333,83.099998 50,83.099998 28.405667,83.099998 10.900002,65.594333 10.900002,44 10.900002,22.405667 28.405667,4.9000015 50,4.9000015 71.594333,4.9000015 89.099998,22.405667 89.099998,44 z"
+       sodipodi:ry="39.099998"
+       sodipodi:rx="39.099998"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:#ee2211"
+       cx="50"
+       cy="44"
+       r="33.5"
+       id="circle3083"
+       d="M 83.5,44 C 83.5,62.501539 68.501539,77.5 50,77.5 31.498461,77.5 16.5,62.501539 16.5,44 16.5,25.498461 31.498461,10.5 50,10.5 68.501539,10.5 83.5,25.498461 83.5,44 z"
+       sodipodi:ry="33.5"
+       sodipodi:rx="33.5"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+  </g>
+  <g
+     style="font-size:42px;font-weight:normal;text-anchor:middle;fill:#ffffff;stroke:#ffffff;stroke-width:1.25;font-family:'WenQuanYi Micro Hei, Arial'"
+     id="text6"
+     transform="translate(-4,2)" />
+  <g
+     transform="translate(4.4814075e-7,1.6647936)"
+     style="display:inline"
+     id="g18015">
+    <g
+       transform="translate(1.36549,2.250535)"
+       style="display:inline"
+       id="g19066">
+      <g
+         transform="matrix(-1.0339627,0,0,1.0339627,888.34584,-245.90707)"
+         id="g5204">
+        <g
+           id="g4916"
+           transform="matrix(0.42429161,0,0,0.35530383,319.4593,167.8082)">
+          <g
+             transform="matrix(0.91849155,-0.04088349,0.02866942,0.91849155,95.269582,54.832886)"
+             id="g873">
+            <path
+               sodipodi:nodetypes="ccccccccc"
+               inkscape:connector-curvature="0"
+               style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2.65330386;stroke-miterlimit:10"
+               d="m 1213.6335,288.03625 -92.5944,36.18456 c 0,0 -8.0242,8.93392 -2.8931,21.42532 l 0.063,0.30499 0.063,0.30498 c 4.9395,12.5585 16.4998,12.34665 16.4998,12.34665 37.098,-28.13428 66.1489,-38.4485 87.024,-50.31774 -0.192,-4.06467 -1.8458,-7.47907 -2.8249,-11.1936 -1.3824,-3.19489 -2.9322,-6.31529 -5.3374,-9.05516 z"
+               id="path47" />
+            <ellipse
+               style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:3.00610209;stroke-miterlimit:10"
+               id="circle53"
+               cy="677.90155"
+               cx="1017.132"
+               stroke-miterlimit="10"
+               rx="3.753881"
+               ry="3.6617434"
+               transform="matrix(0.95110508,-0.30886749,0.22204229,0.97503704,0,0)" />
+          </g>
+          <path
+             sodipodi:nodetypes="cccccc"
+             inkscape:connector-curvature="0"
+             id="rect875"
+             d="m 1188.053,314.76933 -0.1997,22.82133 -37.6537,4.53206 c -16.1431,26.71247 -25.0217,28.93186 -41.2475,19.47896 18.33,-6.79184 27.9258,-27.84095 38.5459,-46.51534 z"
+             style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#ee2211;stroke-width:1.83159566;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" />
+          <ellipse
+             cx="-1207.3654"
+             cy="214.17735"
+             rx="27.158773"
+             ry="32.340363"
+             transform="matrix(-0.99442868,-0.10541155,-0.07412913,0.99724865,0,0)"
+             id="path869"
+             style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#ee2211;stroke-width:1.99324226;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" />
+          <ellipse
+             ry="21.17234"
+             rx="17.729818"
+             cy="340.7244"
+             cx="1184.762"
+             id="path890"
+             style="opacity:1;fill:#ee2211;fill-opacity:1;stroke:#ee2211;stroke-width:2.05792236;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" />
+          <rect
+             transform="matrix(-0.62961158,0.77691007,0.65434208,0.75619868,0,0)"
+             y="1132.5303"
+             x="-684.76074"
+             height="41.437584"
+             width="2.9200215"
+             id="rect892-1"
+             style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2.22107673;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" />
+          <rect
+             style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2.2210741;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
+             id="rect909"
+             width="2.9027057"
+             height="41.684681"
+             x="-1155.4326"
+             y="-703.56848"
+             transform="matrix(-0.65516628,-0.75548471,-0.62877406,0.77758805,0,0)" />
+          <rect
+             style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2.2037704;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
+             id="rect911"
+             width="3.156975"
+             height="37.732437"
+             x="343.79016"
+             y="1165.2843"
+             transform="matrix(0.0023305,0.99999728,0.99999448,-0.00332335,0,0)" />
+          <rect
+             transform="matrix(-0.99998924,0.00463819,0.00325253,0.99999471,0,0)"
+             y="323.77573"
+             x="-1184.9684"
+             height="45.058598"
+             width="2.6436777"
+             id="rect913"
+             style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2.20377064;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" />
+        </g>
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/client/public/images/pieces/Xiangqi/we.svg b/client/public/images/pieces/Xiangqi/we.svg
new file mode 100644
index 00000000..18394c03
--- /dev/null
+++ b/client/public/images/pieces/Xiangqi/we.svg
@@ -0,0 +1,244 @@
+<?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="92"
+   height="92"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
+   sodipodi:docname="red_elephant.svg">
+  <metadata
+     id="metadata12">
+    <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="defs10">
+    <filter
+       height="1.5"
+       width="1.5"
+       y="0"
+       x="0"
+       id="f1"
+       color-interpolation-filters="sRGB">
+      <feOffset
+         id="feOffset3039"
+         dy="0"
+         dx="1"
+         in="SourceAlpha"
+         result="offOut" />
+      <feGaussianBlur
+         id="feGaussianBlur3041"
+         stdDeviation="1"
+         in="offOut"
+         result="blurOut" />
+      <!--
+      <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
+-->
+    </filter>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad1">
+      <stop
+         id="stop3034"
+         style="stop-color:rgb(255,255,255);stop-opacity:0.6"
+         offset="20%" />
+      <stop
+         id="stop3036"
+         style="stop-color:rgb(220,0,0);stop-opacity:0.5"
+         offset="50%" />
+    </linearGradient>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad0">
+      <stop
+         id="stop3029"
+         style="stop-color:rgb(0,0,0);stop-opacity:0.3"
+         offset="20%" />
+      <stop
+         id="stop3031"
+         style="stop-color:rgb(0,0,0);stop-opacity:0.6"
+         offset="100%" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#grad1"
+       id="linearGradient3085"
+       x1="10.900002"
+       y1="4.9000015"
+       x2="10.900002"
+       y2="83.099998"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="linearGradient11421">
+      <stop
+         id="stop11417"
+         style="stop-color:#c83737;stop-opacity:1"
+         offset="20%" />
+      <stop
+         id="stop11419"
+         style="stop-color:#de8787;stop-opacity:1"
+         offset="100%" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient5398"
+       x1="0"
+       y1="0"
+       x2="0"
+       y2="1">
+      <stop
+         offset="20%"
+         style="stop-color:#c83737;stop-opacity:1"
+         id="stop5394" />
+      <stop
+         offset="100%"
+         style="stop-color:#cf8080;stop-opacity:1"
+         id="stop5396" />
+    </linearGradient>
+  </defs>
+  <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="namedview8"
+     showgrid="false"
+     inkscape:zoom="1.3111111"
+     inkscape:cx="-34.440233"
+     inkscape:cy="38.722781"
+     inkscape:window-x="2872"
+     inkscape:window-y="-8"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <g
+     id="use4"
+     transform="translate(-4,2)">
+    <circle
+       style="opacity:0.5;fill:#000000;filter:url(#f1)"
+       cx="50"
+       cy="49.5"
+       r="39"
+       id="circle3075"
+       d="m 89,49.5 c 0,21.539105 -17.460895,39 -39,39 -21.539105,0 -39,-17.460895 -39,-39 0,-21.539105 17.460895,-39 39,-39 21.539105,0 39,17.460895 39,39 z"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="49.5"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:#ee2211"
+       cx="50"
+       cy="44"
+       r="39"
+       id="circle3077"
+       d="M 89,44 C 89,65.539105 71.539105,83 50,83 28.460895,83 11,65.539105 11,44 11,22.460895 28.460895,5 50,5 71.539105,5 89,22.460895 89,44 z"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:url(#linearGradient3085)"
+       cx="50"
+       cy="44"
+       r="39.099998"
+       id="circle3079"
+       d="M 89.099998,44 C 89.099998,65.594333 71.594333,83.099998 50,83.099998 28.405667,83.099998 10.900002,65.594333 10.900002,44 10.900002,22.405667 28.405667,4.9000015 50,4.9000015 71.594333,4.9000015 89.099998,22.405667 89.099998,44 z"
+       sodipodi:ry="39.099998"
+       sodipodi:rx="39.099998"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:none;stroke:#aa0000;stroke-width:1"
+       cx="50"
+       cy="44"
+       r="39.099998"
+       id="circle3081"
+       d="M 89.099998,44 C 89.099998,65.594333 71.594333,83.099998 50,83.099998 28.405667,83.099998 10.900002,65.594333 10.900002,44 10.900002,22.405667 28.405667,4.9000015 50,4.9000015 71.594333,4.9000015 89.099998,22.405667 89.099998,44 z"
+       sodipodi:ry="39.099998"
+       sodipodi:rx="39.099998"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:#ee2211"
+       cx="50"
+       cy="44"
+       r="33.5"
+       id="circle3083"
+       d="M 83.5,44 C 83.5,62.501539 68.501539,77.5 50,77.5 31.498461,77.5 16.5,62.501539 16.5,44 16.5,25.498461 31.498461,10.5 50,10.5 68.501539,10.5 83.5,25.498461 83.5,44 z"
+       sodipodi:ry="33.5"
+       sodipodi:rx="33.5"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+  </g>
+  <g
+     style="font-size:42px;font-weight:normal;text-anchor:middle;fill:#ffffff;stroke:#ffffff;stroke-width:1.25;font-family:'WenQuanYi Micro Hei, Arial'"
+     id="text6"
+     transform="translate(-4,2)" />
+  <g
+     style="display:inline"
+     id="g5374"
+     transform="matrix(1.170336,0,0,1.170336,-53.510217,11.065884)">
+    <g
+       transform="translate(-35.93211,22.786216)"
+       style="opacity:1"
+       id="g5357">
+      <path
+         style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m 125.66609,-2.121176 -3.2,5 -0.6,2.1 c -0.0945,1.5296586 0.15617,2.8292194 0.6,4 l -0.2,2.099999 c -1.09796,3.097738 -2.35981,6.067197 -2.60001,9.5 0.12511,0.773672 0.40427,1.44388 1.3,1.7 11.23011,-0.424319 16.82956,-5.233235 20.30001,-11.7 l 0.2,-2.099999 c -2.10707,-8.89280401 -8.15113,-13.4502442 -16.2,-15.8 -4.40015,-0.5317426 -7.59668,1.3815851 -10.20001,4.5 -2.59354,2.64077835 -4.39616,5.9439949 -5.3,10 -0.89646,1.6487885 -1.64452,1.9405129 -2.4,2.3 -2.28978,-0.6407124 -3.03862,-1.6262894 -2.5,-2.9 0.35259,-1.8089896 3.48816,-3.3504905 5.5,-5 1.59764,-2.6483718 2.34637,-5.1951958 -0.6,-7.3 -8.75831,-2.0518262 -7.05798,4.7061225 -5.2,6.20000004 1.23982,-0.5457366 2.00197,-1.22280981 2.4,-2.00000004 -0.25951,-0.4357328 -0.98217,-0.8162564 0,-1.4 0.5387,0.045976 0.81918,0.2856122 1,0.6 0,1 0.50403,1.1455069 -3.6,4 -2.41796,1.1605474 -2.59331,2.9892138 -3.5,4.6 -1.668162,8.737445 1.94976,11.358136 6.5,12.899999 0.86488,-0.721198 1.12021,-1.741094 1.5,-2.7 1.29573,0.281592 2.51468,0.385517 4.3,1.8 0.43333,-0.4 0.86667,-0.8 1.3,-1.2 l 1.1,0.5 -0.9,0.5 c -0.61971,0.861505 -1.43108,1.608021 -2.5,2.2 l 2.4,0.3 c 1.087,-0.403589 1.93334,-1.017048 2.7,-1.7 l 1.3,-0.4 c 1.21385,-2.971538 2.39138,-5.952154 2.9,-9.099999 -0.0806,-0.9844358 -0.10227,-1.7702685 -0.7,-4.5 l 0.7,-2.3 z"
+         id="path5349"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccc" />
+      <path
+         style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m 109.56608,17.578823 c -1.32838,4.066443 -4.04985,6.321863 -6.6,8.8 -0.20576,0.304421 0.14574,0.397532 1,0.3 3.90473,-1.863513 6.85963,-4.360243 8.1,-8 -0.78642,-0.41302 -1.31194,-1.08384 -2.5,-1.1 z"
+         id="path5353"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="ccccc" />
+    </g>
+    <path
+       sodipodi:nodetypes="ccccccc"
+       inkscape:connector-curvature="0"
+       id="path5363"
+       d="m 79.63397,28.56504 c -0.68176,-0.252758 -0.87046,0.286775 -1.2,0.6 0.0622,0.385834 -0.13002,0.560848 0.6,1.5 0.63484,0.221654 1.42189,0.04926 2.2,-0.1 0.84331,0.145013 1.30379,0.481437 1.8,0.8 -0.0628,-0.684154 -0.45126,-1.226866 -1,-1.7 z"
+       style="fill:#ee2211;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       sodipodi:nodetypes="ccccc"
+       inkscape:connector-curvature="0"
+       id="path5365"
+       d="m 80.03397,27.36504 c -0.82212,0.100251 -1.34347,0.435691 -1.7,0.9 0.31963,-0.0098 0.65496,-0.02748 1.1,-0.1 0.812,-0.717231 1.30759,-0.282359 1.9,-0.2 -0.34309,-0.230079 -0.76634,-0.433443 -1.3,-0.6 z"
+       style="fill:#ee2211;fill-opacity:1;stroke:none;stroke-width:1.00157475;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+  </g>
+</svg>
diff --git a/client/public/images/pieces/Xiangqi/wk.svg b/client/public/images/pieces/Xiangqi/wk.svg
new file mode 100644
index 00000000..c898b301
--- /dev/null
+++ b/client/public/images/pieces/Xiangqi/wk.svg
@@ -0,0 +1,291 @@
+<?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="92"
+   height="92"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
+   sodipodi:docname="red_king.svg">
+  <metadata
+     id="metadata12">
+    <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="defs10">
+    <filter
+       height="1.5"
+       width="1.5"
+       y="0"
+       x="0"
+       id="f1"
+       color-interpolation-filters="sRGB">
+      <feOffset
+         id="feOffset3039"
+         dy="0"
+         dx="1"
+         in="SourceAlpha"
+         result="offOut" />
+      <feGaussianBlur
+         id="feGaussianBlur3041"
+         stdDeviation="1"
+         in="offOut"
+         result="blurOut" />
+      <!--
+      <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
+-->
+    </filter>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad1">
+      <stop
+         id="stop3034"
+         style="stop-color:rgb(255,255,255);stop-opacity:0.6"
+         offset="20%" />
+      <stop
+         id="stop3036"
+         style="stop-color:rgb(220,0,0);stop-opacity:0.5"
+         offset="50%" />
+    </linearGradient>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad0">
+      <stop
+         id="stop3029"
+         style="stop-color:rgb(0,0,0);stop-opacity:0.3"
+         offset="20%" />
+      <stop
+         id="stop3031"
+         style="stop-color:rgb(0,0,0);stop-opacity:0.6"
+         offset="100%" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#grad1"
+       id="linearGradient3085"
+       x1="10.900002"
+       y1="4.9000015"
+       x2="10.900002"
+       y2="83.099998"
+       gradientUnits="userSpaceOnUse" />
+  </defs>
+  <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="namedview8"
+     showgrid="false"
+     inkscape:zoom="2.6222222"
+     inkscape:cx="-38.164201"
+     inkscape:cy="7.0328205"
+     inkscape:window-x="1912"
+     inkscape:window-y="-8"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="g13492"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <g
+     id="use4"
+     transform="translate(-4,2)">
+    <circle
+       style="opacity:0.5;fill:#000000;filter:url(#f1)"
+       cx="50"
+       cy="49.5"
+       r="39"
+       id="circle3075"
+       d="m 89,49.5 c 0,21.539105 -17.460895,39 -39,39 -21.539105,0 -39,-17.460895 -39,-39 0,-21.539105 17.460895,-39 39,-39 21.539105,0 39,17.460895 39,39 z"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="49.5"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:#ee2211"
+       cx="50"
+       cy="44"
+       r="39"
+       id="circle3077"
+       d="M 89,44 C 89,65.539105 71.539105,83 50,83 28.460895,83 11,65.539105 11,44 11,22.460895 28.460895,5 50,5 71.539105,5 89,22.460895 89,44 z"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:url(#linearGradient3085)"
+       cx="50"
+       cy="44"
+       r="39.099998"
+       id="circle3079"
+       d="M 89.099998,44 C 89.099998,65.594333 71.594333,83.099998 50,83.099998 28.405667,83.099998 10.900002,65.594333 10.900002,44 10.900002,22.405667 28.405667,4.9000015 50,4.9000015 71.594333,4.9000015 89.099998,22.405667 89.099998,44 z"
+       sodipodi:ry="39.099998"
+       sodipodi:rx="39.099998"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:none;stroke:#aa0000;stroke-width:1"
+       cx="50"
+       cy="44"
+       r="39.099998"
+       id="circle3081"
+       d="M 89.099998,44 C 89.099998,65.594333 71.594333,83.099998 50,83.099998 28.405667,83.099998 10.900002,65.594333 10.900002,44 10.900002,22.405667 28.405667,4.9000015 50,4.9000015 71.594333,4.9000015 89.099998,22.405667 89.099998,44 z"
+       sodipodi:ry="39.099998"
+       sodipodi:rx="39.099998"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:#ee2211"
+       cx="50"
+       cy="44"
+       r="33.5"
+       id="circle3083"
+       d="M 83.5,44 C 83.5,62.501539 68.501539,77.5 50,77.5 31.498461,77.5 16.5,62.501539 16.5,44 16.5,25.498461 31.498461,10.5 50,10.5 68.501539,10.5 83.5,25.498461 83.5,44 z"
+       sodipodi:ry="33.5"
+       sodipodi:rx="33.5"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+  </g>
+  <g
+     style="font-size:42px;font-weight:normal;text-anchor:middle;fill:#ffffff;stroke:#ffffff;stroke-width:1.25;font-family:'WenQuanYi Micro Hei, Arial'"
+     id="text6"
+     transform="translate(-4,2)" />
+  <g
+     id="g13492"
+     transform="matrix(1.1266215,0,0,1.1266215,-12.194886,-11.017266)">
+    <g
+       id="g14133"
+       transform="matrix(0.89999999,0,0,0.89999999,5.4085058,4.9618441)">
+      <path
+         style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.15365481;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         d="m 51.359744,64.137284 c -4.337713,-0.10611 -8.805939,0.1336 -14.547379,-0.39363 -3.058483,-4.3653 -7.669835,-20.160519 -6.59342,-27.568229 8.133658,-4.95419 36.964481,-6.25835 41.572966,0.16499 1.076415,7.4077 -2.923901,22.915189 -5.982386,27.280479"
+         id="path7039-4"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="ccccc" />
+      <path
+         style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.624152;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         d="m 36.812365,63.358694 c -0.04975,3.77127 0.586986,6.81989 1.603673,10.59116 4.677097,2.07938 8.290066,2.31232 12.581636,2.41134 4.291572,-0.0795 9.098353,-0.71692 13.005531,-2.52132 1.016687,-3.77127 1.877469,-6.70991 1.827718,-10.48118 l -14.483816,0.49591 z"
+         id="path7043-9"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="ccccccc" />
+      <path
+         style="display:inline;fill:none;stroke:#ee2211;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         d="m 36.152435,64.820494 c 10.116218,-2.68441 21.010358,-2.6855 30.279356,0.055"
+         id="path7068-2"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cc" />
+      <path
+         style="display:inline;fill:none;stroke:#ee2211;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         d="M 55.628615,42.156505 53.3517,53.941154"
+         id="path7088-8"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cc" />
+      <path
+         sodipodi:nodetypes="cc"
+         inkscape:connector-curvature="0"
+         id="path7090-7"
+         d="m 47.005327,42.754975 1.715994,10.872389"
+         style="display:inline;fill:none;stroke:#ee2211;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+      <path
+         style="display:inline;fill:none;stroke:#ee2211;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         d="m 37.477824,73.419214 c 10.635287,-2.46469 19.543529,-1.70899 27.242793,-0.2198"
+         id="path7096-3"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cc" />
+      <ellipse
+         ry="2.5287778"
+         rx="2.4187896"
+         style="display:inline;opacity:1;fill:#ee2211;fill-opacity:1;stroke:#ee2211;stroke-width:0.96514052;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
+         id="path7098-0"
+         cx="51.023945"
+         cy="67.205116" />
+      <path
+         style="display:inline;fill:none;stroke:#ee2211;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         d="m 29.883219,35.881575 c 3.031645,8.87729 6.222505,6.09111 6.910112,7.23293 0.798314,2.55026 4.120375,19.604439 4.120375,19.604439 l 0.164982,0.82491"
+         id="path8714-5"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cccc" />
+      <path
+         sodipodi:nodetypes="cccc"
+         inkscape:connector-curvature="0"
+         id="path8716-9"
+         d="m 72.201896,35.570485 c -3.031645,8.87729 -5.522544,6.01334 -6.210152,7.15515 -0.798314,2.55026 -4.820335,19.682209 -4.820335,19.682209 l -0.164982,0.82491"
+         style="display:inline;fill:none;stroke:#ee2211;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+      <path
+         style="display:inline;fill:none;stroke:#ee2211;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         d="m 36.808619,42.970585 c 5.355804,-5.07573 7.816328,-1.15585 10.503881,-0.32996 2.151414,-1.93708 4.337824,-4.08726 8.4727,-0.24195 2.914409,-2.83934 7.470518,-2.8371 10.2803,0.24195"
+         id="path8718-6"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cccc" />
+      <path
+         style="display:inline;fill:none;stroke:#ee2211;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         d="m 42.596868,62.901714 c 0.329506,-2.36495 -0.59859,-6.18345 4.970044,-7.0772 1.838323,-4.4565 4.858416,-4.7748 7.115771,0 2.925394,1.34592 4.570542,0.65162 4.807702,7.04488"
+         id="path8722-9"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cccc" />
+      <path
+         style="display:inline;fill:none;stroke:#ee2211;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         d="m 28.636349,39.736975 c 0.453129,1.38959 1.885764,5.10389 3.477975,4.08568 0.817175,1.59851 1.706522,1.97032 2.736363,1.08377 -0.81768,1.34753 -0.863608,2.50192 0.604935,3.40964 -0.186761,1.75485 -0.585476,3.103729 0.9349,4.289539 -0.533899,2.11747 -0.187173,3.05934 0.962398,4.15206 -0.757651,1.24616 -0.523948,3.26969 0.907403,3.93208 -0.285562,1.18136 -0.829693,2.57144 1.814806,2.8322"
+         id="path8751-3"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cccccccc" />
+      <path
+         sodipodi:nodetypes="cccccccc"
+         inkscape:connector-curvature="0"
+         id="path8754-2"
+         d="m 74.132165,39.637885 c -0.453129,1.38958 -1.885764,5.10388 -3.477975,4.08567 -0.817175,1.59852 -1.706522,1.97032 -2.736363,1.08378 0.81768,1.34752 0.863608,2.50191 -0.604935,3.40963 0.186761,1.75485 0.585476,3.103739 -0.9349,4.289549 0.533899,2.11747 0.187173,3.05933 -0.962398,4.15205 0.757651,1.24617 0.523948,3.26969 -0.907403,3.93208 0.285562,1.18136 0.829693,2.57145 -1.814806,2.8322"
+         style="display:inline;fill:none;stroke:#ee2211;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+      <path
+         style="display:inline;fill:none;stroke:#ee2211;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         d="m 38.347182,72.757924 3.033165,-5.36637 2.955391,4.23866 2.243636,-4.36199 2.394466,4.25907"
+         id="path8756-6"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="ccccc" />
+      <path
+         sodipodi:nodetypes="ccccc"
+         inkscape:connector-curvature="0"
+         id="path8759-3"
+         d="m 38.036089,70.138324 c -4.001746,6.97033 2.190618,-3.38314 3.227598,-5.32748 l 2.828116,3.88163 2.538252,-4.23161 2.085326,3.85214"
+         style="display:inline;fill:none;stroke:#ee2211;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+      <path
+         sodipodi:nodetypes="ccccc"
+         inkscape:connector-curvature="0"
+         id="path8761-9"
+         d="m 63.996206,72.627584 -2.856388,-5.18959 -2.867003,4.06188 -2.449865,-4.47197 -2.683184,4.35531"
+         style="display:inline;fill:none;stroke:#ee2211;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+      <path
+         style="display:inline;fill:none;stroke:#ee2211;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         d="m 64.572465,70.138324 c 4.001745,6.97033 -2.307279,-3.30537 -3.344259,-5.24971 l -2.799844,3.80386 -2.449864,-4.23161 -2.649015,3.8109"
+         id="path8763-1"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="ccccc" />
+    </g>
+  </g>
+</svg>
diff --git a/client/public/images/pieces/Xiangqi/wn.svg b/client/public/images/pieces/Xiangqi/wn.svg
new file mode 100644
index 00000000..dd2de955
--- /dev/null
+++ b/client/public/images/pieces/Xiangqi/wn.svg
@@ -0,0 +1,285 @@
+<?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="92"
+   height="92"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
+   sodipodi:docname="red_horse.svg">
+  <metadata
+     id="metadata12">
+    <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="defs10">
+    <filter
+       height="1.5"
+       width="1.5"
+       y="0"
+       x="0"
+       id="f1"
+       color-interpolation-filters="sRGB">
+      <feOffset
+         id="feOffset3039"
+         dy="0"
+         dx="1"
+         in="SourceAlpha"
+         result="offOut" />
+      <feGaussianBlur
+         id="feGaussianBlur3041"
+         stdDeviation="1"
+         in="offOut"
+         result="blurOut" />
+      <!--
+      <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
+-->
+    </filter>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad1">
+      <stop
+         id="stop3034"
+         style="stop-color:rgb(255,255,255);stop-opacity:0.6"
+         offset="20%" />
+      <stop
+         id="stop3036"
+         style="stop-color:rgb(220,0,0);stop-opacity:0.5"
+         offset="50%" />
+    </linearGradient>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad0">
+      <stop
+         id="stop3029"
+         style="stop-color:rgb(0,0,0);stop-opacity:0.3"
+         offset="20%" />
+      <stop
+         id="stop3031"
+         style="stop-color:rgb(0,0,0);stop-opacity:0.6"
+         offset="100%" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#grad1"
+       id="linearGradient3085"
+       x1="10.900002"
+       y1="4.9000015"
+       x2="10.900002"
+       y2="83.099998"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="linearGradient11421">
+      <stop
+         id="stop11417"
+         style="stop-color:#c83737;stop-opacity:1"
+         offset="20%" />
+      <stop
+         id="stop11419"
+         style="stop-color:#de8787;stop-opacity:1"
+         offset="100%" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient5398"
+       x1="0"
+       y1="0"
+       x2="0"
+       y2="1">
+      <stop
+         offset="20%"
+         style="stop-color:#c83737;stop-opacity:1"
+         id="stop5394" />
+      <stop
+         offset="100%"
+         style="stop-color:#cf8080;stop-opacity:1"
+         id="stop5396" />
+    </linearGradient>
+    <filter
+       style="color-interpolation-filters:sRGB"
+       height="1.5"
+       width="1.5"
+       y="0"
+       x="0"
+       id="f1-4">
+      <feOffset
+         id="feOffset3039-4"
+         dy="0"
+         dx="1"
+         in="SourceAlpha"
+         result="offOut" />
+      <feGaussianBlur
+         id="feGaussianBlur3041-4"
+         stdDeviation="1"
+         in="offOut"
+         result="blurOut" />
+      <!--
+      <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
+-->
+    </filter>
+  </defs>
+  <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="namedview8"
+     showgrid="false"
+     inkscape:zoom="0.92709555"
+     inkscape:cx="-18.698056"
+     inkscape:cy="280.1"
+     inkscape:window-x="2872"
+     inkscape:window-y="-8"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <g
+     id="use4"
+     transform="translate(-4,2)">
+    <circle
+       style="opacity:0.5;fill:#000000;filter:url(#f1)"
+       cx="50"
+       cy="49.5"
+       r="39"
+       id="circle3075"
+       d="m 89,49.5 c 0,21.539105 -17.460895,39 -39,39 -21.539105,0 -39,-17.460895 -39,-39 0,-21.539105 17.460895,-39 39,-39 21.539105,0 39,17.460895 39,39 z"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="49.5"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:#ee2211"
+       cx="50"
+       cy="44"
+       r="39"
+       id="circle3077"
+       d="M 89,44 C 89,65.539105 71.539105,83 50,83 28.460895,83 11,65.539105 11,44 11,22.460895 28.460895,5 50,5 71.539105,5 89,22.460895 89,44 z"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:url(#linearGradient3085)"
+       cx="50"
+       cy="44"
+       r="39.099998"
+       id="circle3079"
+       d="M 89.099998,44 C 89.099998,65.594333 71.594333,83.099998 50,83.099998 28.405667,83.099998 10.900002,65.594333 10.900002,44 10.900002,22.405667 28.405667,4.9000015 50,4.9000015 71.594333,4.9000015 89.099998,22.405667 89.099998,44 z"
+       sodipodi:ry="39.099998"
+       sodipodi:rx="39.099998"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:none;stroke:#aa0000;stroke-width:1"
+       cx="50"
+       cy="44"
+       r="39.099998"
+       id="circle3081"
+       d="M 89.099998,44 C 89.099998,65.594333 71.594333,83.099998 50,83.099998 28.405667,83.099998 10.900002,65.594333 10.900002,44 10.900002,22.405667 28.405667,4.9000015 50,4.9000015 71.594333,4.9000015 89.099998,22.405667 89.099998,44 z"
+       sodipodi:ry="39.099998"
+       sodipodi:rx="39.099998"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:#ee2211"
+       cx="50"
+       cy="44"
+       r="33.5"
+       id="circle3083"
+       d="M 83.5,44 C 83.5,62.501539 68.501539,77.5 50,77.5 31.498461,77.5 16.5,62.501539 16.5,44 16.5,25.498461 31.498461,10.5 50,10.5 68.501539,10.5 83.5,25.498461 83.5,44 z"
+       sodipodi:ry="33.5"
+       sodipodi:rx="33.5"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+  </g>
+  <g
+     style="font-size:42px;font-weight:normal;text-anchor:middle;fill:#ffffff;stroke:#ffffff;stroke-width:1.25;font-family:'WenQuanYi Micro Hei, Arial'"
+     id="text6"
+     transform="translate(-4,2)" />
+  <g
+     style="display:inline"
+     id="g10283"
+     transform="matrix(0.96565541,0,0,0.96565541,124.54484,2.823745)">
+    <g
+       transform="matrix(1.6119947,0,0,1.6119947,-51.297818,-45.558668)"
+       id="g4496"
+       style="display:inline">
+      <path
+         style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.19975252;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         d="m -20.363965,43.589358 c -0.0276,-1.46313 -0.713126,-2.145608 -1.299776,-3.329198 -0.571744,1.388345 -1.389781,2.98152 -1.051241,4.192856 -0.64554,-0.302018 -1.29108,0.196403 -1.93662,0.50794 -4.172427,6.925057 -3.872501,6.543133 -7.74648,9.703329 -0.41274,1.0845 -0.66256,1.961621 0.0587,3.579812 0.36665,0.484202 2.0734,1.323734 3.37442,1.496479 0.37959,0.533363 0.0389,0.715844 0.0293,0.850939 0.57883,0.586855 0.84987,0.352113 1.46713,0.528169 1.64825,-1.771306 3.2607,-3.327849 4.75353,-4.166667 1.95618,-0.980405 3.91236,-0.564172 5.86854,-0.704225 1.456321,0.21705 2.389217,-0.81096 2.481038,-0.822807 -0.7034,1.107585 -1.211128,2.439303 -3.126578,3.698394 -1.18159,-0.284668 -1.84361,-0.179659 -2.4061,0 -4.23123,3.229653 -5.76905,8.997115 -5.75117,11.326292 5.708582,2.230783 11.7045,1.157214 17.7229999,-0.176057 -1.599,-1.233028 -1.55432,-2.671516 -1.9953,-4.049296 -0.3933899,-3.368319 0.386688,-3.431093 0.88028,-6.57277 0.34933,-6.266657 -0.432697,-11.619231 -5.5252069,-14.931742 -0.91599,-0.402395 -2.781791,-0.345578 -3.748111,-0.295054 0.0658,-1.508632 -0.62168,-2.655508 -0.98402,-4.021428 -0.008,-0.0078 -1.465491,2.090218 -1.163721,2.744109 -0.07401,0.08009 0.206841,0.429509 0.09838,0.440925 z"
+         id="path4426"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cccccccccccccccccccccccc" />
+      <path
+         style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.09243207;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         d="m -19.406506,41.091703 c 14.3383277,-1.44366 14.6623349,12.941854 12.9102306,22.786351 -0.3727255,2.094222 0.5431423,3.922119 0.4131333,5.516454 -4.3778739,-1.27574 -3.261783,-4.989674 -2.1272975,-9.89572 0.1816486,-7.188013 -0.4354701,-13.936194 -8.2870824,-15.80692 -0.538977,-0.05014 -1.697034,0.233285 -2.238074,0.223765 -1.184158,0.0502 -0.854474,-2.06219 -0.67091,-2.823934 z"
+         id="path4428"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cscccccc" />
+      <ellipse
+         style="opacity:1;fill:#ee2211;fill-opacity:1;stroke:#ee2211;stroke-width:0.09785748;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
+         id="path4461"
+         cx="-22.465561"
+         cy="49.837406"
+         rx="0.96838528"
+         ry="1.0133952" />
+      <path
+         style="fill:#ee2211;fill-opacity:1;stroke:#ee2211;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m -24.006062,50.908416 c 1.03577,-0.831732 -0.63174,-2.617565 3.11033,-2.494132"
+         id="path4463"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cc" />
+      <path
+         style="fill:#ee2211;fill-opacity:1;stroke:#ee2211;stroke-width:0.93052417;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         d="m -29.234621,60.161919 c 0.95231,-0.642849 1.758922,-1.427453 2.394037,-2.268554"
+         id="path4489"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cc" />
+    </g>
+    <path
+       sodipodi:nodetypes="cccsc"
+       inkscape:connector-curvature="0"
+       id="path5410"
+       d="m -102.89655,45.661554 c -0.18838,1.060968 0.035,1.786052 0.60673,2.494349 0.8387,0.540409 1.66987,1.091355 2.662885,1.415711 0,0 0.554672,-0.395936 0.432413,-0.412667 -1.076438,-0.14731 -2.933168,-0.973326 -3.702028,-3.497393 z"
+       style="display:inline;fill:#ee2211;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       sodipodi:nodetypes="ccccscc"
+       inkscape:connector-curvature="0"
+       id="path5412"
+       d="m -100.49552,45.624567 c -0.36265,0.193491 -0.6895,0.422791 -0.73888,0.929555 0.21409,0.310494 0.55658,0.428382 1.0249,0.357521 0.314135,-0.297622 0.655486,-0.56803 0.786545,-1.048729 0,0 -0.619705,-1.191737 -0.619705,-1.048729 0,0.143009 0.0238,0.786547 0.0238,0.786547 z"
+       style="display:inline;fill:#ee2211;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+  </g>
+</svg>
diff --git a/client/public/images/pieces/Xiangqi/wp.svg b/client/public/images/pieces/Xiangqi/wp.svg
new file mode 100644
index 00000000..4abd3a56
--- /dev/null
+++ b/client/public/images/pieces/Xiangqi/wp.svg
@@ -0,0 +1,271 @@
+<?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="92"
+   height="92"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
+   sodipodi:docname="red_pawn.svg">
+  <metadata
+     id="metadata12">
+    <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>
+  <defs
+     id="defs10">
+    <filter
+       height="1.5"
+       width="1.5"
+       y="0"
+       x="0"
+       id="f1"
+       color-interpolation-filters="sRGB">
+      <feOffset
+         id="feOffset3039"
+         dy="0"
+         dx="1"
+         in="SourceAlpha"
+         result="offOut" />
+      <feGaussianBlur
+         id="feGaussianBlur3041"
+         stdDeviation="1"
+         in="offOut"
+         result="blurOut" />
+      <!--
+      <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
+-->
+    </filter>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad1">
+      <stop
+         id="stop3034"
+         style="stop-color:rgb(255,255,255);stop-opacity:0.6"
+         offset="20%" />
+      <stop
+         id="stop3036"
+         style="stop-color:rgb(220,0,0);stop-opacity:0.5"
+         offset="50%" />
+    </linearGradient>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad0">
+      <stop
+         id="stop3029"
+         style="stop-color:rgb(0,0,0);stop-opacity:0.3"
+         offset="20%" />
+      <stop
+         id="stop3031"
+         style="stop-color:rgb(0,0,0);stop-opacity:0.6"
+         offset="100%" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#grad1"
+       id="linearGradient3085"
+       x1="10.900002"
+       y1="4.9000015"
+       x2="10.900002"
+       y2="83.099998"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="linearGradient11421">
+      <stop
+         id="stop11417"
+         style="stop-color:#c83737;stop-opacity:1"
+         offset="20%" />
+      <stop
+         id="stop11419"
+         style="stop-color:#de8787;stop-opacity:1"
+         offset="100%" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient5398"
+       x1="0"
+       y1="0"
+       x2="0"
+       y2="1">
+      <stop
+         offset="20%"
+         style="stop-color:#c83737;stop-opacity:1"
+         id="stop5394" />
+      <stop
+         offset="100%"
+         style="stop-color:#cf8080;stop-opacity:1"
+         id="stop5396" />
+    </linearGradient>
+    <filter
+       style="color-interpolation-filters:sRGB"
+       height="1.5"
+       width="1.5"
+       y="0"
+       x="0"
+       id="f1-4">
+      <feOffset
+         id="feOffset3039-4"
+         dy="0"
+         dx="1"
+         in="SourceAlpha"
+         result="offOut" />
+      <feGaussianBlur
+         id="feGaussianBlur3041-4"
+         stdDeviation="1"
+         in="offOut"
+         result="blurOut" />
+      <!--
+      <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
+-->
+    </filter>
+  </defs>
+  <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="namedview8"
+     showgrid="false"
+     inkscape:zoom="3.7083822"
+     inkscape:cx="39.000686"
+     inkscape:cy="39.643836"
+     inkscape:window-x="2872"
+     inkscape:window-y="-8"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <g
+     id="use4"
+     transform="translate(-4,2)">
+    <circle
+       style="opacity:0.5;fill:#000000;filter:url(#f1)"
+       cx="50"
+       cy="49.5"
+       r="39"
+       id="circle3075"
+       d="m 89,49.5 c 0,21.539105 -17.460895,39 -39,39 -21.539105,0 -39,-17.460895 -39,-39 0,-21.539105 17.460895,-39 39,-39 21.539105,0 39,17.460895 39,39 z"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="49.5"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:#ee2211"
+       cx="50"
+       cy="44"
+       r="39"
+       id="circle3077"
+       d="M 89,44 C 89,65.539105 71.539105,83 50,83 28.460895,83 11,65.539105 11,44 11,22.460895 28.460895,5 50,5 71.539105,5 89,22.460895 89,44 z"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:url(#linearGradient3085)"
+       cx="50"
+       cy="44"
+       r="39.099998"
+       id="circle3079"
+       d="M 89.099998,44 C 89.099998,65.594333 71.594333,83.099998 50,83.099998 28.405667,83.099998 10.900002,65.594333 10.900002,44 10.900002,22.405667 28.405667,4.9000015 50,4.9000015 71.594333,4.9000015 89.099998,22.405667 89.099998,44 z"
+       sodipodi:ry="39.099998"
+       sodipodi:rx="39.099998"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:none;stroke:#aa0000;stroke-width:1"
+       cx="50"
+       cy="44"
+       r="39.099998"
+       id="circle3081"
+       d="M 89.099998,44 C 89.099998,65.594333 71.594333,83.099998 50,83.099998 28.405667,83.099998 10.900002,65.594333 10.900002,44 10.900002,22.405667 28.405667,4.9000015 50,4.9000015 71.594333,4.9000015 89.099998,22.405667 89.099998,44 z"
+       sodipodi:ry="39.099998"
+       sodipodi:rx="39.099998"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:#ee2211"
+       cx="50"
+       cy="44"
+       r="33.5"
+       id="circle3083"
+       d="M 83.5,44 C 83.5,62.501539 68.501539,77.5 50,77.5 31.498461,77.5 16.5,62.501539 16.5,44 16.5,25.498461 31.498461,10.5 50,10.5 68.501539,10.5 83.5,25.498461 83.5,44 z"
+       sodipodi:ry="33.5"
+       sodipodi:rx="33.5"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+  </g>
+  <g
+     style="font-size:42px;font-weight:normal;text-anchor:middle;fill:#ffffff;stroke:#ffffff;stroke-width:1.25;font-family:'WenQuanYi Micro Hei, Arial'"
+     id="text6"
+     transform="translate(-4,2)" />
+  <g
+     transform="translate(0.02103906,1.7456904)"
+     style="display:inline;fill:#ffffff;stroke:#ffffff"
+     id="g9866">
+    <g
+       style="display:inline;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.31294143;stroke-miterlimit:4;stroke-dasharray:none;paint-order:stroke fill markers"
+       transform="matrix(0.73170801,0,0,0.89061254,62.585414,-13.581686)"
+       id="g2182-3">
+      <g
+         style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.31294143;stroke-miterlimit:4;stroke-dasharray:none"
+         id="g2180-9"
+         transform="translate(0.4695196,-1.5015006)">
+        <path
+           style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.31294143;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
+           d="m -22.715841,41.496901 c -6.709808,7.383569 -10.663816,12.802391 -14.029253,18.972935 9.833495,-1.692893 19.278926,-2.323037 27.646001,0 -2.69856,-4.464975 -7.002481,-10.253202 -13.616748,-18.972935 z"
+           id="path2176-6"
+           inkscape:connector-curvature="0"
+           sodipodi:nodetypes="cccc" />
+        <path
+           sodipodi:nodetypes="cccccccc"
+           inkscape:connector-curvature="0"
+           id="path2178-9"
+           d="m -26.817667,60.896469 c 1.31085,8.861829 -3.645845,14.386908 -11.545204,19.081976 -5.236973,2.010186 -7.708873,4.499726 -7.614698,9.332185 12.369865,3.211336 31.696805,2.290793 45.67493078,-0.116941 -0.002369,-3.821858 -2.08387088,-9.351048 -7.28998228,-9.958106 -10.3223275,-4.971535 -10.9033515,-10.063579 -11.0201045,-18.30082 -3.173543,-0.438952 -5.925438,-0.207767 -8.204942,-0.03829 z"
+           style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.31294143;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
+      </g>
+    </g>
+    <path
+       sodipodi:nodetypes="ccccc"
+       inkscape:connector-curvature="0"
+       id="path6140"
+       d="m 37.364676,36.197364 -1.389805,2.974841 2.603272,-0.615322 c -0.516847,-0.05328 -1.134816,0.02931 -1.651663,-0.18539 -0.03118,-0.693179 0.308827,-1.521087 0.438196,-2.174129 z"
+       style="fill:#ffffff;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       sodipodi:nodetypes="cccccc"
+       inkscape:connector-curvature="0"
+       id="path6146"
+       d="m 42.066862,48.315182 c -0.970796,1.874384 -4.188748,6.060346 -7.208317,7.995683 -3.889337,1.575798 -5.791152,4.885757 -5.571735,8.311361 l 0.881332,0.37813 c -0.117629,-2.366189 0.54481,-4.864987 2.662886,-6.640362 3.833557,-2.202021 8.236266,-5.603108 9.235834,-10.044812 z"
+       style="fill:#ffffff;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+  </g>
+</svg>
diff --git a/client/public/images/pieces/Xiangqi/wr.svg b/client/public/images/pieces/Xiangqi/wr.svg
new file mode 100644
index 00000000..974a5c24
--- /dev/null
+++ b/client/public/images/pieces/Xiangqi/wr.svg
@@ -0,0 +1,353 @@
+<?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="92"
+   height="92"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
+   sodipodi:docname="red_chariot.svg">
+  <metadata
+     id="metadata12">
+    <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="defs10">
+    <filter
+       height="1.5"
+       width="1.5"
+       y="0"
+       x="0"
+       id="f1"
+       color-interpolation-filters="sRGB">
+      <feOffset
+         id="feOffset3039"
+         dy="0"
+         dx="1"
+         in="SourceAlpha"
+         result="offOut" />
+      <feGaussianBlur
+         id="feGaussianBlur3041"
+         stdDeviation="1"
+         in="offOut"
+         result="blurOut" />
+      <!--
+      <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
+-->
+    </filter>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad1">
+      <stop
+         id="stop3034"
+         style="stop-color:rgb(255,255,255);stop-opacity:0.6"
+         offset="20%" />
+      <stop
+         id="stop3036"
+         style="stop-color:rgb(220,0,0);stop-opacity:0.5"
+         offset="50%" />
+    </linearGradient>
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="grad0">
+      <stop
+         id="stop3029"
+         style="stop-color:rgb(0,0,0);stop-opacity:0.3"
+         offset="20%" />
+      <stop
+         id="stop3031"
+         style="stop-color:rgb(0,0,0);stop-opacity:0.6"
+         offset="100%" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#grad1"
+       id="linearGradient3085"
+       x1="10.900002"
+       y1="4.9000015"
+       x2="10.900002"
+       y2="83.099998"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       y2="1"
+       x2="0"
+       y1="0"
+       x1="0"
+       id="linearGradient11421">
+      <stop
+         id="stop11417"
+         style="stop-color:#c83737;stop-opacity:1"
+         offset="20%" />
+      <stop
+         id="stop11419"
+         style="stop-color:#de8787;stop-opacity:1"
+         offset="100%" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient5398"
+       x1="0"
+       y1="0"
+       x2="0"
+       y2="1">
+      <stop
+         offset="20%"
+         style="stop-color:#c83737;stop-opacity:1"
+         id="stop5394" />
+      <stop
+         offset="100%"
+         style="stop-color:#cf8080;stop-opacity:1"
+         id="stop5396" />
+    </linearGradient>
+    <filter
+       style="color-interpolation-filters:sRGB"
+       height="1.5"
+       width="1.5"
+       y="0"
+       x="0"
+       id="f1-4">
+      <feOffset
+         id="feOffset3039-4"
+         dy="0"
+         dx="1"
+         in="SourceAlpha"
+         result="offOut" />
+      <feGaussianBlur
+         id="feGaussianBlur3041-4"
+         stdDeviation="1"
+         in="offOut"
+         result="blurOut" />
+      <!--
+      <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
+-->
+    </filter>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5290"
+       id="linearGradient5306"
+       gradientUnits="userSpaceOnUse"
+       x1="22.018419"
+       y1="47.282806"
+       x2="75.110641"
+       y2="47.282806" />
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient5290">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop5286" />
+      <stop
+         style="stop-color:#4d4d4d;stop-opacity:1"
+         offset="1"
+         id="stop5288" />
+    </linearGradient>
+  </defs>
+  <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="namedview8"
+     showgrid="false"
+     inkscape:zoom="1.3111111"
+     inkscape:cx="-58.671317"
+     inkscape:cy="44.012072"
+     inkscape:window-x="2872"
+     inkscape:window-y="-8"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="g18015"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <g
+     id="use4"
+     transform="translate(-4,2)">
+    <circle
+       style="opacity:0.5;fill:#000000;filter:url(#f1)"
+       cx="50"
+       cy="49.5"
+       r="39"
+       id="circle3075"
+       d="m 89,49.5 c 0,21.539105 -17.460895,39 -39,39 -21.539105,0 -39,-17.460895 -39,-39 0,-21.539105 17.460895,-39 39,-39 21.539105,0 39,17.460895 39,39 z"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="49.5"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:#ee2211"
+       cx="50"
+       cy="44"
+       r="39"
+       id="circle3077"
+       d="M 89,44 C 89,65.539105 71.539105,83 50,83 28.460895,83 11,65.539105 11,44 11,22.460895 28.460895,5 50,5 71.539105,5 89,22.460895 89,44 z"
+       sodipodi:ry="39"
+       sodipodi:rx="39"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:url(#linearGradient3085)"
+       cx="50"
+       cy="44"
+       r="39.099998"
+       id="circle3079"
+       d="M 89.099998,44 C 89.099998,65.594333 71.594333,83.099998 50,83.099998 28.405667,83.099998 10.900002,65.594333 10.900002,44 10.900002,22.405667 28.405667,4.9000015 50,4.9000015 71.594333,4.9000015 89.099998,22.405667 89.099998,44 z"
+       sodipodi:ry="39.099998"
+       sodipodi:rx="39.099998"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:none;stroke:#aa0000;stroke-width:1"
+       cx="50"
+       cy="44"
+       r="39.099998"
+       id="circle3081"
+       d="M 89.099998,44 C 89.099998,65.594333 71.594333,83.099998 50,83.099998 28.405667,83.099998 10.900002,65.594333 10.900002,44 10.900002,22.405667 28.405667,4.9000015 50,4.9000015 71.594333,4.9000015 89.099998,22.405667 89.099998,44 z"
+       sodipodi:ry="39.099998"
+       sodipodi:rx="39.099998"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+    <circle
+       style="fill:#ee2211"
+       cx="50"
+       cy="44"
+       r="33.5"
+       id="circle3083"
+       d="M 83.5,44 C 83.5,62.501539 68.501539,77.5 50,77.5 31.498461,77.5 16.5,62.501539 16.5,44 16.5,25.498461 31.498461,10.5 50,10.5 68.501539,10.5 83.5,25.498461 83.5,44 z"
+       sodipodi:ry="33.5"
+       sodipodi:rx="33.5"
+       sodipodi:cy="44"
+       sodipodi:cx="50" />
+  </g>
+  <g
+     style="font-size:42px;font-weight:normal;text-anchor:middle;fill:#ffffff;stroke:#ffffff;stroke-width:1.25;font-family:'WenQuanYi Micro Hei, Arial'"
+     id="text6"
+     transform="translate(-4,2)" />
+  <g
+     transform="translate(4.4814075e-7,-1.1440677)"
+     style="display:inline"
+     id="g18015">
+    <g
+       id="g18181"
+       transform="translate(0,2.3349016)">
+      <path
+         style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m 24.659465,26.904975 c 12.079888,0.82929 16.235222,0.778634 20.790704,0.762712 l -0.115084,18.315683 1.15722,-0.03443 0.229866,-18.28125 C 59.504821,27.7557 65.492444,27.481526 69.355506,26.904978 53.15633,21.719733 37.356437,21.6211 24.659465,26.904975 Z"
+         id="path5517"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="ccccccc" />
+      <path
+         inkscape:connector-curvature="0"
+         style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.12982513;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
+         d="M 50.044649,37.78537 A 16.761462,16.761462 0 0 1 66.805279,54.545996 16.761462,16.761462 0 0 1 50.044649,71.309166 16.761462,16.761462 0 0 1 33.281485,54.545996 16.761462,16.761462 0 0 1 50.044649,37.78537 Z m 0,2.515362 a 14.247242,14.247242 0 0 0 -14.247802,14.245264 14.247242,14.247242 0 0 0 14.247802,14.2478 14.247242,14.247242 0 0 0 14.2478,-14.2478 14.247242,14.247242 0 0 0 -14.2478,-14.245264 z"
+         id="path5173" />
+      <path
+         style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.29825127px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="M 30.340966,50.544723 C 29.240607,48.961402 28.288371,46.424541 27.319045,44.57917 l -4.114171,-0.07619 c -0.572036,0.863469 -0.801476,1.726938 -0.228571,2.590407 l 3.047542,0.228566 c 0.679011,2.273621 1.630084,4.00315 2.590413,5.714133 l 4.508653,0.16831 c 0.108315,-1.15859 -0.02335,-0.80349 0.360831,-2.611896 -1.235017,0.05123 -1.925316,0.02215 -3.142776,-0.04778 z"
+         id="path5176"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cccccccccc" />
+      <path
+         style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.29825127px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m 64.677261,28.842398 c 0.03917,5.884009 0.265917,11.78969 0.115055,16.956669 -4.797619,-5.826791 -6.000532,-6.87719 -14.110332,-8.400876 0.266048,-2.019106 5.124498,-8.160352 8.096482,-8.825452 z"
+         id="path5178"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="ccccc" />
+      <path
+         style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m 64.670174,53.149166 c -0.21864,-1.896417 -1.639002,-5.533526 -3.730067,-8.463135 -2.31979,-3.250055 -8.120538,-4.6395 -10.524676,-4.587544 -1.072241,2.513709 -2.372868,5.80951 -10.146798,6.630961 0,0.631156 -0.06417,3.053966 -0.07197,4.001862 -1.007086,0.06729 -2.60815,0.118058 -3.694251,0.04705 -0.198372,0.686616 -0.359385,2.050886 -0.327775,2.418476 9.184798,0.18599 19.417583,0.025 28.495537,-0.0477 z"
+         id="path5248"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="csccccccc" />
+      <path
+         style="display:inline;fill:#ee2211;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m 41.764847,47.194434 -0.905721,0.04767 v 3.146187 l 0.619704,-0.572034 z"
+         id="path5414"
+         inkscape:connector-curvature="0" />
+      <path
+         style="display:inline;fill:#ee2211;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m 50.86972,40.330027 c -0.179509,1.048729 -0.909708,2.097458 -1.716102,3.146187 0.930784,-0.834786 1.629443,-1.620091 2.441718,-3.165932 z"
+         id="path5416"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cccc" />
+      <path
+         style="display:inline;fill:#ee2211;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="m 51.402262,37.11403 c 0.282885,-1.227948 2.298384,-3.281929 3.185678,-4.268113 -0.482432,1.120674 -2.342435,3.234241 -2.235675,4.472754 z"
+         id="path5418"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cccc" />
+      <path
+         style="display:inline;fill:none;stroke:#ee2211;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         d="M 50.631372,52.897426 57.151519,41.40668"
+         id="path5420"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cc" />
+      <path
+         style="display:inline;fill:#000000;stroke:#ee2211;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         d="M 49.747793,52.962446 49.612964,40.687669"
+         id="path5437"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cc" />
+      <path
+         sodipodi:type="star"
+         style="display:inline;opacity:1;fill:url(#linearGradient5306);fill-opacity:1;stroke:#ffffff;stroke-width:0.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
+         id="path5165"
+         sodipodi:sides="12"
+         sodipodi:cx="198.1891"
+         sodipodi:cy="38.199802"
+         sodipodi:r1="10.981865"
+         sodipodi:r2="0.10981865"
+         sodipodi:arg1="0.82281385"
+         sodipodi:arg2="1.0846132"
+         inkscape:flatsided="false"
+         inkscape:rounded="0"
+         inkscape:randomized="0"
+         d="m 205.65854,46.250197 -7.41812,-7.953301 2.39221,10.609472 -2.44764,-10.596824 -3.23301,10.384179 3.17869,-10.400935 -7.99196,7.376453 7.9533,-7.418125 -10.60947,2.392212 10.59682,-2.447634 -10.38418,-3.233019 10.40094,3.178699 -7.37646,-7.991966 7.41813,7.953301 -2.39221,-10.609472 2.44763,10.596824 3.23302,-10.384179 -3.1787,10.400935 7.99197,-7.376453 -7.9533,7.418125 10.60947,-2.392213 -10.59683,2.447634 10.38418,3.233019 -10.40093,-3.178698 z"
+         transform="matrix(-1.3208656,0.32230963,0.32230963,1.3208656,299.72684,-59.778699)" />
+      <path
+         style="display:inline;fill:none;stroke:#ee2211;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         d="m 51.490574,53.331596 11.393108,-6.84261"
+         id="path5471"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cc" />
+      <path
+         style="display:inline;fill:none;stroke:#ee2211;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         d="M 49.008493,53.363606 44.715382,45.91596 v 0.06741"
+         id="path5473"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="ccc" />
+      <path
+         style="display:inline;fill:none;stroke:#ee2211;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         d="M 47.243438,53.331596 39.692976,49.151872"
+         id="path5475"
+         inkscape:connector-curvature="0" />
+    </g>
+  </g>
+</svg>
diff --git a/client/public/variants/Xiangqi/Boards.png b/client/public/variants/Xiangqi/Boards.png
new file mode 100644
index 00000000..6d2fa666
--- /dev/null
+++ b/client/public/variants/Xiangqi/Boards.png
@@ -0,0 +1 @@
+#$# git-fat 3028274bc0082cf1a376c0dee26caed0b5d64feb               763485
diff --git a/client/public/variants/Xiangqi/ElephantDiagram.png b/client/public/variants/Xiangqi/ElephantDiagram.png
new file mode 100644
index 00000000..450c69ab
--- /dev/null
+++ b/client/public/variants/Xiangqi/ElephantDiagram.png
@@ -0,0 +1 @@
+#$# git-fat 4ca235d26baaba6c2d38443262e9e7b26dd99c41                59999
diff --git a/client/public/variants/Xiangqi/HorseDiagram.png b/client/public/variants/Xiangqi/HorseDiagram.png
new file mode 100644
index 00000000..fc2c9418
--- /dev/null
+++ b/client/public/variants/Xiangqi/HorseDiagram.png
@@ -0,0 +1 @@
+#$# git-fat c81242020ecffe542e81e359626dc922f88ef5d5                77328
diff --git a/client/src/translations/en.js b/client/src/translations/en.js
index 3cde6ed6..57dcd898 100644
--- a/client/src/translations/en.js
+++ b/client/src/translations/en.js
@@ -176,7 +176,7 @@ export const translations = {
   "Bishop versus pawns": "Bishop versus pawns",
   "Board upside down": "Board upside down",
   "Both sides of the mirror": "Both sides of the mirror",
-  "Burmese chess": "Burmese chess",
+  "Burmese Chess": "Burmese Chess",
   "Capture all of a kind": "Capture all of a kind",
   "Capture both colors": "Capture both colors",
   "Capture en passant": "Capture en passant",
@@ -185,6 +185,7 @@ export const translations = {
   "Capture the princess": "Capture the princess",
   "Captures reborn": "Captures reborn",
   "Change colors": "Change colors",
+  "Chinese Chess": "Chinese Chess",
   "Convert & support (v1)": "Convert & support (v1)",
   "Convert & support (v2)": "Convert & support (v2)",
   "Dangerous captures": "Dangerous captures",
diff --git a/client/src/translations/es.js b/client/src/translations/es.js
index 612b0e35..a7e3c9d4 100644
--- a/client/src/translations/es.js
+++ b/client/src/translations/es.js
@@ -176,7 +176,7 @@ export const translations = {
   "Bishop versus pawns": "Alfil contra peones",
   "Board upside down": "Tablero al revés",
   "Both sides of the mirror": "Ambos lados del espejo",
-  "Burmese chess": "Ajedrez birmano",
+  "Burmese Chess": "Ajedrez birmano",
   "Capture all of a kind": "Capturar todo del mismo tipo",
   "Capture both colors": "Captura ambos colores",
   "Capture en passant": "Capturar en passant",
@@ -185,6 +185,7 @@ export const translations = {
   "Capture the princess": "Capturar a la princesa",
   "Captures reborn": "Las capturas renacen",
   "Change colors": "Cambiar colores",
+  "Chinese Chess": "Ajedrez chino",
   "Convert & support (v1)": "Convertir & apoyar (v1)",
   "Convert & support (v2)": "Convertir & apoyar (v2)",
   "Dangerous captures": "Capturas peligrosas",
diff --git a/client/src/translations/fr.js b/client/src/translations/fr.js
index 6163dc45..d971d6ba 100644
--- a/client/src/translations/fr.js
+++ b/client/src/translations/fr.js
@@ -176,7 +176,7 @@ export const translations = {
   "Bishop versus pawns": "Fou contre pions",
   "Board upside down": "Échiquier à l'envers",
   "Both sides of the mirror": "Les deux côté du miroir",
-  "Burmese chess": "Échecs birmans",
+  "Burmese Chess": "Échecs birmans",
   "Capture all of a kind": "Capturez tout d'un même type",
   "Capture both colors": "Capturer les deux couleurs",
   "Capture en passant": "Capturer en passant",
@@ -185,6 +185,7 @@ export const translations = {
   "Capture the princess": "Capturer la princesse",
   "Captures reborn": "Les captures renaissent",
   "Change colors": "Changer les couleurs",
+  "Chinese Chess": "Échecs chinois",
   "Convert & support (v1)": "Convertir & soutenir (v1)",
   "Convert & support (v2)": "Convertir & soutenir (v2)",
   "Dangerous captures": "Captures dangeureuses",
diff --git a/client/src/translations/rules/Xiangqi/en.pug b/client/src/translations/rules/Xiangqi/en.pug
new file mode 100644
index 00000000..06e01086
--- /dev/null
+++ b/client/src/translations/rules/Xiangqi/en.pug
@@ -0,0 +1,66 @@
+p.boxed.
+  Chinese chess, with different pieces behaving
+  differently than orthodox chess.
+
+p.
+  Pieces stand on intersections rather than squares: this is purely aesthetic,
+  and doesn't affect movements' descriptions.
+
+figure
+  img.img-center(src="/variants/Xiangqi/Boards.png")
+  figcaption
+    | Xiangqi boards borrowed from 
+    a(href="https://www.pychess.org/variant/xiangqi") pychess-variants
+    | . Chinese pieces on the right, international ones on the left.
+
+p.
+  The central area between rows 5 and 6 is called the "river".
+  It affects some pieces behavior.
+
+p.
+  Only the rooks behave exactly as in standard chess.
+  All other pieces are quite different:
+ul
+  li.
+    The King moves orthogonaly by one square, and cannot leave the "palace"
+    consisting of the nine intersections of the grey rectangles
+    on the diagram above.
+  li.
+    The pieces surrounding the king are Advisors: they move by one square
+    at a time, diagonally only. They are also restricted to the palace.
+  li.
+    The pawns ("Soldiers") move - and capture - by going up one intersection.
+    After they reach the second half of the board, they can then also move
+    (and capture) by one square lateraly.
+  li.
+    The Elephant moves by two intersections diagonally. It cannot jump over
+    obstacles: the midpoint intersection should be vacant.
+    The elephants cannot cross the river.
+  li.
+    The knights ("Horses") also cannot jump over obstacles, although they
+    appear to move as in orthodox chess. They make an orthogonal step first,
+    and then a diagonal step so that they are at a regular "knight distance"
+    from the initial intersection.
+    However, the square after first step must be empty.
+  li.
+    The Cannons move like a rook but capture by jumping first over an
+    obstacle (friendly or enemy). After such a jump the cannon can only
+    capture (no normal moves).
+
+figure.diagram-container
+  .diagram.diag12
+    img(src="/variants/Xiangqi/ElephantDiagram.png")
+  .diagram.diag22
+    img(src="/variants/Xiangqi/HorseDiagram.png")
+  figcaption
+    | Elephant and Horse moves illustrated, from 
+    a(href="https://www.pychess.org/variant/xiangqi") pychess-variants
+    | .
+
+h3 More information
+
+p
+  | Many resources are available online: just search with keywords Xiangqi
+  | or Chinese chess. You can play it on 
+  a(href="https://www.pychess.org") pychess-variants
+  | , against humans or a (basic) bot.
diff --git a/client/src/translations/rules/Xiangqi/es.pug b/client/src/translations/rules/Xiangqi/es.pug
new file mode 100644
index 00000000..5e62a07c
--- /dev/null
+++ b/client/src/translations/rules/Xiangqi/es.pug
@@ -0,0 +1,68 @@
+p.boxed.
+  Ajedrez chino, con diferentes piezas comportándose
+  diferente al ajedrez ortodoxo.
+
+p.
+  Las piezas se colocan en las intersecciones en lugar de en el centro de
+  las casillas. El efecto es solo estético, no hay impacto en la descripción
+  de los desplazamientos.
+
+figure
+  img.img-center(src="/variants/Xiangqi/Boards.png")
+  figcaption
+    | Meseta Xiangqi tomado de 
+    a(href="https://www.pychess.org/variant/xiangqi") pychess-variants
+    | . Piezas chinas a la derecha, internacionales a la izquierda.
+
+p.
+  La parte central entre las filas 5 y 6 se llama "río".
+  Afecta el comportamiento de ciertas piezas.
+
+p.
+  Solo las torres se comportan como en el ajedrez estándar.
+  Todas las demás piezas son bastante diferentes:
+ul
+  li.
+    El Rey se mueve ortogonalmente una casilla y no puede salir
+    el "palacio" que consta de las nueve intersecciones de rectángulos grises
+    en el diagrama de arriba.
+  li.
+    Las piezas que rodean al rey son los Consejeros: mueven una
+    casilla a la vez, solo en diagonal.
+    Ellos también están restringidos al palacio.
+  li.
+    Los peones ("Soldados") se mueven y capturan subiendo uno
+    intersección. Una vez que cruzan el río, también pueden
+    mover (y capturar) un cuadrado de lado.
+  li.
+    El Elefante se mueve desde dos intersecciones diagonales. No puede
+    saltar obstáculos: la intersección en el punto central debe
+    ser libre. Los elefantes no pueden cruzar el río.
+li.
+    Los Caballos tampoco pueden saltar obstáculos,
+    aunque parecen moverse como los caballos ortodoxos.
+    Ellos primero dar un paso ortogonal, luego un paso diagonal de
+    para estar a una distancia de caballo "estándar" de la intersección
+    inicial. Sin embargo, la casilla después del primer paso debe estar vacía.
+  li.
+    Los Cañones se mueven como una torre pero capturan saltando primero
+    sobre un obstáculo (amigo o enemigo). Después de tal salto el cañón
+    solo puede capturar (sin movimientos normales).
+
+figure.diagram-container
+  .diagram.diag12
+    img(src="/variants/Xiangqi/ElephantDiagram.png")
+  .diagram.diag22
+    img(src="/variants/Xiangqi/HorseDiagram.png")
+  figcaption
+    | Jugadas del Elefante y del Caballo illustradas, de 
+    a(href="https://www.pychess.org/variant/xiangqi") pychess-variants
+    | .
+
+h3 Más información
+
+p
+  | Hay muchos recursos disponibles en línea, solo busque
+  | con las palabras clave Xiangqi o Ajedrez chino. Puedes jugarlo en 
+  a(href="https://www.pychess.org") pychess-variants
+  | , contra humanos o un programa (básico).
diff --git a/client/src/translations/rules/Xiangqi/fr.pug b/client/src/translations/rules/Xiangqi/fr.pug
new file mode 100644
index 00000000..05f8a402
--- /dev/null
+++ b/client/src/translations/rules/Xiangqi/fr.pug
@@ -0,0 +1,68 @@
+p.boxed.
+  Échecs chinois, avec différentes pièces se comportant
+  différemment des échecs orthodoxes.
+
+p.
+  Les pièces se positionnent sur les intersections plutôt qu'au centre des
+  cases. L'effet n'est qu'esthétique, il n'y a pas d'impact sur la description
+  des déplacements.
+
+figure
+  img.img-center(src="/variants/Xiangqi/Boards.png")
+  figcaption
+    | Plateau de Xiangqi empruntés à 
+    a(href="https://www.pychess.org/variant/xiangqi") pychess-variants
+    | . Pièces chinoises à droite, internationales à gauche.
+
+p.
+  La partie centrale entre les rangées 5 et 6 est appelée la "rivière".
+  Elle affecte le comportement de certaines pièces.
+
+p.
+  Seules les tours se comportent comme aux échecs standards.
+  Toutes les autres pièces sont plutôt différentes :
+ul
+  li.
+    Le Roi se déplace orthogonalement d'une case, et ne peut pas quitter
+    le "palais" consistant en les neuf intersections des rectangles gris
+    sur le diagramme ci-dessus.
+  li.
+    Les pièces entourant le roi sont les Conseillers : ils se déplacent d'une
+    case à la fois, en diagonale seulement.
+    Ils sont eux-aussi restreints au palais.
+  li.
+    Les pions ("Soldats") se déplacent - et capturent - en montant d'une
+    intersection. Une fois qu'ils on franchi la rivière, ils peuvent aussi
+    se déplacer (et capturer) d'une case latéralement.
+  li.
+    L'Éléphant se déplacent de deux intersections en diagonale. Il ne peut pas
+    sauter par dessus les obstacles : l'intersection au point central doit
+    être libre. Les éléphants ne peuvent traverser la rivière.
+  li.
+    Les cavaliers ("Chevaux") ne peuvent pas non plus sauter les obstacles,
+    bien qu'ils paraissent se déplacer comme les cavaliers orthodoxes. Ils
+    effecuent d'abord un pas orthogonal, puis ensuite un en diagonale de
+    manière à se retrouver à distance de cavalier "standard" de l'intersection
+    initiale. Cependant, la case après le premier pas doit être vide.
+  li.
+    Les Canons se déplacent comme une tour mais capturent en sautant d'abord
+    par dessus un obstacle (ami ou ennemi). Après un tel saut le canon
+    ne peut que capturer (pas de coups normaux).
+
+figure.diagram-container
+  .diagram.diag12
+    img(src="/variants/Xiangqi/ElephantDiagram.png")
+  .diagram.diag22
+    img(src="/variants/Xiangqi/HorseDiagram.png")
+  figcaption
+    | Coups de l'Élephant et du Cheval illustrés, depuis 
+    a(href="https://www.pychess.org/variant/xiangqi") pychess-variants
+    | .
+
+h3 Plus d'information
+
+p
+  | Beaucoup de ressources sont disponibles en ligne : cherchez simplement
+  avec les mots-clé Xiangqi ou Échecs chinois. Vous pouvez y jouer sur 
+  a(href="https://www.pychess.org") pychess-variants
+  | , contre des humains ou un programme (basique).
diff --git a/client/src/variants/Xiangqi.js b/client/src/variants/Xiangqi.js
new file mode 100644
index 00000000..3889b20a
--- /dev/null
+++ b/client/src/variants/Xiangqi.js
@@ -0,0 +1,301 @@
+import { ChessRules } from "@/base_rules";
+
+export class XiangqiRules extends ChessRules {
+
+  static get Monochrome() {
+    return true;
+  }
+
+  static get Notoodark() {
+    return true;
+  }
+
+  static get Lines() {
+    let lines = [];
+    // Draw all inter-squares lines, shifted:
+    for (let i = 0; i < V.size.x; i++)
+      lines.push([[i+0.5, 0.5], [i+0.5, V.size.y-0.5]]);
+    for (let j = 0; j < V.size.y; j++)
+      lines.push([[0.5, j+0.5], [V.size.x-0.5, j+0.5]]);
+    // Add palaces:
+    lines.push([[0.5, 3.5], [2.5, 5.5]]);
+    lines.push([[0.5, 5.5], [2.5, 3.5]]);
+    lines.push([[9.5, 3.5], [7.5, 5.5]]);
+    lines.push([[9.5, 5.5], [7.5, 3.5]]);
+    // Show river:
+    lines.push([[4.5, 0.5], [5.5, 8.5]]);
+    lines.push([[5.5, 0.5], [4.5, 8.5]]);
+    return lines;
+  }
+
+  static get HasFlags() {
+    return false;
+  }
+
+  static get HasEnpassant() {
+    return false;
+  }
+
+  static get ELEPHANT() {
+    return "e";
+  }
+
+  static get CANNON() {
+    return "c";
+  }
+
+  static get ADVISOR() {
+    return "a";
+  }
+
+  static get PIECES() {
+    return [V.PAWN, V.ROOK, V.KNIGHT, V.ELEPHANT, V.ADVISOR, V.KING, V.CANNON];
+  }
+
+  getPpath(b) {
+    return "Xiangqi/" + b;
+  }
+
+  static get size() {
+    return { x: 10, y: 9};
+  }
+
+  getPotentialMovesFrom(sq) {
+    switch (this.getPiece(sq[0], sq[1])) {
+      case V.PAWN: return this.getPotentialPawnMoves(sq);
+      case V.ROOK: return super.getPotentialRookMoves(sq);
+      case V.KNIGHT: return this.getPotentialKnightMoves(sq);
+      case V.ELEPHANT: return this.getPotentialElephantMoves(sq);
+      case V.ADVISOR: return this.getPotentialAdvisorMoves(sq);
+      case V.KING: return this.getPotentialKingMoves(sq);
+      case V.CANNON: return this.getPotentialCannonMoves(sq);
+    }
+    return []; //never reached
+  }
+
+  getPotentialPawnMoves([x, y]) {
+    const c = this.getColor(x, y);
+    const shiftX = (c == 'w' ? -1 : 1);
+    const crossedRiver = (c == 'w' && x <= 4 || c == 'b' && x >= 5);
+    const lastRank = (c == 'w' && x == 0 || c == 'b' && x == 9);
+    let steps = [];
+    if (!lastRank) steps.push([shiftX, 0]);
+    if (crossedRiver) {
+      if (y > 0) steps.push([0, -1]);
+      if (y < 9) steps.push([0, 1]);
+    }
+    return super.getSlideNJumpMoves([x, y], steps, "oneStep");
+  }
+
+  knightStepsFromRookStep(step) {
+    if (step[0] == 0) return [ [1, 2*step[1]], [-1, 2*step[1]] ];
+    return [ [2*step[0], 1], [2*step[0], -1] ];
+  }
+
+  getPotentialKnightMoves([x, y]) {
+    let steps = [];
+    for (let rookStep of ChessRules.steps[V.ROOK]) {
+      const [i, j] = [x + rookStep[0], y + rookStep[1]];
+      if (V.OnBoard(i, j) && this.board[i][j] == V.EMPTY) {
+        Array.prototype.push.apply(steps,
+          // These moves might be impossible, but need to be checked:
+          this.knightStepsFromRookStep(rookStep));
+      }
+    }
+    return super.getSlideNJumpMoves([x, y], steps, "oneStep");
+  }
+
+  getPotentialElephantMoves([x, y]) {
+    let steps = [];
+    const c = this.getColor(x, y);
+    for (let bishopStep of ChessRules.steps[V.BISHOP]) {
+      const [i, j] = [x + bishopStep[0], y + bishopStep[1]];
+      if (V.OnBoard(i, j) && this.board[i][j] == V.EMPTY) {
+        const [newX, newY] = [x + 2*bishopStep[0], y + 2*bishopStep[1]];
+        if ((c == 'w' && newX >= 5) || (c == 'b' && newX <= 4))
+          // A priori valid (elephant don't cross the river)
+          steps.push(bishopStep.map(s => 2*s));
+          // "out of board" checks delayed to next method
+      }
+    }
+    return super.getSlideNJumpMoves([x, y], steps, "oneStep");
+  }
+
+  insidePalace(x, y, c) {
+    return (
+      (y >= 3 && y <= 5) &&
+      (
+        (c == 'w' && x >= 7) ||
+        (c == 'b' && x <= 2)
+      )
+    );
+  }
+
+  getPotentialAdvisorMoves([x, y]) {
+    // Diagonal steps inside palace
+    let steps = [];
+    const c = this.getColor(x, y);
+    for (let s of ChessRules.steps[V.BISHOP]) {
+      if (this.insidePalace(x + s[0], y + s[1], c)) steps.push(s);
+    }
+    return super.getSlideNJumpMoves([x, y], steps, "oneStep");
+  }
+
+  getPotentialKingMoves([x, y]) {
+    // Orthogonal steps inside palace
+    let steps = [];
+    const c = this.getColor(x, y);
+    for (let s of ChessRules.steps[V.ROOK]) {
+      if (this.insidePalace(x + s[0], y + s[1], c)) steps.push(s);
+    }
+    return super.getSlideNJumpMoves([x, y], steps, "oneStep");
+  }
+
+  // NOTE: duplicated from Shako (TODO?)
+  getPotentialCannonMoves([x, y]) {
+    const oppCol = V.GetOppCol(this.turn);
+    let moves = [];
+    // Look in every direction until an obstacle (to jump) is met
+    for (const step of V.steps[V.ROOK]) {
+      let i = x + step[0];
+      let j = y + step[1];
+      while (V.OnBoard(i, j) && this.board[i][j] == V.EMPTY) {
+        moves.push(this.getBasicMove([x, y], [i, j]));
+        i += step[0];
+        j += step[1];
+      }
+      // Then, search for an enemy
+      i += step[0];
+      j += step[1];
+      while (V.OnBoard(i, j) && this.board[i][j] == V.EMPTY) {
+        i += step[0];
+        j += step[1];
+      }
+      if (V.OnBoard(i, j) && this.getColor(i, j) == oppCol)
+        moves.push(this.getBasicMove([x, y], [i, j]));
+    }
+    return moves;
+  }
+
+  // (King) Never attacked by advisor, since it stays in the palace
+  // Also, never attacked by elephants since they don't cross the river.
+  isAttacked(sq, color) {
+    return (
+      this.isAttackedByPawn(sq, color) ||
+      super.isAttackedByRook(sq, color) ||
+      this.isAttackedByKnight(sq, color) ||
+      this.isAttackedByCannon(sq, color)
+    );
+  }
+
+  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;
+  }
+
+  knightStepsFromBishopStep(step) {
+    return [ [2*step[0], step[1]], [step[0], 2*step[1]] ];
+  }
+
+  isAttackedByKnight([x, y], color) {
+    // Check bishop steps: if empty, look continuation knight step
+    let steps = [];
+    for (let s of ChessRules.steps[V.BISHOP]) {
+      const [i, j] = [x + s[0], y + s[1]];
+      if (
+        V.OnBoard(i, j) &&
+        this.board[i][j] == V.EMPTY
+      ) {
+        Array.prototype.push.apply(steps, this.knightStepsFromBishopStep(s));
+      }
+    }
+    return (
+      super.isAttackedBySlideNJump([x, y], color, V.KNIGHT, steps, "oneStep")
+    );
+  }
+
+  // NOTE: duplicated from Shako (TODO?)
+  isAttackedByCannon([x, y], color) {
+    // Reversed process: is there an obstacle in line,
+    // and a cannon next in the same line?
+    for (const step of V.steps[V.ROOK]) {
+      let [i, j] = [x+step[0], y+step[1]];
+      while (V.OnBoard(i, j) && this.board[i][j] == V.EMPTY) {
+        i += step[0];
+        j += step[1];
+      }
+      if (V.OnBoard(i, j)) {
+        // Keep looking in this direction
+        i += step[0];
+        j += step[1];
+        while (V.OnBoard(i, j) && this.board[i][j] == V.EMPTY) {
+          i += step[0];
+          j += step[1];
+        }
+        if (
+          V.OnBoard(i, j) &&
+          this.getPiece(i, j) == V.CANNON &&
+          this.getColor(i, j) == color
+        ) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  static get VALUES() {
+    return {
+      p: 1,
+      r: 9,
+      n: 4,
+      e: 2.5,
+      a: 2,
+      c: 4.5,
+      k: 1000
+    };
+  }
+
+  evalPosition() {
+    let evaluation = 0;
+    for (let i = 0; i < V.size.x; i++) {
+      for (let j = 0; j < V.size.y; j++) {
+        if (this.board[i][j] != V.EMPTY) {
+          const c = this.getColor(i, j);
+          const sign = (c == 'w' ? 1 : -1);
+          const piece = this.getPiece(i, j);
+          let pieceEval = V.VALUES[this.getPiece(i, j)];
+          if (
+            piece == V.PAWN &&
+            (
+              (c == 'w' && i <= 4) ||
+              (c == 'b' && i >= 5)
+            )
+          ) {
+            // Pawn crossed the river: higher value
+            pieceEval++;
+          }
+          evaluation += sign * pieceEval;
+        }
+      }
+    }
+    return evaluation;
+  }
+
+  static GenRandInitFen() {
+    // No randomization here (TODO?)
+    return "rneakaenr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNEAKAENR w 0";
+  }
+
+};
diff --git a/server/db/populate.sql b/server/db/populate.sql
index 7def7a62..b0596058 100644
--- a/server/db/populate.sql
+++ b/server/db/populate.sql
@@ -104,7 +104,7 @@ insert or ignore into Variants (name, description) values
   ('Shako', 'Non-conformism and utopia'),
   ('Shatranj', 'Ancient rules'),
   ('Shogi', 'Japanese Chess'),
-  ('Sittuyin', 'Burmese chess'),
+  ('Sittuyin', 'Burmese Chess'),
   ('Suicide', 'Lose all pieces'),
   ('Suction', 'Attract opposite king'),
   ('Swap', 'Dangerous captures'),
@@ -119,4 +119,5 @@ insert or ignore into Variants (name, description) values
   ('Vchess', 'Pawns capture backward'),
   ('Wildebeest', 'Balanced sliders & leapers'),
   ('Wormhole', 'Squares disappear'),
+  ('Xiangqi', 'Chinese Chess'),
   ('Zen', 'Reverse captures');
-- 
2.44.0