From: Benjamin Auder Date: Wed, 15 Apr 2020 02:20:55 +0000 (+0200) Subject: Add Makruk, Shako and Shogi + a few fixes X-Git-Url: https://git.auder.net/variants/Chakart/css/assets/current/doc/DESCRIPTION?a=commitdiff_plain;h=cd49e617866590dbc68530ad961b109cdbe1ce55;p=vchess.git Add Makruk, Shako and Shogi + a few fixes --- diff --git a/TODO b/TODO index d2b81cae..59181f90 100644 --- a/TODO +++ b/TODO @@ -1,15 +1,5 @@ -// TODO: also fix moves played on smartphone, annoying shift... - -Shako, also known as UniEed Chess (Jean-Louis -Cazaux, 1990). Board 10x10; extra pieces are -Elephant (moves one or two squares -diagonally, may leap intervening square) and -Cannon (as above); CC on a1/j1 and a10/j10, -ERNBQKBNRE on ranks 2/9, 10xP on ranks -3/8. The name means chess in Esperanto. -(Cazaux) - -Shogi + Makruk/Thai chess --> see on Pychess +Monochrome avec Zen captures ? +Zen1 & 2 (forced captured ?) Chakart :) https://www.chessvariants.com/crossover.dir/koopachess.html diff --git a/client/public/images/pieces/Makruk/bb.svg b/client/public/images/pieces/Makruk/bb.svg new file mode 100644 index 00000000..837a8294 --- /dev/null +++ b/client/public/images/pieces/Makruk/bb.svg @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Makruk/bf.svg b/client/public/images/pieces/Makruk/bf.svg new file mode 100644 index 00000000..0f7e9695 --- /dev/null +++ b/client/public/images/pieces/Makruk/bf.svg @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/client/public/images/pieces/Makruk/bk.svg b/client/public/images/pieces/Makruk/bk.svg new file mode 100644 index 00000000..5ee3ad3b --- /dev/null +++ b/client/public/images/pieces/Makruk/bk.svg @@ -0,0 +1,299 @@ + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Makruk/bn.svg b/client/public/images/pieces/Makruk/bn.svg new file mode 100644 index 00000000..4f613514 --- /dev/null +++ b/client/public/images/pieces/Makruk/bn.svg @@ -0,0 +1,330 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Makruk/bp.svg b/client/public/images/pieces/Makruk/bp.svg new file mode 100644 index 00000000..a0d61ca8 --- /dev/null +++ b/client/public/images/pieces/Makruk/bp.svg @@ -0,0 +1,218 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/client/public/images/pieces/Makruk/bq.svg b/client/public/images/pieces/Makruk/bq.svg new file mode 100644 index 00000000..7ca7c18c --- /dev/null +++ b/client/public/images/pieces/Makruk/bq.svg @@ -0,0 +1,292 @@ + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Makruk/br.svg b/client/public/images/pieces/Makruk/br.svg new file mode 100644 index 00000000..8131200e --- /dev/null +++ b/client/public/images/pieces/Makruk/br.svg @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Makruk/wb.svg b/client/public/images/pieces/Makruk/wb.svg new file mode 100644 index 00000000..e055ce97 --- /dev/null +++ b/client/public/images/pieces/Makruk/wb.svg @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Makruk/wf.svg b/client/public/images/pieces/Makruk/wf.svg new file mode 100644 index 00000000..a1fee69e --- /dev/null +++ b/client/public/images/pieces/Makruk/wf.svg @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/client/public/images/pieces/Makruk/wk.svg b/client/public/images/pieces/Makruk/wk.svg new file mode 100644 index 00000000..b06dc6d1 --- /dev/null +++ b/client/public/images/pieces/Makruk/wk.svg @@ -0,0 +1,299 @@ + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Makruk/wn.svg b/client/public/images/pieces/Makruk/wn.svg new file mode 100644 index 00000000..1085d4f5 --- /dev/null +++ b/client/public/images/pieces/Makruk/wn.svg @@ -0,0 +1,330 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Makruk/wp.svg b/client/public/images/pieces/Makruk/wp.svg new file mode 100644 index 00000000..e86d0694 --- /dev/null +++ b/client/public/images/pieces/Makruk/wp.svg @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/client/public/images/pieces/Makruk/wq.svg b/client/public/images/pieces/Makruk/wq.svg new file mode 100644 index 00000000..e390e7b3 --- /dev/null +++ b/client/public/images/pieces/Makruk/wq.svg @@ -0,0 +1,292 @@ + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Makruk/wr.svg b/client/public/images/pieces/Makruk/wr.svg new file mode 100644 index 00000000..e20ed0ad --- /dev/null +++ b/client/public/images/pieces/Makruk/wr.svg @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/SOURCE b/client/public/images/pieces/SOURCE index 89cf2dbd..1f96b87f 100644 --- a/client/public/images/pieces/SOURCE +++ b/client/public/images/pieces/SOURCE @@ -5,6 +5,6 @@ Some fairy pieces found on the web and icon scout: https://iconscout.com/ PNG images for Eightpieces from https://greenchess.net/index.php and Jeff Kubach design. Images of the Hawk and Elephant were designed by "Couch Tomato #2218" on Discord, for the pychess-variants website (http://pychess-variants.herokuapp.com/) -He also designed all the Horde pieces in Orda, +He also designed all the Horde pieces in Orda, the Shako Cannon and Elephant, the Sittuyin pieces set, and he sent me the wizard and champion SVG files as well (modified from Wikipedia) diff --git a/client/public/images/pieces/Shako/bc.svg b/client/public/images/pieces/Shako/bc.svg new file mode 100644 index 00000000..3e53c3fd --- /dev/null +++ b/client/public/images/pieces/Shako/bc.svg @@ -0,0 +1,223 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shako/be.svg b/client/public/images/pieces/Shako/be.svg new file mode 100644 index 00000000..92c9f6f4 --- /dev/null +++ b/client/public/images/pieces/Shako/be.svg @@ -0,0 +1,166 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shako/wc.svg b/client/public/images/pieces/Shako/wc.svg new file mode 100644 index 00000000..9aaff66c --- /dev/null +++ b/client/public/images/pieces/Shako/wc.svg @@ -0,0 +1,204 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shako/we.svg b/client/public/images/pieces/Shako/we.svg new file mode 100644 index 00000000..098bf4a4 --- /dev/null +++ b/client/public/images/pieces/Shako/we.svg @@ -0,0 +1,200 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/bb.svg b/client/public/images/pieces/Shogi/bb.svg new file mode 120000 index 00000000..49671f4c --- /dev/null +++ b/client/public/images/pieces/Shogi/bb.svg @@ -0,0 +1 @@ +wb.svg \ No newline at end of file diff --git a/client/public/images/pieces/Shogi/bbi.svg b/client/public/images/pieces/Shogi/bbi.svg new file mode 120000 index 00000000..5ad393f7 --- /dev/null +++ b/client/public/images/pieces/Shogi/bbi.svg @@ -0,0 +1 @@ +wbi.svg \ No newline at end of file diff --git a/client/public/images/pieces/Shogi/bd.svg b/client/public/images/pieces/Shogi/bd.svg new file mode 120000 index 00000000..c4401330 --- /dev/null +++ b/client/public/images/pieces/Shogi/bd.svg @@ -0,0 +1 @@ +wd.svg \ No newline at end of file diff --git a/client/public/images/pieces/Shogi/bdi.svg b/client/public/images/pieces/Shogi/bdi.svg new file mode 120000 index 00000000..86b76b1c --- /dev/null +++ b/client/public/images/pieces/Shogi/bdi.svg @@ -0,0 +1 @@ +wdi.svg \ No newline at end of file diff --git a/client/public/images/pieces/Shogi/bg.svg b/client/public/images/pieces/Shogi/bg.svg new file mode 120000 index 00000000..60095064 --- /dev/null +++ b/client/public/images/pieces/Shogi/bg.svg @@ -0,0 +1 @@ +wg.svg \ No newline at end of file diff --git a/client/public/images/pieces/Shogi/bgi.svg b/client/public/images/pieces/Shogi/bgi.svg new file mode 120000 index 00000000..a2117b15 --- /dev/null +++ b/client/public/images/pieces/Shogi/bgi.svg @@ -0,0 +1 @@ +wgi.svg \ No newline at end of file diff --git a/client/public/images/pieces/Shogi/bh.svg b/client/public/images/pieces/Shogi/bh.svg new file mode 120000 index 00000000..6d636de7 --- /dev/null +++ b/client/public/images/pieces/Shogi/bh.svg @@ -0,0 +1 @@ +wh.svg \ No newline at end of file diff --git a/client/public/images/pieces/Shogi/bhi.svg b/client/public/images/pieces/Shogi/bhi.svg new file mode 120000 index 00000000..bbb4eb32 --- /dev/null +++ b/client/public/images/pieces/Shogi/bhi.svg @@ -0,0 +1 @@ +whi.svg \ No newline at end of file diff --git a/client/public/images/pieces/Shogi/bk.svg b/client/public/images/pieces/Shogi/bk.svg new file mode 100644 index 00000000..31e25e67 --- /dev/null +++ b/client/public/images/pieces/Shogi/bk.svg @@ -0,0 +1,224 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/bki.svg b/client/public/images/pieces/Shogi/bki.svg new file mode 100644 index 00000000..701e19db --- /dev/null +++ b/client/public/images/pieces/Shogi/bki.svg @@ -0,0 +1,262 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/bl.svg b/client/public/images/pieces/Shogi/bl.svg new file mode 120000 index 00000000..c21b5aa7 --- /dev/null +++ b/client/public/images/pieces/Shogi/bl.svg @@ -0,0 +1 @@ +wl.svg \ No newline at end of file diff --git a/client/public/images/pieces/Shogi/bli.svg b/client/public/images/pieces/Shogi/bli.svg new file mode 120000 index 00000000..47d01dcf --- /dev/null +++ b/client/public/images/pieces/Shogi/bli.svg @@ -0,0 +1 @@ +wli.svg \ No newline at end of file diff --git a/client/public/images/pieces/Shogi/bm.svg b/client/public/images/pieces/Shogi/bm.svg new file mode 120000 index 00000000..a9c2cd14 --- /dev/null +++ b/client/public/images/pieces/Shogi/bm.svg @@ -0,0 +1 @@ +wm.svg \ No newline at end of file diff --git a/client/public/images/pieces/Shogi/bmi.svg b/client/public/images/pieces/Shogi/bmi.svg new file mode 120000 index 00000000..228dbfa1 --- /dev/null +++ b/client/public/images/pieces/Shogi/bmi.svg @@ -0,0 +1 @@ +wmi.svg \ No newline at end of file diff --git a/client/public/images/pieces/Shogi/bn.svg b/client/public/images/pieces/Shogi/bn.svg new file mode 120000 index 00000000..33ef4af2 --- /dev/null +++ b/client/public/images/pieces/Shogi/bn.svg @@ -0,0 +1 @@ +wn.svg \ No newline at end of file diff --git a/client/public/images/pieces/Shogi/bni.svg b/client/public/images/pieces/Shogi/bni.svg new file mode 120000 index 00000000..5d4dbc5d --- /dev/null +++ b/client/public/images/pieces/Shogi/bni.svg @@ -0,0 +1 @@ +wni.svg \ No newline at end of file diff --git a/client/public/images/pieces/Shogi/bo.svg b/client/public/images/pieces/Shogi/bo.svg new file mode 120000 index 00000000..719b624b --- /dev/null +++ b/client/public/images/pieces/Shogi/bo.svg @@ -0,0 +1 @@ +wo.svg \ No newline at end of file diff --git a/client/public/images/pieces/Shogi/boi.svg b/client/public/images/pieces/Shogi/boi.svg new file mode 120000 index 00000000..cbe16544 --- /dev/null +++ b/client/public/images/pieces/Shogi/boi.svg @@ -0,0 +1 @@ +woi.svg \ No newline at end of file diff --git a/client/public/images/pieces/Shogi/bp.svg b/client/public/images/pieces/Shogi/bp.svg new file mode 120000 index 00000000..e2dd8982 --- /dev/null +++ b/client/public/images/pieces/Shogi/bp.svg @@ -0,0 +1 @@ +wp.svg \ No newline at end of file diff --git a/client/public/images/pieces/Shogi/bpi.svg b/client/public/images/pieces/Shogi/bpi.svg new file mode 120000 index 00000000..291a6a99 --- /dev/null +++ b/client/public/images/pieces/Shogi/bpi.svg @@ -0,0 +1 @@ +wpi.svg \ No newline at end of file diff --git a/client/public/images/pieces/Shogi/bq.svg b/client/public/images/pieces/Shogi/bq.svg new file mode 120000 index 00000000..7ae9b2d6 --- /dev/null +++ b/client/public/images/pieces/Shogi/bq.svg @@ -0,0 +1 @@ +wq.svg \ No newline at end of file diff --git a/client/public/images/pieces/Shogi/bqi.svg b/client/public/images/pieces/Shogi/bqi.svg new file mode 120000 index 00000000..2fbac46a --- /dev/null +++ b/client/public/images/pieces/Shogi/bqi.svg @@ -0,0 +1 @@ +wqi.svg \ No newline at end of file diff --git a/client/public/images/pieces/Shogi/br.svg b/client/public/images/pieces/Shogi/br.svg new file mode 120000 index 00000000..3f766fa3 --- /dev/null +++ b/client/public/images/pieces/Shogi/br.svg @@ -0,0 +1 @@ +wr.svg \ No newline at end of file diff --git a/client/public/images/pieces/Shogi/bri.svg b/client/public/images/pieces/Shogi/bri.svg new file mode 120000 index 00000000..43abb93d --- /dev/null +++ b/client/public/images/pieces/Shogi/bri.svg @@ -0,0 +1 @@ +wri.svg \ No newline at end of file diff --git a/client/public/images/pieces/Shogi/bs.svg b/client/public/images/pieces/Shogi/bs.svg new file mode 120000 index 00000000..f1c400f5 --- /dev/null +++ b/client/public/images/pieces/Shogi/bs.svg @@ -0,0 +1 @@ +ws.svg \ No newline at end of file diff --git a/client/public/images/pieces/Shogi/bsi.svg b/client/public/images/pieces/Shogi/bsi.svg new file mode 120000 index 00000000..0ad15779 --- /dev/null +++ b/client/public/images/pieces/Shogi/bsi.svg @@ -0,0 +1 @@ +wsi.svg \ No newline at end of file diff --git a/client/public/images/pieces/Shogi/bt.svg b/client/public/images/pieces/Shogi/bt.svg new file mode 120000 index 00000000..7e0ea5d3 --- /dev/null +++ b/client/public/images/pieces/Shogi/bt.svg @@ -0,0 +1 @@ +wt.svg \ No newline at end of file diff --git a/client/public/images/pieces/Shogi/bti.svg b/client/public/images/pieces/Shogi/bti.svg new file mode 120000 index 00000000..e6105392 --- /dev/null +++ b/client/public/images/pieces/Shogi/bti.svg @@ -0,0 +1 @@ +wti.svg \ No newline at end of file diff --git a/client/public/images/pieces/Shogi/license.txt b/client/public/images/pieces/Shogi/license.txt new file mode 100644 index 00000000..68c30878 --- /dev/null +++ b/client/public/images/pieces/Shogi/license.txt @@ -0,0 +1 @@ +Permission of author (Daniel Lee) \ No newline at end of file diff --git a/client/public/images/pieces/Shogi/wb.svg b/client/public/images/pieces/Shogi/wb.svg new file mode 100644 index 00000000..0c95a944 --- /dev/null +++ b/client/public/images/pieces/Shogi/wb.svg @@ -0,0 +1,376 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/wbi.svg b/client/public/images/pieces/Shogi/wbi.svg new file mode 100644 index 00000000..2857d96b --- /dev/null +++ b/client/public/images/pieces/Shogi/wbi.svg @@ -0,0 +1,395 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/wd.svg b/client/public/images/pieces/Shogi/wd.svg new file mode 100644 index 00000000..41889dfa --- /dev/null +++ b/client/public/images/pieces/Shogi/wd.svg @@ -0,0 +1,430 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/wdi.svg b/client/public/images/pieces/Shogi/wdi.svg new file mode 100644 index 00000000..838266c8 --- /dev/null +++ b/client/public/images/pieces/Shogi/wdi.svg @@ -0,0 +1,491 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/wg.svg b/client/public/images/pieces/Shogi/wg.svg new file mode 100644 index 00000000..abc67085 --- /dev/null +++ b/client/public/images/pieces/Shogi/wg.svg @@ -0,0 +1,539 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/wgi.svg b/client/public/images/pieces/Shogi/wgi.svg new file mode 100644 index 00000000..d81b4a30 --- /dev/null +++ b/client/public/images/pieces/Shogi/wgi.svg @@ -0,0 +1,1147 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/wh.svg b/client/public/images/pieces/Shogi/wh.svg new file mode 100644 index 00000000..53264965 --- /dev/null +++ b/client/public/images/pieces/Shogi/wh.svg @@ -0,0 +1,433 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/whi.svg b/client/public/images/pieces/Shogi/whi.svg new file mode 100644 index 00000000..24dcbc28 --- /dev/null +++ b/client/public/images/pieces/Shogi/whi.svg @@ -0,0 +1,434 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/wk.svg b/client/public/images/pieces/Shogi/wk.svg new file mode 100644 index 00000000..0d920295 --- /dev/null +++ b/client/public/images/pieces/Shogi/wk.svg @@ -0,0 +1,206 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/wki.svg b/client/public/images/pieces/Shogi/wki.svg new file mode 100644 index 00000000..68590506 --- /dev/null +++ b/client/public/images/pieces/Shogi/wki.svg @@ -0,0 +1,244 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/wl.svg b/client/public/images/pieces/Shogi/wl.svg new file mode 100644 index 00000000..4cf5ffed --- /dev/null +++ b/client/public/images/pieces/Shogi/wl.svg @@ -0,0 +1,916 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/wli.svg b/client/public/images/pieces/Shogi/wli.svg new file mode 100644 index 00000000..31c5f17c --- /dev/null +++ b/client/public/images/pieces/Shogi/wli.svg @@ -0,0 +1,997 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/wm.svg b/client/public/images/pieces/Shogi/wm.svg new file mode 100644 index 00000000..40e9e4aa --- /dev/null +++ b/client/public/images/pieces/Shogi/wm.svg @@ -0,0 +1,1079 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/wmi.svg b/client/public/images/pieces/Shogi/wmi.svg new file mode 100644 index 00000000..63ff7331 --- /dev/null +++ b/client/public/images/pieces/Shogi/wmi.svg @@ -0,0 +1,1208 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/wn.svg b/client/public/images/pieces/Shogi/wn.svg new file mode 100644 index 00000000..18833cf8 --- /dev/null +++ b/client/public/images/pieces/Shogi/wn.svg @@ -0,0 +1,819 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/wni.svg b/client/public/images/pieces/Shogi/wni.svg new file mode 100644 index 00000000..4fc7e054 --- /dev/null +++ b/client/public/images/pieces/Shogi/wni.svg @@ -0,0 +1,873 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/wo.svg b/client/public/images/pieces/Shogi/wo.svg new file mode 100644 index 00000000..0e1aa87e --- /dev/null +++ b/client/public/images/pieces/Shogi/wo.svg @@ -0,0 +1,841 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/woi.svg b/client/public/images/pieces/Shogi/woi.svg new file mode 100644 index 00000000..dcb8eaa5 --- /dev/null +++ b/client/public/images/pieces/Shogi/woi.svg @@ -0,0 +1,913 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/wp.svg b/client/public/images/pieces/Shogi/wp.svg new file mode 100644 index 00000000..b56dfc99 --- /dev/null +++ b/client/public/images/pieces/Shogi/wp.svg @@ -0,0 +1,1012 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/wpi.svg b/client/public/images/pieces/Shogi/wpi.svg new file mode 100644 index 00000000..5765b6ce --- /dev/null +++ b/client/public/images/pieces/Shogi/wpi.svg @@ -0,0 +1,1061 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/wq.svg b/client/public/images/pieces/Shogi/wq.svg new file mode 100644 index 00000000..abfd82f6 --- /dev/null +++ b/client/public/images/pieces/Shogi/wq.svg @@ -0,0 +1,1029 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/wqi.svg b/client/public/images/pieces/Shogi/wqi.svg new file mode 100644 index 00000000..111783ca --- /dev/null +++ b/client/public/images/pieces/Shogi/wqi.svg @@ -0,0 +1,1125 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/wr.svg b/client/public/images/pieces/Shogi/wr.svg new file mode 100644 index 00000000..6b0849c2 --- /dev/null +++ b/client/public/images/pieces/Shogi/wr.svg @@ -0,0 +1,390 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/wri.svg b/client/public/images/pieces/Shogi/wri.svg new file mode 100644 index 00000000..d522dbb3 --- /dev/null +++ b/client/public/images/pieces/Shogi/wri.svg @@ -0,0 +1,440 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/ws.svg b/client/public/images/pieces/Shogi/ws.svg new file mode 100644 index 00000000..83ecbd27 --- /dev/null +++ b/client/public/images/pieces/Shogi/ws.svg @@ -0,0 +1,647 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/wsi.svg b/client/public/images/pieces/Shogi/wsi.svg new file mode 100644 index 00000000..195754de --- /dev/null +++ b/client/public/images/pieces/Shogi/wsi.svg @@ -0,0 +1,838 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/wt.svg b/client/public/images/pieces/Shogi/wt.svg new file mode 100644 index 00000000..919c1733 --- /dev/null +++ b/client/public/images/pieces/Shogi/wt.svg @@ -0,0 +1,672 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/images/pieces/Shogi/wti.svg b/client/public/images/pieces/Shogi/wti.svg new file mode 100644 index 00000000..e0894807 --- /dev/null +++ b/client/public/images/pieces/Shogi/wti.svg @@ -0,0 +1,926 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/src/components/BaseGame.vue b/client/src/components/BaseGame.vue index e99c194e..8a053765 100644 --- a/client/src/components/BaseGame.vue +++ b/client/src/components/BaseGame.vue @@ -212,6 +212,10 @@ export default { this.moves = JSON.parse(JSON.stringify(game.moves || [])); // Post-processing: decorate each move with notation and FEN this.vr = new V(game.fenStart); + this.inMultimove = false; //in case of + this.$refs["board"].resetCurrentAttempt(); //also in case of + let analyseBtn = document.getElementById("analyzeBtn"); + if (!!analyseBtn) analyseBtn.classList.remove("active"); const parsedFen = V.ParseFen(game.fenStart); const firstMoveColor = parsedFen.turn; this.firstMoveNumber = Math.floor(parsedFen.movesCount / 2) + 1; diff --git a/client/src/components/Board.vue b/client/src/components/Board.vue index c7c37896..8a42d34e 100644 --- a/client/src/components/Board.vue +++ b/client/src/components/Board.vue @@ -214,7 +214,7 @@ export default { attrs: { src: "/images/pieces/" + - this.vr.getReservePpath(i, playingColor) + + this.vr.getReservePpath(i, playingColor, orientation) + ".svg" } }), @@ -241,7 +241,7 @@ export default { attrs: { src: "/images/pieces/" + - this.vr.getReservePpath(i, oppCol) + + this.vr.getReservePpath(i, oppCol, orientation) + ".svg" } }), diff --git a/client/src/styles/_board_squares_img.sass b/client/src/styles/_board_squares_img.sass index e9606602..cbb2c346 100644 --- a/client/src/styles/_board_squares_img.sass +++ b/client/src/styles/_board_squares_img.sass @@ -1,10 +1,10 @@ // Styles for diagrams and board (partial). .light-square-diag - background-color: #e5e5ca + background-color: #dfdfdf .dark-square-diag - background-color: #6f8f57 + background-color: #7287b6 div.board user-select: none diff --git a/client/src/styles/_rules.sass b/client/src/styles/_rules.sass index 17b10667..40397a8d 100644 --- a/client/src/styles/_rules.sass +++ b/client/src/styles/_rules.sass @@ -65,7 +65,7 @@ ul:not(.browser-default) ul:not(.browser-default) > li list-style-type: disc -table +table.rules margin: 15px auto .italic diff --git a/client/src/translations/en.js b/client/src/translations/en.js index c2f982a7..3d83513a 100644 --- a/client/src/translations/en.js +++ b/client/src/translations/en.js @@ -187,6 +187,7 @@ export const translations = { "Interweaved colorbound teams": "Interweaved colorbound teams", "Get strong at self-mate": "Get strong at self-mate", "Give three checks": "Give three checks", + "Japanese Chess": "Japanese Chess", "Keep antiking in check (v1)": "Keep antiking in check (v1)", "Keep antiking in check (v2)": "Keep antiking in check (v2)", "Kings cross the 8x8 board": "Kings cross the 8x8 board", @@ -205,6 +206,7 @@ export const translations = { "Move like a knight (v2)": "Move like a knight (v2)", "Neverending rows": "Neverending rows", "No-check mode": "No-check mode", + "Non-conformism and utopia": "Non-conformism and utopia", "Occupy the enemy palace": "Occupy the enemy palace", "Pawns move diagonally": "Pawns move diagonally", "Play at the same time": "Play at the same time", @@ -223,6 +225,7 @@ export const translations = { "Shoot pieces": "Shoot pieces", "Squares disappear": "Squares disappear", "Standard rules": "Standard rules", + "Thai Chess": "Thai Chess", "The colorbound clobberers": "The colorbound clobberers", "The end of the world": "The end of the world", "Transform an essay": "Transform an essay", diff --git a/client/src/translations/es.js b/client/src/translations/es.js index e3f3d141..335d1e04 100644 --- a/client/src/translations/es.js +++ b/client/src/translations/es.js @@ -187,6 +187,7 @@ export const translations = { "Interweaved colorbound teams": "Equipos unicolores entrelazados", "Get strong at self-mate": "Progreso en mates asistidos", "Give three checks": "Dar tres jaques", + "Japanese Chess": "Ajedrez japonés", "Keep antiking in check (v1)": "Mantener el antirey en jaque (v1)", "Keep antiking in check (v2)": "Mantener el antirey en jaque (v2)", "Kings cross the 8x8 board": "Los reyes cruzan el 8x8 tablero", @@ -205,6 +206,7 @@ export const translations = { "Move like a knight (v2)": "Moverse como un caballo (v2)", "Neverending rows": "Filas interminables", "No-check mode": "Modo sin jaque", + "Non-conformism and utopia": "No-conformismo y utopía", "Occupy the enemy palace": "Ocupar el palacio enemigo", "Pawns move diagonally": "Peones se mueven en diagonal", "Play at the same time": "Jugar al mismo tiempo", @@ -223,6 +225,7 @@ export const translations = { "Shoot pieces": "Tirar de las piezas", "Squares disappear": "Las casillas desaparecen", "Standard rules": "Reglas estandar", + "Thai Chess": "Ajedrez tailandés", "The colorbound clobberers": "Los batidores unicolor", "The end of the world": "El fin del mundo", "Transform an essay": "Transformar un ensayo", diff --git a/client/src/translations/fr.js b/client/src/translations/fr.js index 5e0663c0..e9e983e0 100644 --- a/client/src/translations/fr.js +++ b/client/src/translations/fr.js @@ -187,6 +187,7 @@ export const translations = { "Interweaved colorbound teams": "Équipes unicolores entremêlées", "Get strong at self-mate": "Progressez en mats aidés", "Give three checks": "Donnez trois échecs", + "Japanese Chess": "Échecs japonais", "Keep antiking in check (v1)": "Gardez l'antiroi en échec (v1)", "Keep antiking in check (v2)": "Gardez l'antiroi en échec (v2)", "Kings cross the 8x8 board": "Les rois traversent l'échiquier 8x8", @@ -205,6 +206,7 @@ export const translations = { "Move like a knight (v2)": "Bouger comme un cavalier (v2)", "Neverending rows": "Rangées sans fin", "No-check mode": "Mode sans échec", + "Non-conformism and utopia": "Non-conformisme et utopie", "Occupy the enemy palace": "Occuper le palais ennemi", "Pawns move diagonally": "Les pions vont en diagonale", "Play at the same time": "Jouer en même temps", @@ -223,6 +225,7 @@ export const translations = { "Shoot pieces": "Tirez sur les pièces", "Squares disappear": "Les cases disparaissent", "Standard rules": "Règles usuelles", + "Thai Chess": "Échecs thai", "The colorbound clobberers": "Les tabasseurs unicolores", "The end of the world": "La fin du monde", "Transform an essay": "Transformer un essai", diff --git a/client/src/translations/rules/Makruk/en.pug b/client/src/translations/rules/Makruk/en.pug new file mode 100644 index 00000000..f9c06ccb --- /dev/null +++ b/client/src/translations/rules/Makruk/en.pug @@ -0,0 +1,40 @@ +p.boxed + | Bishops and queen are less powerful then in standard chess. + +p. + From left to right, with Thai names in parentheses: rook (Ruea), + knight (Ma), bishop (Khon), queen (Met), king (Khun). + +figure.showPieces.text-center + img(src="/images/pieces/Makruk/wr.svg") + img(src="/images/pieces/Makruk/wn.svg") + img(src="/images/pieces/Makruk/wb.svg") + img(src="/images/pieces/Makruk/wq.svg") + img(src="/images/pieces/Makruk/wk.svg") + +ul + li All pieces except bishops and queen move like in orthodox chess. + li The queen moves by one square in any diagonal direction. + li The bishop moves one square forward, or like a queen. + li The only special move is the pawn promotion, always to a queen. + li There is no castling option. + +p. + Pawns promote on the sixth rank, into a queen but still represented + like a pawn, as illustrated on the diagram. + +figure.diagram-container + .diagram.diag12 + | fen:8/8/8/4P3/8/8/8/8: + .diagram.diag22 + | fen:8/8/4F3/8/8/8/8/8: + figcaption Before and after pawn promotion on e6. + +h3 Source + +p + a(href="https://www.pychess.org/variant/makruk") + | Makruk + |  on pychess-variants (playable there). This variant is also playable + a(href="https://www.playok.com/en/makruk/") on playok + | . diff --git a/client/src/translations/rules/Makruk/es.pug b/client/src/translations/rules/Makruk/es.pug new file mode 100644 index 00000000..50f58556 --- /dev/null +++ b/client/src/translations/rules/Makruk/es.pug @@ -0,0 +1,44 @@ +p.boxed + | Los alfiles y la dama son menos poderosos que el ajedrez estándar. + +p. + De izquierda a derecha, con los nombres tailandeses entre paréntesis: + torre (Ruea), caballo (Ma), alfil (Khon), dama (Met), rey (Khun). + +figure.showPieces.text-center + img(src="/images/pieces/Makruk/wr.svg") + img(src="/images/pieces/Makruk/wn.svg") + img(src="/images/pieces/Makruk/wb.svg") + img(src="/images/pieces/Makruk/wq.svg") + img(src="/images/pieces/Makruk/wk.svg") + +ul + li. + Todas las piezas excepto los alfiles y la dama se mueven como en el + ajedrez ortodoxo. + li La dama se mueve una casilla en cualquier dirección diagonal. + li El alfil se mueve un espacio hacia adelante, o como una dama. + li. + El único movimiento especial es la promoción de los peones, siempre como + dama. + li No hay enroque. + +p. + Los peones son promovidos en la sexta fila, en una dama pero representada + por un peón particular, como se ilustra en el diagrama. + +figure.diagram-container + .diagram.diag12 + | fen:8/8/8/4P3/8/8/8/8: + .diagram.diag22 + | fen:8/8/4F3/8/8/8/8/8: + figcaption Antes y después de la promoción en e6. + +h3 Fuente + +p + a(href="https://www.pychess.org/variant/makruk") + | Makruk + |  en Pychess-variantes (jugable allí). Esta variante es jugable tambien + a(href="https://www.playok.com/en/makruk/") en playok + | . diff --git a/client/src/translations/rules/Makruk/fr.pug b/client/src/translations/rules/Makruk/fr.pug new file mode 100644 index 00000000..b6fdced1 --- /dev/null +++ b/client/src/translations/rules/Makruk/fr.pug @@ -0,0 +1,43 @@ +p.boxed + | Les fous et la dame sont moins puissants qu'aux échecs standards. + +p. + De gauche à droite, avec les noms thai entre parenthèses : tour (Ruea), + cavalier (Ma), fou (Khon), dame (Met), roi (Khun). + +figure.showPieces.text-center + img(src="/images/pieces/Makruk/wr.svg") + img(src="/images/pieces/Makruk/wn.svg") + img(src="/images/pieces/Makruk/wb.svg") + img(src="/images/pieces/Makruk/wq.svg") + img(src="/images/pieces/Makruk/wk.svg") + +ul + li. + Toutes les pièces sauf les fous et la dame se déplacent comme aux échecs + orthodoxes. + li La dame se déplace d'une case dans n'importe quelle direction diagonale. + li Le fou se déplace d'une case vers l'avant, ou bien comme une dame. + li Le seul coup spécial est la promotion des pions, toujours en dame. + li Il n'y a pas de roque. + +p. + Les pions sont promus sur la sixième rangée, en une dame mais représentée + par un pion particulier, comme illustré sur le diagramme. + +figure.diagram-container + .diagram.diag12 + | fen:8/8/8/4P3/8/8/8/8: + .diagram.diag22 + | fen:8/8/4F3/8/8/8/8/8: + figcaption Avant et après la promotion en e6. + +h3 Source + +p + a(href="https://www.pychess.org/variant/makruk") + | Makruk + |  sur pychess-variants (jouable là-bas). Cette variante est jouable + | également + a(href="https://www.playok.com/en/makruk/") sur playok + | . diff --git a/client/src/translations/rules/Monochrome/fr.pug b/client/src/translations/rules/Monochrome/fr.pug index 66ac9558..a37e52c8 100644 --- a/client/src/translations/rules/Monochrome/fr.pug +++ b/client/src/translations/rules/Monochrome/fr.pug @@ -10,7 +10,7 @@ p. p. Puisque les captures sont obligatoires, les pièces pourraient effectuer - quelques aller-retours autour de l'échiquier, chaneant de propriétaire à + quelques aller-retours autour de l'échiquier, changeant de propriétaire à chaque passage au centre. Par exemple sur le diagramme suivant, la séquence serait 1.Rxd7 Rxd1 2.Rxd8 et les noirs gagneraient, en supposant que la dernière rangée est la 8eme. diff --git a/client/src/translations/rules/Orda/en.pug b/client/src/translations/rules/Orda/en.pug index 2f63d041..244baf11 100644 --- a/client/src/translations/rules/Orda/en.pug +++ b/client/src/translations/rules/Orda/en.pug @@ -64,7 +64,7 @@ p. Similarly, the Yurt also captures the same way it moves; it moves as the silver general in Shogi. -table +table.rules tr th Horde piece th Kingdom "counterpart" @@ -175,7 +175,7 @@ p. Fairy Stockfish, noting that they are generic values, not necessarily specific to Orda chess. -table +table.rules tr th Kingdom piece th Value (Early / Late) @@ -212,7 +212,7 @@ p | an approximation. span.italic Note: this simplification is used by the weak bot here. -table +table.rules tr th Kingdom piece th Value diff --git a/client/src/translations/rules/Orda/es.pug b/client/src/translations/rules/Orda/es.pug index 72c4ac18..c62594d6 100644 --- a/client/src/translations/rules/Orda/es.pug +++ b/client/src/translations/rules/Orda/es.pug @@ -65,7 +65,7 @@ p. caballo. La yurta también captura a medida que se mueve: como un general de plata en el Shogi. -table +table.rules tr th Pieza de la Horda th "Contraparte" del Reino @@ -176,7 +176,7 @@ p. están los valores utilizados por Fairy Stockfish. Estos son valores genérico, no necesariamente específico del ajedrez Orda. -table +table.rules tr th Pieza del Reino th Valor (inicio / fin) @@ -214,7 +214,7 @@ p span.italic | Nota: esta simplificación es utilizada por el bot equivocada aquí. -table +table.rules tr th Pieza del Reino th Valor diff --git a/client/src/translations/rules/Orda/fr.pug b/client/src/translations/rules/Orda/fr.pug index a39264be..7b10a474 100644 --- a/client/src/translations/rules/Orda/fr.pug +++ b/client/src/translations/rules/Orda/fr.pug @@ -67,7 +67,7 @@ p. cavalier. La yourte capture également comme elle se déplace : comme un général d'argent au Shogi. -table +table.rules tr th Pièce de la Horde th "Contrepartie" du Royaume @@ -178,7 +178,7 @@ p. valeurs utilisées par Fairy Stockfish. Celles-ci sont des valeurs génériques, pas nécessairement spécifiques aux échecs Orda. -table +table.rules tr th Pièce du royaume th Valeur (Début / Fin) @@ -215,7 +215,7 @@ p | utilisée comme approximation. span.note Note : cette simplification est utilisée par le mauvais bot ici. -table +table.rules tr th Pièce du Royaume th Valeur diff --git a/client/src/translations/rules/Shako/en.pug b/client/src/translations/rules/Shako/en.pug new file mode 100644 index 00000000..b4cacf9f --- /dev/null +++ b/client/src/translations/rules/Shako/en.pug @@ -0,0 +1,31 @@ +p.boxed + | Two new pieces on a bigger board (10x10). + +p. + The rules are essentially the same as orthodox chess, but with two new + pieces, the elephant and cannon. Because of the 10x10 board, pawns promote + at the 10th rank, into any piece. + +figure.diagram-container + .diagram.diag12 + | fen:91/91/91/3b6/4E5/3N6/2p3P3/91/91/91 c4,c8,d7,f5,f7,g8: + .diagram.diag22 + | fen:91/91/91/91/1P2CB2p1/91/4p5/91/91/4n5 c6,d6,e7,e8,e9,e10,e5,e1,i6: + figcaption Left: moves of the elephant. Right: moves of the cannon. + +p. + The elephant moves by one or two squares diagonally, potentially jumping + over a piece. The cannon moves like a rook but captures by jumping first + over an obstacle, as the diagram illustrates. After such a jump the cannon + can only capture (no normal moves). + +h3 Source + +p + a(href="https://www.chessvariants.com/large.dir/shako.html") Shako + |  on chessvariants.com. + | This variant is also playable + a(href="https://www.pychess.org/variant/shako") on pychess-variants + | . + +p Inventor: Jean-Louis Cazaux (1990) diff --git a/client/src/translations/rules/Shako/es.pug b/client/src/translations/rules/Shako/es.pug new file mode 100644 index 00000000..2fcddd24 --- /dev/null +++ b/client/src/translations/rules/Shako/es.pug @@ -0,0 +1,33 @@ +p.boxed + | Dos piezas nuevas en un tablero más grande (10x10). + +p. + Las reglas son esencialmente las mismas que para el ajedrez ortodoxo, pero + con dos piezas nuevas, el elefante y el cañón. El tablero de ajedrez tiene + 10 filas: los peones se promocionan en el décimo, en cualquier pieza. + +figure.diagram-container + .diagram.diag12 + | fen:91/91/91/3b6/4E5/3N6/2p3P3/91/91/91 c4,c8,d7,f5,f7,g8: + .diagram.diag22 + | fen:91/91/91/91/1P2CB2p1/91/4p5/91/91/4n5 c6,d6,e7,e8,e9,e10,e5,e1,i6: + figcaption. + Izquierda: movimientos del elefante. Derecha: movimientos del cañón. + +p. + El elefante mueve una o dos casillas en diagonal, saltando + posiblemente sobre una pieza. El cañón se mueve como una torre pero + capturar saltando primero sobre un obstáculo, como se ilustra en el + diagrama. Después de tal salto, el cañón solo puede capturar + (no jugadas normales). + +h3 Fuente + +p + a(href="https://www.chessvariants.com/large.dir/shako.html") Shako + |  en chessvariants.com. + | Esta variante también es jugable + a(href="https://www.pychess.org/variant/shako") en pychess-variants + | . + +p Inventor: Jean-Louis Cazaux (1990) diff --git a/client/src/translations/rules/Shako/fr.pug b/client/src/translations/rules/Shako/fr.pug new file mode 100644 index 00000000..897b634d --- /dev/null +++ b/client/src/translations/rules/Shako/fr.pug @@ -0,0 +1,32 @@ +p.boxed + | Deux nouvelles pièces sur un plus grand échiquier (10x10). + +p. + Les règles sont essentiellement les mêmes qu'aux échecs orthodoxes, mais + avec deux nouvelles pièces, l'éléphant et le canon. L'échiquier ayant 10 + rangées, les pions sont promus sur la 10eme, en n'importe quelle pièce. + +figure.diagram-container + .diagram.diag12 + | fen:91/91/91/3b6/4E5/3N6/2p3P3/91/91/91 c4,c8,d7,f5,f7,g8: + .diagram.diag22 + | fen:91/91/91/91/1P2CB2p1/91/4p5/91/91/4n5 c6,d6,e7,e8,e9,e10,e5,e1,i6: + figcaption Gauche : coups de l'éléphant. Droite : coups du canon. + +p. + L'éléphant se déplace d'une ou deux cases en diagonale, sautant + éventuellement par dessus une pièce. Le canon se déplace comme une tour mais + capture en sautant d'abord par dessus un obstacle, comme illustré sur le + diagramme. Après un tel saut le canon ne peut que capturer + (pas de coups normaux). + +h3 Source + +p + a(href="https://www.chessvariants.com/large.dir/shako.html") Shako + |  sur chessvariants.com. + | Cette variante est également jouable + a(href="https://www.pychess.org/variant/shako") sur pychess-variants + | . + +p Inventeur : Jean-Louis Cazaux (1990) diff --git a/client/src/translations/rules/Shogi/en.pug b/client/src/translations/rules/Shogi/en.pug new file mode 100644 index 00000000..6cd3062d --- /dev/null +++ b/client/src/translations/rules/Shogi/en.pug @@ -0,0 +1,131 @@ +p.boxed + | Every captured piece change color and can be dropped back later. + | Most pieces can promote on the three last ranks. + +p + | The following description is often borrowed from the + a(href="https://www.pychess.org/variant/shogi") Shogi guide + |  on pychess-variants, where I found the pieces images. + | Shogi is played on a 9 x 9 board. + | The side with a black king starts the game. + +p. + Captures are achieved by replacement on the destination square. + Any captured unit is added to a reserve of "pocket" pieces. + At each turn you can drop one of these pieces instead of moving one. + A dropped piece must be able to move, theoretically, considering only its + position on the board. + Pawns cannot be dropped on a file already containing a pawn of the same + color. They also can't be dropped to give checkmate. + +h3 Pieces movements + +h4 King, rook, bishop + +figure.showPieces.text-center + img(src="/images/pieces/Shogi/wk.svg") + img(src="/images/pieces/Shogi/bk.svg") + img(src="/images/pieces/Shogi/wr.svg") + img(src="/images/pieces/Shogi/wb.svg") + figcaption From left to right: black & white kings, rook, bishop. + +p These pieces look different but move exactly as in orthodox chess. + +h4 + | Gold General + img(src="/images/pieces/Shogi/wg.svg") + +p. + The gold general moves by one square only, either like a rook or diagonally + forward. + +figure.diagram-container + .diagram + | fen:9/9/9/3b5/4Gp3/9/9/9/9 d6,e6,f6,d5,f5,e4: + figcaption Gold general movements. + +h4 + | Silver General + img(src="/images/pieces/Shogi/ws.svg") + +p. + The silver general moves by one square only, either like a bishop or + orthogonally forward. + +figure.diagram-container + .diagram + | fen:9/9/9/3b5/4S4/5p3/9/9/9 d6,e6,f6,d4,f4: + figcaption Silver general movements. + +h4 + | Knight + img(src="/images/pieces/Shogi/wn.svg") + +p. + The knight moves like a restricted orthodox knight: two squares forward, + and one to the side as the diagram illustrates. + +figure.diagram-container + .diagram + | fen:9/9/5p3/9/4N4/9/9/9/9 d7,f7: + figcaption Knight movements. + +h4 + | Lance + img(src="/images/pieces/Shogi/wl.svg") + +p The lance moves like a rook but only in one direction: forward. + +figure.diagram-container + .diagram + | fen:9/4p4/9/9/9/4L4/9/9/9 e5,e6,e7,e8: + figcaption Lance movements. + +h4 + | Pawn + img(src="/images/pieces/Shogi/wl.svg") + +p. + The pawn moves like in orthodox chess (without two squares initial move), + and he also captures in this way. + +h3 Promotion + +p. + All pieces except the gold general and the king can be promoted, + by playing a move arriving on one of the three last ranks. + Promotion is optional unless a normal move would result in a blocked piece. + Capturing a promoted piece put the non-promoted form in the reserve. + +figure.showPieces.text-center + img(src="/images/pieces/Shogi/wq.svg") + img(src="/images/pieces/Shogi/wo.svg") + img(src="/images/pieces/Shogi/wm.svg") + img(src="/images/pieces/Shogi/wt.svg") + figcaption. + Promotions from left to right: pawn ('Q'), knight ('O'), + lance ('M'), and silver general ('T'). + +p. + Minor pieces in this game are the pawn, knight, lance and silver general. + They all promote to a gold general: only their appearance differ. + The rook and the bishop promote respectively into a Dragon King and a + Dragon Horse, which allow them to move like a king in addition to their + usual movements. + +figure.diagram-container + .diagram.diag12 + | fen:9/9/9/9/4D4/9/9/9/9 a5,b5,c5,d5,f5,g5,h5,i5,e1,e2,e3,e4,e6,e7,e8,e9,d4,d6,f6,f4: + .diagram.diag22 + | fen:9/9/9/9/4H4/9/9/9/9 a9,b8,c7,d6,f4,g3,h2,i1,a1,b2,c3,d4,f6,g7,h8,i9,d5,e6,f5,e4: + figcaption Left: promoted rook. Right: promoted bishop. + +h3 More information + +p + | This game is very popular in Japan, so a lot of resources can be found + | online. A good starting point is the + a(href="https://www.pychess.org/variant/shogi") Shogi page + |  at pychess-variants, where you can also play, and / or the + a(href="https://en.wikipedia.org/wiki/Shogi") Wikipedia page + | . diff --git a/client/src/translations/rules/Shogi/es.pug b/client/src/translations/rules/Shogi/es.pug new file mode 100644 index 00000000..cdf199cb --- /dev/null +++ b/client/src/translations/rules/Shogi/es.pug @@ -0,0 +1,137 @@ +p.boxed + | Una pieza capturada cambia de color y se puede soltar más tarde. + | La mayoría de las piezas se pueden promocionar en los últimos tres filas. + +p + | La siguiente descripción a menudo se toma del + a(href="https://www.pychess.org/variant/shogi") guía Shogi + |  en pychess-variantes, donde también encontré las imágenes de las + | piezas. El Shogi se juega en un tablero de 9 x 9. + | El lado del rey negro comienza el juego. + +p. + Las capturas se realizan mediante reemplazo en la casilla de destino. + Cualquier unidad capturada se agrega a una reserva de piezas "de bolsillo". + En cada turno puedes colocar una de estas piezas en lugar de mover una. + Una pieza paracaidizada debe poder moverse, teóricamente, mientras no + considerando su posición en el estante. + Los peones no se pueden colocar en una columna que ya contiene un peón + del mismo color. Tampoco pueden dar jaque mate. + +h3 Movimientos de las piezas + +h4 Rey, torre, alfil + +figure.showPieces.text-center + img(src="/images/pieces/Shogi/wk.svg") + img(src="/images/pieces/Shogi/bk.svg") + img(src="/images/pieces/Shogi/wr.svg") + img(src="/images/pieces/Shogi/wb.svg") + figcaption De izquierda a derecha: reyes en blanco & negro, torre, alfil. + +p. + Estas piezas parecen diferentes pero se mueven exactamente como + en ajedrez ortodoxo. + +h4 + | General de oro + img(src="/images/pieces/Shogi/wg.svg") + +p. + El general del oro se mueve solo de una casilla, ya sea como una torre o + diagonalmente hacia adelante. + +figure.diagram-container + .diagram + | fen:9/9/9/3b5/4Gp3/9/9/9/9 d6,e6,f6,d5,f5,e4: + figcaption Movimientos del general de oro. + +h4 + | General de plata + img(src="/images/pieces/Shogi/ws.svg") + +p. + El general plateado se mueve solo de una casilla, ya sea como un alfil o + ortogonalmente hacia adelante. + +figure.diagram-container + .diagram + | fen:9/9/9/3b5/4S4/5p3/9/9/9 d6,e6,f6,d4,f4: + figcaption Movimientos del general de plata. + +h4 + | Caballo + img(src="/images/pieces/Shogi/wn.svg") + +p. + El caballo se mueve como un caballo ortodoxo restringido: dos espacios + hacia adelante, luego uno en el costado como se muestra en el diagrama. + +figure.diagram-container + .diagram + | fen:9/9/5p3/9/4N4/9/9/9/9 d7,f7: + figcaption Movimientos del caballo. + +h4 + | Lanza + img(src="/images/pieces/Shogi/wl.svg") + +p. + La lanza se mueve como una torre pero siempre en la misma dirección: + hacia adelante. + +figure.diagram-container + .diagram + | fen:9/4p4/9/9/9/4L4/9/9/9 e5,e6,e7,e8: + figcaption Movimientos de la lanza. + +h4 + | Peón + img(src="/images/pieces/Shogi/wl.svg") + +p. + El peón avanza como en el ajedrez ortodoxo (sin desplazamiento inicial de dos + casillas), y también captura así. + +h3 Promoción + +p. + Todas las piezas excepto el general de oro y el rey pueden ser + promovido, jugando un movimiento que llega a una de las últimas tres filas. + La promoción es opcional a menos que una jugada normal resulte en una pieza + bloqueada. La captura de una pieza promocionada agrega su forma no promovida + a la reserva. + +figure.showPieces.text-center + img(src="/images/pieces/Shogi/wq.svg") + img(src="/images/pieces/Shogi/wo.svg") + img(src="/images/pieces/Shogi/wm.svg") + img(src="/images/pieces/Shogi/wt.svg") + figcaption. + Promociones de izquierda a derecha: peón ('Q'), caballo ('O'), + lanza ('M') y plata general ('T'). + +p. + Las piezas menores en este juego son el peón, el caballo, la lanza y el + general de plata. Todos se promocionan como un general de oro: solo sus + apariencia es diferente. + La torre y el alfil son promovidos respectivamente en un Dragón Rey y un + Dragón Caballo, lo que les permite moverse como un rey además de su + capacidades usuales. + +figure.diagram-container + .diagram.diag12 + | fen:9/9/9/9/4D4/9/9/9/9 a5,b5,c5,d5,f5,g5,h5,i5,e1,e2,e3,e4,e6,e7,e8,e9,d4,d6,f6,f4: + .diagram.diag22 + | fen:9/9/9/9/4H4/9/9/9/9 a9,b8,c7,d6,f4,g3,h2,i1,a1,b2,c3,d4,f6,g7,h8,i9,d5,e6,f5,e4: + figcaption Izquierda: torre promovida. Derecha: alfil promovido. + +h3 Más información + +p + | Este juego es muy popular en Japón, por lo que muchos recursos son + | disponible en línea. Un buen punto de partida es la + a(href="https://www.pychess.org/variant/shogi") página Shogi + |  en pychess-variants, donde también puedes jugar, y / o la + a(href="https://es.wikipedia.org/wiki/Shogi") página Wikipedia + | . diff --git a/client/src/translations/rules/Shogi/fr.pug b/client/src/translations/rules/Shogi/fr.pug new file mode 100644 index 00000000..02d1234a --- /dev/null +++ b/client/src/translations/rules/Shogi/fr.pug @@ -0,0 +1,137 @@ +p.boxed + | Une pièce capturée change de couleur et peut être parachutée plus tard. + | La plupart des pièces peuvent se promouvoir sur les trois dernières + | rangées. + +p + | La description suivante est souvent empruntée au + a(href="https://www.pychess.org/variant/shogi") guide Shogi + |  sur pychess-variants, où j'ai aussi trouvé les images des pièces. + | Le Shogi se joue sur un échiquier 9 x 9. + | Le côté ayant le roi noir démarre la partie. + +p. + Les captures s'effectuent par remplacement sur la case de destination. + Toute unité capturée est ajoutée à une réserve de pièces "de poche". + À chaque tour vous pouvez poser l'une de ces pièces au lieu d'en déplacer + une. Une pièce parachutée doit pouvoir bouger, théoriquement, en ne + considérant que sa position sur le plateau. + Les pions ne peuvent pas être posés sur une colonne contenant déjà un pion + de la même couleur. Ils ne peuvent pas non plus donner échec et mat. + +h3 Mouvements des pièces + +h4 Roi, tour, fou + +figure.showPieces.text-center + img(src="/images/pieces/Shogi/wk.svg") + img(src="/images/pieces/Shogi/bk.svg") + img(src="/images/pieces/Shogi/wr.svg") + img(src="/images/pieces/Shogi/wb.svg") + figcaption De gauche à droite : rois noir & blanc, tour, fou. + +p. + Ces pièces ont l'air différentes mais se déplacent exactement comme aux + échecs orthodoxes. + +h4 + | Général d'or + img(src="/images/pieces/Shogi/wg.svg") + +p. + Le général d'or se déplace d'une case seulement, soit comme une tour soit + en diagonale vers l'avant. + +figure.diagram-container + .diagram + | fen:9/9/9/3b5/4Gp3/9/9/9/9 d6,e6,f6,d5,f5,e4: + figcaption Déplacements du général d'or. + +h4 + | Général d'argent + img(src="/images/pieces/Shogi/ws.svg") + +p. + Le général d'argent se déplace d'une case seulement, soit comme un fou soit + orthogonalement vers l'avant. + +figure.diagram-container + .diagram + | fen:9/9/9/3b5/4S4/5p3/9/9/9 d6,e6,f6,d4,f4: + figcaption Déplacements du général d'argent. + +h4 + | Cavalier + img(src="/images/pieces/Shogi/wn.svg") + +p. + Le cavalier se déplace comme un cavalier orthodoxe restreint : deux cases + vers l'avant, puis une sur le côté comme illustré sur le diagramme. + +figure.diagram-container + .diagram + | fen:9/9/5p3/9/4N4/9/9/9/9 d7,f7: + figcaption Déplacements du cavalier. + +h4 + | Lance + img(src="/images/pieces/Shogi/wl.svg") + +p. + Le lance se déplace comme une tour mais toujours dans la même direction : + vers l'avant. + +figure.diagram-container + .diagram + | fen:9/4p4/9/9/9/4L4/9/9/9 e5,e6,e7,e8: + figcaption Déplacements de la lance. + +h4 + | Pion + img(src="/images/pieces/Shogi/wl.svg") + +p. + Le pion avance comme aux échecs orthodoxes (sans déplacement initial de deux + cases), et il capture également ainsi. + +h3 Promotion + +p. + Toutes les pièces à l'exception du général d'or et du roi peuvent être + promues, en jouant un coup arrivant sur l'une des trois dernières rangées. + La promotion est optionnelle à moins qu'un coup normal résulte en une pièce + bloquée. Capturer une pièce promue ajoute sa forme non-promue en réserve. + +figure.showPieces.text-center + img(src="/images/pieces/Shogi/wq.svg") + img(src="/images/pieces/Shogi/wo.svg") + img(src="/images/pieces/Shogi/wm.svg") + img(src="/images/pieces/Shogi/wt.svg") + figcaption. + Promotions de gauche à droite : pion ('Q'), cavalier ('O'), + lance ('M'), et général d'argent ('T'). + +p. + Les pièces mineures dans ce jeu sont le pion, le cavalier, la lance et le + général d'argent. Elles se promeuvent toutes en un général d'or : seule leur + apparence diffère. + La tour et le fou sont promus respectivement en un Dragon Roi et un Dragon + Cheval, leur permettant de se déplacer comme un roi en plus de leurs + capacités usuelles. + +figure.diagram-container + .diagram.diag12 + | fen:9/9/9/9/4D4/9/9/9/9 a5,b5,c5,d5,f5,g5,h5,i5,e1,e2,e3,e4,e6,e7,e8,e9,d4,d6,f6,f4: + .diagram.diag22 + | fen:9/9/9/9/4H4/9/9/9/9 a9,b8,c7,d6,f4,g3,h2,i1,a1,b2,c3,d4,f6,g7,h8,i9,d5,e6,f5,e4: + figcaption Gauche : tour promue. Droite : fou promu. + +h3 Plus d'information + +p + | Ce jeu est très populaire au Japon, donc beaucoup de ressources sont + | disponibles en ligne. Un bon point de départ est la + a(href="https://www.pychess.org/variant/shogi") page Shogi + |  sur pychess-variants, où vous pouvez également jouer, et / ou la + a(href="https://fr.wikipedia.org/wiki/Shogi") page Wikipedia + | . diff --git a/client/src/translations/rules/Sittuyin/en.pug b/client/src/translations/rules/Sittuyin/en.pug index d9703ac4..c152bffb 100644 --- a/client/src/translations/rules/Sittuyin/en.pug +++ b/client/src/translations/rules/Sittuyin/en.pug @@ -18,7 +18,7 @@ figure.showPieces.text-center ul li Elephants replace the orthodox bishops. li General replace the orthodox queen. - li The only special pawn move is the promotion, always to a general. + li The only special move is the pawn promotion, always to a general. li There is no castling option. h3 First move diff --git a/client/src/translations/rules/Sittuyin/es.pug b/client/src/translations/rules/Sittuyin/es.pug index f7a757e0..be6b9c0d 100644 --- a/client/src/translations/rules/Sittuyin/es.pug +++ b/client/src/translations/rules/Sittuyin/es.pug @@ -19,7 +19,7 @@ ul li Los elefantes reemplazan a los alfiles. li El general reemplaza a la dama ortodoxa. li. - El único movimiento de peón especial es la promoción, + El único movimiento especial es la promoción de peón, siempre en un general. li No hay enroque. diff --git a/client/src/translations/rules/Sittuyin/fr.pug b/client/src/translations/rules/Sittuyin/fr.pug index 4b6ee434..d884b7f4 100644 --- a/client/src/translations/rules/Sittuyin/fr.pug +++ b/client/src/translations/rules/Sittuyin/fr.pug @@ -18,7 +18,7 @@ figure.showPieces.text-center ul li Les éléphants remplacent les fous. li Le général remplace la dame orthodoxe. - li Le seul coup spécial de pion est la promotion, toujours en un général. + li Le seul coup spécial est la promotion du pion, toujours en un général. li Il n'y a pas de roque. h3 Premier coup diff --git a/client/src/variants/Grasshopper.js b/client/src/variants/Grasshopper.js index fb8c27cd..5069e231 100644 --- a/client/src/variants/Grasshopper.js +++ b/client/src/variants/Grasshopper.js @@ -39,51 +39,6 @@ export class GrasshopperRules extends ChessRules { } } - getPotentialPawnMoves([x, y]) { - const color = this.turn; - let moves = []; - const [sizeX, sizeY] = [V.size.x, V.size.y]; - const shiftX = color == "w" ? -1 : 1; - const lastRank = color == "w" ? 0 : sizeX - 1; - - const finalPieces = - x + shiftX == lastRank - ? [V.ROOK, V.KNIGHT, V.BISHOP, V.QUEEN, V.GRASSHOPPER] - : [V.PAWN]; - if (this.board[x + shiftX][y] == V.EMPTY) { - // One square forward - for (let piece of finalPieces) { - moves.push( - this.getBasicMove([x, y], [x + shiftX, y], { - c: color, - p: piece - }) - ); - } - // No 2-squares jump - } - // Captures - for (let shiftY of [-1, 1]) { - if ( - y + shiftY >= 0 && - y + shiftY < sizeY && - this.board[x + shiftX][y + shiftY] != V.EMPTY && - this.canTake([x, y], [x + shiftX, y + shiftY]) - ) { - for (let piece of finalPieces) { - moves.push( - this.getBasicMove([x, y], [x + shiftX, y + shiftY], { - c: color, - p: piece - }) - ); - } - } - } - - return moves; - } - getPotentialGrasshopperMoves([x, y]) { let moves = []; // Look in every direction until an obstacle (to jump) is met diff --git a/client/src/variants/Makruk.js b/client/src/variants/Makruk.js new file mode 100644 index 00000000..2da534f1 --- /dev/null +++ b/client/src/variants/Makruk.js @@ -0,0 +1,138 @@ +import { ChessRules, Move, PiPo } from "@/base_rules"; +import { ArrayFun } from "@/utils/array"; +import { randInt, shuffle } from "@/utils/alea"; + +export class MakrukRules extends ChessRules { + static get HasFlags() { + return false; + } + + static get HasEnpassant() { + return false; + } + + static get PawnSpecs() { + return Object.assign( + {}, + ChessRules.PawnSpecs, + { + twoSquares: false, + promotions: [V.QUEEN] + } + ); + } + + static get PIECES() { + return ChessRules.PIECES.concat(V.PROMOTED); + } + + static get PROMOTED() { + return 'f'; + } + + static GenRandInitFen(randomness) { + if (randomness == 0) + return "rnbqkbnr/8/pppppppp/8/8/PPPPPPPP/8/RNBKQBNR w 0"; + + let pieces = { w: new Array(8), b: new Array(8) }; + for (let c of ["w", "b"]) { + if (c == 'b' && randomness == 1) { + pieces['b'] = pieces['w']; + break; + } + + // Get random squares for every piece, totally freely (no castling) + let positions = shuffle(ArrayFun.range(8)); + const composition = ['b', 'b', 'r', 'r', 'n', 'n', 'k', 'q']; + for (let i = 0; i < 8; i++) pieces[c][positions[i]] = composition[i]; + } + return ( + pieces["b"].join("") + + "/8/pppppppp/8/8/PPPPPPPP/8/" + + pieces["w"].join("").toUpperCase() + + " w 0" + ); + } + + getPpath(b) { + return "Makruk/" + b; + } + + getPotentialMovesFrom([x, y]) { + if (this.getPiece(x, y) == V.PROMOTED) + return this.getPotentialQueenMoves([x, y]); + return super.getPotentialMovesFrom([x, y]); + } + + getPotentialPawnMoves([x, y]) { + const color = this.turn; + const shiftX = V.PawnSpecs.directions[color]; + const sixthRank = (color == 'w' ? 2 : 5); + const tr = (x + shiftX == sixthRank ? { p: V.PROMOTED, c: color } : null); + let moves = []; + if (this.board[x + shiftX][y] == V.EMPTY) + // One square forward + moves.push(this.getBasicMove([x, y], [x + shiftX, y], tr)); + // Captures + for (let shiftY of [-1, 1]) { + if ( + y + shiftY >= 0 && y + shiftY < 8 && + this.board[x + shiftX][y + shiftY] != V.EMPTY && + this.canTake([x, y], [x + shiftX, y + shiftY]) + ) { + moves.push(this.getBasicMove([x, y], [x + shiftX, y + shiftY], tr)); + } + } + return moves; + } + + getPotentialBishopMoves(sq) { + const forward = (this.turn == 'w' ? -1 : 1); + return this.getSlideNJumpMoves( + sq, + V.steps[V.BISHOP].concat([ [forward, 0] ]), + "oneStep" + ); + } + + getPotentialQueenMoves(sq) { + return this.getSlideNJumpMoves( + sq, + V.steps[V.BISHOP], + "oneStep" + ); + } + + isAttackedByBishop(sq, color) { + const forward = (this.turn == 'w' ? 1 : -1); + return this.isAttackedBySlideNJump( + sq, + color, + V.BISHOP, + V.steps[V.BISHOP].concat([ [forward, 0] ]), + "oneStep" + ); + } + + isAttackedByQueen(sq, color) { + return this.isAttackedBySlideNJump( + sq, + color, + V.QUEEN, + V.steps[V.BISHOP], + "oneStep" + ); + } + + static get VALUES() { + return { + p: 1, + r: 5, + n: 3, + b: 3, + q: 2, + f: 2, + k: 1000 + }; + } +}; diff --git a/client/src/variants/Shako.js b/client/src/variants/Shako.js new file mode 100644 index 00000000..ee694d01 --- /dev/null +++ b/client/src/variants/Shako.js @@ -0,0 +1,340 @@ +import { ChessRules, Move, PiPo } from "@/base_rules"; +import { ArrayFun } from "@/utils/array"; +import { randInt, sample } from "@/utils/alea"; + +export class ShakoRules extends ChessRules { + static get PawnSpecs() { + return Object.assign( + {}, + ChessRules.PawnSpecs, + { + initShift: { w: 2, b: 2 }, + promotions: + ChessRules.PawnSpecs.promotions.concat([V.ELEPHANT, V.CANNON]) + } + ); + } + + static get ELEPHANT() { + return "e"; + } + + static get CANNON() { + return "c"; + } + + static get PIECES() { + return ChessRules.PIECES.concat([V.ELEPHANT, V.CANNON]); + } + + getPpath(b) { + const prefix = [V.ELEPHANT, V.CANNON].includes(b[1]) ? "Shako/" : ""; + return prefix + b; + } + + static get steps() { + return Object.assign( + {}, + ChessRules.steps, + { + e: [ + [-1, -1], + [-1, 1], + [1, -1], + [1, 1], + [-2, -2], + [-2, 2], + [2, -2], + [2, 2] + ] + } + ); + } + + static get size() { + return { x: 10, y: 10}; + } + + getPotentialMovesFrom([x, y]) { + switch (this.getPiece(x, y)) { + case V.ELEPHANT: + return this.getPotentialElephantMoves([x, y]); + case V.CANNON: + return this.getPotentialCannonMoves([x, y]); + default: + return super.getPotentialMovesFrom([x, y]); + } + } + + getPotentialElephantMoves([x, y]) { + return this.getSlideNJumpMoves([x, y], V.steps[V.ELEPHANT], "oneStep"); + } + + 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; + } + + getCastleMoves([x, y]) { + const c = this.getColor(x, y); + if (x != (c == "w" ? V.size.x - 2 : 1) || y != this.INIT_COL_KING[c]) + return []; //x isn't second rank, or king has moved (shortcut) + + // Castling ? + const oppCol = V.GetOppCol(c); + let moves = []; + let i = 0; + // King, then rook: + const finalSquares = [ + [3, 4], + [7, 6] + ]; + castlingCheck: for ( + let castleSide = 0; + castleSide < 2; + castleSide++ //large, then small + ) { + if (this.castleFlags[c][castleSide] >= V.size.y) continue; + // If this code is reached, rook and king are on initial position + + const rookPos = this.castleFlags[c][castleSide]; + + // Nothing on the path of the king ? (and no checks) + const castlingPiece = this.getPiece(x, rookPos); + const finDist = finalSquares[castleSide][0] - y; + let step = finDist / Math.max(1, Math.abs(finDist)); + i = y; + do { + if ( + this.isAttacked([x, i], oppCol) || + (this.board[x][i] != V.EMPTY && + // NOTE: next check is enough, because of chessboard constraints + (this.getColor(x, i) != c || + ![V.KING, castlingPiece].includes(this.getPiece(x, i)))) + ) { + continue castlingCheck; + } + i += step; + } while (i != finalSquares[castleSide][0]); + + // Nothing on the path to the rook? + step = castleSide == 0 ? -1 : 1; + for (i = y + step; i != rookPos; i += step) { + if (this.board[x][i] != V.EMPTY) continue castlingCheck; + } + + // Nothing on final squares, except maybe king and castling rook? + for (i = 0; i < 2; i++) { + if ( + finalSquares[castleSide][i] != rookPos && + this.board[x][finalSquares[castleSide][i]] != V.EMPTY && + ( + this.getPiece(x, finalSquares[castleSide][i]) != V.KING || + this.getColor(x, finalSquares[castleSide][i]) != c + ) + ) { + continue castlingCheck; + } + } + + // If this code is reached, castle is valid + moves.push( + new Move({ + appear: [ + new PiPo({ + x: x, + y: finalSquares[castleSide][0], + p: V.KING, + c: c + }), + new PiPo({ + x: x, + y: finalSquares[castleSide][1], + p: castlingPiece, + c: c + }) + ], + vanish: [ + new PiPo({ x: x, y: y, p: V.KING, c: c }), + new PiPo({ x: x, y: rookPos, p: castlingPiece, c: c }) + ], + end: + Math.abs(y - rookPos) <= 2 + ? { x: x, y: rookPos } + : { x: x, y: y + 2 * (castleSide == 0 ? -1 : 1) } + }) + ); + } + + return moves; + } + + isAttacked(sq, color) { + return ( + super.isAttacked(sq, color) || + this.isAttackedByElephant(sq, color) || + this.isAttackedByCannon(sq, color) + ); + } + + isAttackedByElephant(sq, color) { + return ( + this.isAttackedBySlideNJump( + sq, color, V.ELEPHANT, V.steps[V.ELEPHANT], "oneStep" + ) + ); + } + + 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; + } + + updateCastleFlags(move, piece) { + const c = V.GetOppCol(this.turn); + const firstRank = (c == "w" ? V.size.x - 2 : 1); + // Update castling flags if rooks are moved + const oppCol = this.turn; + const oppFirstRank = V.size.x - 1 - firstRank; + if (piece == V.KING) + this.castleFlags[c] = [V.size.y, V.size.y]; + else if ( + move.start.x == firstRank && //our rook moves? + this.castleFlags[c].includes(move.start.y) + ) { + const flagIdx = (move.start.y == this.castleFlags[c][0] ? 0 : 1); + this.castleFlags[c][flagIdx] = V.size.y; + } + // NOTE: not "else if" because a rook could take an opposing rook + if ( + move.end.x == oppFirstRank && //we took opponent rook? + this.castleFlags[oppCol].includes(move.end.y) + ) { + const flagIdx = (move.end.y == this.castleFlags[oppCol][0] ? 0 : 1); + this.castleFlags[oppCol][flagIdx] = V.size.y; + } + } + + static get VALUES() { + return Object.assign( + { e: 3, c: 5 }, + ChessRules.VALUES + ); + } + + static get SEARCH_DEPTH() { + return 2; + } + + static GenRandInitFen(randomness) { + if (randomness == 0) { + return ( + "c8c/ernbqkbnre/pppppppppp/91/91/91/91/PPPPPPPPPP/ERNBQKBNRE/C8C " + + "w 0 bibi -" + ); + } + + let pieces = { w: new Array(10), b: new Array(10) }; + let flags = ""; + // Shuffle pieces on second (and before-last rank if randomness == 2) + for (let c of ["w", "b"]) { + if (c == 'b' && randomness == 1) { + pieces['b'] = pieces['w']; + flags += flags; + break; + } + + let positions = ArrayFun.range(10); + + // Get random squares for bishops + elephants + const be1Pos = sample([0, 2, 4, 6, 8], 2); + const be2Pos = sample([1, 3, 5, 7, 9], 2); + const bishop1Pos = be1Pos[0]; + const bishop2Pos = be2Pos[0]; + const elephant1Pos = be1Pos[1]; + const elephant2Pos = be2Pos[1]; + // Remove chosen squares + (be1Pos.concat(be2Pos)).sort((x, y) => y - x).forEach(pos => { + positions.splice(pos, 1); + }); + + let randIndex = randInt(6); + const knight1Pos = positions[randIndex]; + positions.splice(randIndex, 1); + randIndex = randInt(5); + const knight2Pos = positions[randIndex]; + positions.splice(randIndex, 1); + + randIndex = randInt(4); + const queenPos = positions[randIndex]; + positions.splice(randIndex, 1); + + const rook1Pos = positions[0]; + const kingPos = positions[1]; + const rook2Pos = positions[2]; + + pieces[c][elephant1Pos] = "e"; + pieces[c][rook1Pos] = "r"; + pieces[c][knight1Pos] = "n"; + pieces[c][bishop1Pos] = "b"; + pieces[c][queenPos] = "q"; + pieces[c][kingPos] = "k"; + pieces[c][bishop2Pos] = "b"; + pieces[c][knight2Pos] = "n"; + pieces[c][rook2Pos] = "r"; + pieces[c][elephant2Pos] = "e"; + flags += V.CoordToColumn(rook1Pos) + V.CoordToColumn(rook2Pos); + } + // Add turn + flags + enpassant + return ( + "c8c/" + pieces["b"].join("") + + "/pppppppppp/91/91/91/91/PPPPPPPPPP/" + + pieces["w"].join("").toUpperCase() + "/C8C" + + " w 0 " + flags + " -" + ); + } +}; diff --git a/client/src/variants/Shogi.js b/client/src/variants/Shogi.js new file mode 100644 index 00000000..52cfb544 --- /dev/null +++ b/client/src/variants/Shogi.js @@ -0,0 +1,596 @@ +import { ChessRules, PiPo, Move } from "@/base_rules"; +import { ArrayFun } from "@/utils/array"; + +export class ShogiRules extends ChessRules { + static get HasFlags() { + return false; + } + + static get HasEnpassant() { + return false; + } + + static IsGoodFen(fen) { + if (!ChessRules.IsGoodFen(fen)) return false; + const fenParsed = V.ParseFen(fen); + // 3) Check reserves + if (!fenParsed.reserve || !fenParsed.reserve.match(/^[0-9]{14,14}$/)) + return false; + return true; + } + + static ParseFen(fen) { + const fenParts = fen.split(" "); + return Object.assign( + ChessRules.ParseFen(fen), + { reserve: fenParts[3] } + ); + } + + // pawns, rooks, knights, bishops and king kept from ChessRules + static get GOLD_G() { + return "g"; + } + static get SILVER_G() { + return "s"; + } + static get LANCER() { + return "l"; + } + + // Promoted pieces: + static get P_PAWN() { + return 'q'; + } + static get P_KNIGHT() { + return 'o'; + } + static get P_SILVER() { + return 't'; + } + static get P_LANCER() { + return 'm'; + } + static get P_ROOK() { + return 'd'; + } + static get P_BISHOP() { + return 'h'; + } + + static get PIECES() { + return [ + ChessRules.PAWN, + ChessRules.ROOK, + ChessRules.KNIGHT, + ChessRules.BISHOP, + ChessRules.KING, + V.GOLD_G, + V.SILVER_G, + V.LANCER, + V.P_PAWN, + V.P_KNIGHT, + V.P_SILVER, + V.P_LANCER, + V.P_ROOK, + V.P_BISHOP + ]; + } + + getPpath(b, color, score, orientation) { + // 'i' for "inversed": + const suffix = (b[0] == orientation ? "" : "i"); + return "Shogi/" + b + suffix; + } + + getPPpath(m, orientation) { + return ( + this.getPpath( + m.appear[0].c + m.appear[0].p, + null, + null, + orientation + ) + ); + } + + static GenRandInitFen() { + // No randomization for now: + return ( + "lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL " + + "w 0 00000000000000" + ); + } + + getFen() { + return super.getFen() + " " + this.getReserveFen(); + } + + getFenForRepeat() { + return super.getFenForRepeat() + "_" + this.getReserveFen(); + } + + getReserveFen() { + let counts = new Array(14); + for (let i = 0; i < V.RESERVE_PIECES.length; i++) { + counts[i] = this.reserve["w"][V.RESERVE_PIECES[i]]; + counts[6 + i] = this.reserve["b"][V.RESERVE_PIECES[i]]; + } + return counts.join(""); + } + + setOtherVariables(fen) { + super.setOtherVariables(fen); + const fenParsed = V.ParseFen(fen); + // Also init reserves (used by the interface to show landable pieces) + this.reserve = { + w: { + [V.PAWN]: parseInt(fenParsed.reserve[0]), + [V.ROOK]: parseInt(fenParsed.reserve[1]), + [V.BISHOP]: parseInt(fenParsed.reserve[2]), + [V.GOLD_G]: parseInt(fenParsed.reserve[3]), + [V.SILVER_G]: parseInt(fenParsed.reserve[4]), + [V.KNIGHT]: parseInt(fenParsed.reserve[5]), + [V.LANCER]: parseInt(fenParsed.reserve[6]) + }, + b: { + [V.PAWN]: parseInt(fenParsed.reserve[7]), + [V.ROOK]: parseInt(fenParsed.reserve[8]), + [V.BISHOP]: parseInt(fenParsed.reserve[9]), + [V.GOLD_G]: parseInt(fenParsed.reserve[10]), + [V.SILVER_G]: parseInt(fenParsed.reserve[11]), + [V.KNIGHT]: parseInt(fenParsed.reserve[12]), + [V.LANCER]: parseInt(fenParsed.reserve[13]) + } + }; + } + + getColor(i, j) { + if (i >= V.size.x) return i == V.size.x ? "w" : "b"; + return this.board[i][j].charAt(0); + } + + getPiece(i, j) { + if (i >= V.size.x) return V.RESERVE_PIECES[j]; + return this.board[i][j].charAt(1); + } + + static get size() { + return { x: 9, y: 9}; + } + + getReservePpath(index, color, orientation) { + return ( + "Shogi/" + color + V.RESERVE_PIECES[index] + + (color != orientation ? 'i' : '') + ); + } + + // Ordering on reserve pieces + static get RESERVE_PIECES() { + return ( + [V.PAWN, V.ROOK, V.BISHOP, V.GOLD_G, V.SILVER_G, V.KNIGHT, V.LANCER] + ); + } + + getReserveMoves([x, y]) { + const color = this.turn; + const p = V.RESERVE_PIECES[y]; + if (p == V.PAWN) { + var oppCol = V.GetOppCol(color); + var allowedFiles = + [...Array(9).keys()].filter(j => + [...Array(9).keys()].every(i => { + return ( + this.board[i][j] == V.EMPTY || + this.getColor(i, j) != color || + this.getPiece(i, j) != V.PAWN + ); + }) + ) + } + if (this.reserve[color][p] == 0) return []; + let moves = []; + const forward = color == 'w' ? -1 : 1; + const lastRanks = color == 'w' ? [0, 1] : [8, 7]; + for (let i = 0; i < V.size.x; i++) { + if ( + (i == lastRanks[0] && [V.PAWN, V.KNIGHT, V.LANCER].includes(p)) || + (i == lastRanks[1] && p == V.KNIGHT) + ) { + continue; + } + for (let j = 0; j < V.size.y; j++) { + if ( + this.board[i][j] == V.EMPTY && + (p != V.PAWN || allowedFiles.includes(j)) + ) { + let mv = new Move({ + appear: [ + new PiPo({ + x: i, + y: j, + c: color, + p: p + }) + ], + vanish: [], + start: { x: x, y: y }, //a bit artificial... + end: { x: i, y: j } + }); + if (p == V.PAWN) { + // Do not drop on checkmate: + this.play(mv); + const res = (this.underCheck(oppCol) && !this.atLeastOneMove()); + this.undo(mv); + if (res) continue; + } + moves.push(mv); + } + } + } + return moves; + } + + getPotentialMovesFrom([x, y]) { + if (x >= V.size.x) { + // Reserves, outside of board: x == sizeX(+1) + return this.getReserveMoves([x, y]); + } + switch (this.getPiece(x, y)) { + case V.PAWN: + return this.getPotentialPawnMoves([x, y]); + case V.ROOK: + return this.getPotentialRookMoves([x, y]); + case V.KNIGHT: + return this.getPotentialKnightMoves([x, y]); + case V.BISHOP: + return this.getPotentialBishopMoves([x, y]); + case V.SILVER_G: + return this.getPotentialSilverMoves([x, y]); + case V.LANCER: + return this.getPotentialLancerMoves([x, y]); + case V.KING: + return this.getPotentialKingMoves([x, y]); + case V.P_ROOK: + return this.getPotentialDragonMoves([x, y]); + case V.P_BISHOP: + return this.getPotentialHorseMoves([x, y]); + case V.GOLD_G: + case V.P_PAWN: + case V.P_SILVER: + case V.P_KNIGHT: + case V.P_LANCER: + return this.getPotentialGoldMoves([x, y]); + } + return []; //never reached + } + + // Modified to take promotions into account + getSlideNJumpMoves([x, y], steps, options) { + const color = this.turn; + const oneStep = options.oneStep; + const forcePromoteOnLastRank = options.force; + const promoteInto = options.promote; + const lastRanks = (color == 'w' ? [0, 1, 2] : [9, 8, 7]); + let moves = []; + outerLoop: for (let step of steps) { + let i = x + step[0]; + let j = y + step[1]; + while (V.OnBoard(i, j) && this.board[i][j] == V.EMPTY) { + if (i != lastRanks[0] || !forcePromoteOnLastRank) + moves.push(this.getBasicMove([x, y], [i, j])); + if (!!promoteInto && lastRanks.includes(i)) { + moves.push( + this.getBasicMove( + [x, y], [i, j], { c: color, p: promoteInto }) + ); + } + if (oneStep) continue outerLoop; + i += step[0]; + j += step[1]; + } + if (V.OnBoard(i, j) && this.canTake([x, y], [i, j])) { + if (i != lastRanks[0] || !forcePromoteOnLastRank) + moves.push(this.getBasicMove([x, y], [i, j])); + if (!!promoteInto && lastRanks.includes(i)) { + moves.push( + this.getBasicMove( + [x, y], [i, j], { c: color, p: promoteInto }) + ); + } + } + } + return moves; + } + + getPotentialGoldMoves(sq) { + const forward = (this.turn == 'w' ? -1 : 1); + return this.getSlideNJumpMoves( + sq, + V.steps[V.ROOK].concat([ [forward, 1], [forward, -1] ]), + { oneStep: true } + ); + } + + getPotentialPawnMoves(sq) { + const forward = (this.turn == 'w' ? -1 : 1); + return ( + this.getSlideNJumpMoves( + sq, + [[forward, 0]], + { + oneStep: true, + promote: V.P_PAWN, + force: true + } + ) + ); + } + + getPotentialSilverMoves(sq) { + const forward = (this.turn == 'w' ? -1 : 1); + return this.getSlideNJumpMoves( + sq, + V.steps[V.BISHOP].concat([ [forward, 0] ]), + { + oneStep: true, + promote: V.P_SILVER + } + ); + } + + getPotentialKnightMoves(sq) { + const forward = (this.turn == 'w' ? -2 : 2); + return this.getSlideNJumpMoves( + sq, + [ [forward, 1], [forward, -1] ], + { + oneStep: true, + promote: V.P_KNIGHT, + force: true + } + ); + } + + getPotentialRookMoves(sq) { + return this.getSlideNJumpMoves( + sq, V.steps[V.ROOK], { promote: V.P_ROOK }); + } + + getPotentialBishopMoves(sq) { + return this.getSlideNJumpMoves( + sq, V.steps[V.BISHOP], { promote: V.P_BISHOP }); + } + + getPotentialLancerMoves(sq) { + const forward = (this.turn == 'w' ? -1 : 1); + return this.getSlideNJumpMoves( + sq, [[forward, 0]], { promote: V.P_LANCER }); + } + + getPotentialDragonMoves(sq) { + return ( + this.getSlideNJumpMoves(sq, V.steps[V.ROOK]).concat( + this.getSlideNJumpMoves(sq, V.steps[V.BISHOP], { oneStep: true })) + ); + } + + getPotentialHorseMoves(sq) { + return ( + this.getSlideNJumpMoves(sq, V.steps[V.BISHOP]).concat( + this.getSlideNJumpMoves(sq, V.steps[V.ROOK], { oneStep: true })) + ); + } + + getPotentialKingMoves(sq) { + return this.getSlideNJumpMoves( + sq, + V.steps[V.ROOK].concat(V.steps[V.BISHOP]), + { oneStep: true } + ); + } + + isAttacked(sq, color) { + return ( + this.isAttackedByPawn(sq, color) || + this.isAttackedByRook(sq, color) || + this.isAttackedByDragon(sq, color) || + this.isAttackedByKnight(sq, color) || + this.isAttackedByBishop(sq, color) || + this.isAttackedByHorse(sq, color) || + this.isAttackedByLancer(sq, color) || + this.isAttackedBySilver(sq, color) || + this.isAttackedByGold(sq, color) || + this.isAttackedByKing(sq, color) + ); + } + + isAttackedByGold([x, y], color) { + const shift = (color == 'w' ? 1 : -1); + for (let step of V.steps[V.ROOK].concat([[shift, 1], [shift, -1]])) { + const [i, j] = [x + step[0], y + step[1]]; + if ( + V.OnBoard(i, j) && + this.board[i][j] != V.EMPTY && + this.getColor(i, j) == color && + [V.GOLD_G, V.P_PAWN, V.P_SILVER, V.P_KNIGHT, V.P_LANCER] + .includes(this.getPiece(i, j)) + ) { + return true; + } + } + return false; + } + + isAttackedBySilver([x, y], color) { + const shift = (color == 'w' ? 1 : -1); + for (let step of V.steps[V.BISHOP].concat([[shift, 0]])) { + const [i, j] = [x + step[0], y + step[1]]; + if ( + V.OnBoard(i, j) && + this.board[i][j] != V.EMPTY && + this.getColor(i, j) == color && + this.getPiece(i, j) == V.SILVER_G + ) { + return true; + } + } + return false; + } + + isAttackedByPawn([x, y], color) { + const shift = (color == 'w' ? 1 : -1); + const [i, j] = [x + shift, y]; + return ( + V.OnBoard(i, j) && + this.board[i][j] != V.EMPTY && + this.getColor(i, j) == color && + this.getPiece(i, j) == V.PAWN + ); + } + + isAttackedByKnight(sq, color) { + const forward = (color == 'w' ? 2 : -2); + return this.isAttackedBySlideNJump( + sq, color, V.KNIGHT, [[forward, 1], [forward, -1]], "oneStep"); + } + + isAttackedByLancer(sq, color) { + const forward = (color == 'w' ? 1 : -1); + return this.isAttackedBySlideNJump(sq, color, V.LANCER, [[forward, 0]]); + } + + isAttackedByDragon(sq, color) { + return ( + this.isAttackedBySlideNJump(sq, color, V.P_ROOK, V.steps[V.ROOK]) || + this.isAttackedBySlideNJump( + sq, color, V.DRAGON, V.steps[V.BISHOP], "oneStep") + ); + } + + isAttackedByHorse(sq, color) { + return ( + this.isAttackedBySlideNJump(sq, color, V.P_BISHOP, V.steps[V.BISHOP]) || + this.isAttackedBySlideNJump( + sq, color, V.DRAGON, V.steps[V.ROOK], "oneStep") + ); + } + + getAllValidMoves() { + let moves = super.getAllPotentialMoves(); + const color = this.turn; + for (let i = 0; i < V.RESERVE_PIECES.length; i++) { + moves = moves.concat( + this.getReserveMoves([V.size.x + (color == "w" ? 0 : 1), i]) + ); + } + return this.filterValid(moves); + } + + atLeastOneMove() { + if (!super.atLeastOneMove()) { + // Search one reserve move + for (let i = 0; i < V.RESERVE_PIECES.length; i++) { + let moves = this.filterValid( + this.getReserveMoves([V.size.x + (this.turn == "w" ? 0 : 1), i]) + ); + if (moves.length > 0) return true; + } + return false; + } + return true; + } + + static get P_CORRESPONDANCES() { + return { + q: 'p', + o: 'n', + t: 's', + m: 'l', + d: 'r', + h: 'b' + }; + } + + static MayDecode(piece) { + if (Object.keys(V.P_CORRESPONDANCES).includes(piece)) + return V.P_CORRESPONDANCES[piece]; + return piece; + } + + postPlay(move) { + super.postPlay(move); + const color = move.appear[0].c; + if (move.vanish.length == 0) + // Drop unpromoted piece: + this.reserve[color][move.appear[0].p]--; + else if (move.vanish.length == 2) + // May capture a promoted piece: + this.reserve[color][V.MayDecode(move.vanish[1].p)]++; + } + + postUndo(move) { + super.postUndo(move); + const color = this.turn; + if (move.vanish.length == 0) + this.reserve[color][move.appear[0].p]++; + else if (move.vanish.length == 2) + this.reserve[color][V.MayDecode(move.vanish[1].p)]--; + } + + static get SEARCH_DEPTH() { + return 2; + } + + static get VALUES() { + // TODO: very arbitrary and wrong + return { + p: 1, + q: 3, + r: 5, + d: 6, + n: 2, + o: 3, + b: 3, + h: 4, + s: 3, + t: 3, + l: 2, + m: 3, + g: 3, + k: 1000, + } + } + + evalPosition() { + let evaluation = super.evalPosition(); + // Add reserves: + for (let i = 0; i < V.RESERVE_PIECES.length; i++) { + const p = V.RESERVE_PIECES[i]; + evaluation += this.reserve["w"][p] * V.VALUES[p]; + evaluation -= this.reserve["b"][p] * V.VALUES[p]; + } + return evaluation; + } + + getNotation(move) { + const finalSquare = V.CoordsToSquare(move.end); + if (move.vanish.length == 0) { + // Rebirth: + const piece = move.appear[0].p.toUpperCase(); + return (piece != 'P' ? piece : "") + "@" + finalSquare; + } + const piece = move.vanish[0].p.toUpperCase(); + return ( + (piece != 'P' || move.vanish.length == 2 ? piece : "") + + (move.vanish.length == 2 ? "x" : "") + + finalSquare + + ( + move.appear[0].p != move.vanish[0].p + ? "=" + move.appear[0].p.toUpperCase() + : "" + ) + ); + } +}; diff --git a/client/src/variants/Sittuyin.js b/client/src/variants/Sittuyin.js index f37eabf3..aae1890e 100644 --- a/client/src/variants/Sittuyin.js +++ b/client/src/variants/Sittuyin.js @@ -119,29 +119,20 @@ export class SittuyinRules extends ChessRules { getPotentialPawnMoves([x, y]) { const color = this.turn; - const [sizeX, sizeY] = [V.size.x, V.size.y]; const shiftX = V.PawnSpecs.directions[color]; let moves = []; - // NOTE: next condition is generally true (no pawn on last rank) - if (x + shiftX >= 0 && x + shiftX < sizeX) { - if (this.board[x + shiftX][y] == V.EMPTY) { + if (x + shiftX >= 0 && x + shiftX < 8) { + if (this.board[x + shiftX][y] == V.EMPTY) // One square forward moves.push(this.getBasicMove([x, y], [x + shiftX, y])); - } // Captures - if (V.PawnSpecs.canCapture) { - for (let shiftY of [-1, 1]) { - if ( - y + shiftY >= 0 && - y + shiftY < sizeY - ) { - if ( - this.board[x + shiftX][y + shiftY] != V.EMPTY && - this.canTake([x, y], [x + shiftX, y + shiftY]) - ) { - moves.push(this.getBasicMove([x, y], [x + shiftX, y + shiftY])); - } - } + for (let shiftY of [-1, 1]) { + if ( + y + shiftY >= 0 && y + shiftY < 8 && + this.board[x + shiftX][y + shiftY] != V.EMPTY && + this.canTake([x, y], [x + shiftX, y + shiftY]) + ) { + moves.push(this.getBasicMove([x, y], [x + shiftX, y + shiftY])); } } } diff --git a/client/src/views/Hall.vue b/client/src/views/Hall.vue index 411407f6..133a5f9e 100644 --- a/client/src/views/Hall.vue +++ b/client/src/views/Hall.vue @@ -241,7 +241,9 @@ export default { vid: parseInt(localStorage.getItem("vid")) || 0, to: "", //name of challenged player (if any) cadence: localStorage.getItem("cadence") || "", - randomness: parseInt(localStorage.getItem("challRandomness")) || 2, + randomness: + // Warning: randomness can be 0, then !!randomness is false + (parseInt(localStorage.getItem("challRandomness"))+1 || 3) - 1, // VariantRules object, stored to not interfere with // diagrams of targetted challenges: V: null, diff --git a/server/db/populate.sql b/server/db/populate.sql index a085aa12..91e92543 100644 --- a/server/db/populate.sql +++ b/server/db/populate.sql @@ -48,6 +48,7 @@ insert or ignore into Variants (name, description) values ('Knightrelay2', 'Move like a knight (v2)'), ('Losers', 'Get strong at self-mate'), ('Magnetic', 'Laws of attraction'), + ('Makruk', 'Thai Chess'), ('Maxima', 'Occupy the enemy palace'), ('Monochrome', 'All of the same color'), ('Monster', 'White move twice'), @@ -62,7 +63,9 @@ insert or ignore into Variants (name, description) values ('Royalrace', 'Kings cross the 11x11 board'), ('Rugby', 'Transform an essay'), ('Schess', 'Seirawan-Harper Chess'), + ('Shako', 'Non-conformism and utopia'), ('Shatranj', 'Ancient rules'), + ('Shogi', 'Japanese Chess'), ('Sittuyin', 'Burmese chess'), ('Suicide', 'Lose all pieces'), ('Suction', 'Attract opposite king'),