"pug-walk": "^1.1.7"
}
},
+ "pug-loader": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/pug-loader/-/pug-loader-2.4.0.tgz",
+ "integrity": "sha512-cD4bU2wmkZ1EEVyu0IfKOsh1F26KPva5oglO1Doc3knx8VpBIXmFHw16k9sITYIjQMCnRv1vb4vfQgy7VdR6eg==",
+ "dev": true,
+ "requires": {
+ "loader-utils": "^1.1.0",
+ "pug-walk": "^1.0.0",
+ "resolve": "^1.1.7"
+ }
+ },
"pug-parser": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-5.0.0.tgz",
},
"dependencies": {
"ajv-keywords": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz",
- "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=",
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.3.0.tgz",
+ "integrity": "sha512-CMzN9S62ZOO4sA/mJZIO4S++ZM7KFWzH3PPWkveLhy4OZ9i1/VatgwWMD46w/XbGCBy7Ye0gCk+Za6mmyfKK7g==",
"dev": true
},
"schema-utils": {
"lint-staged": "^8.1.0",
"node-sass": "^4.9.0",
"pug": "^2.0.3",
+ "pug-loader": "^2.4.0",
"pug-plain-loader": "^1.0.0",
"raw-loader": "^1.0.0",
"sass-loader": "^7.0.1",
--- /dev/null
+<script>
+import { store } from "@/store";
+import { ArrayFun } from "@/utils/array";
+export default {
+ name: "my-diagrammer",
+ props: ["fen","vname"],
+ data: {
+ function() {
+ return {
+ st: store.state,
+ // args: object with position (mandatory), and
+ // orientation, marks, shadow (optional)
+ args: this.parseFen(this.fen),
+ };
+ }
+ },
+ render(h) {
+ if (!window.V)
+ return;
+ // Obtain the array of pieces images names:
+ const board = V.GetBoard(this.args.position);
+ const orientation = this.args.orientation || "w";
+ const markArray = this.getMarkArray(this.args.marks);
+ const shadowArray = this.getShadowArray(this.args.shadow);
+// const [startX,startY,inc] = orientation == 'w'
+// ? [0, 0, 1]
+// : [V.size.x-1, V.size.y-1, -1];
+ const diagDiv = h(
+ 'div',
+ {
+ 'class': {
+ 'diagram': true,
+ },
+ },
+ [...Array(V.size.x).keys()].map(i => {
+ let ci = (orientation=='w' ? i : sizeX-i-1);
+ return h(
+ 'div',
+ {
+ 'class': {
+ 'row': true,
+ },
+ },
+ [...Array(V.size.y).keys()].map(j => {
+ let cj = (orientation=='w' ? j : sizeY-j-1);
+ let elems = [];
+ if (board[ci][cj] != V.EMPTY)
+ {
+ elems.push(
+ h(
+ 'img',
+ {
+ 'class': {
+ 'piece': true,
+ },
+ attrs: {
+ src: require("@/assets/images/pieces/" +
+ V.getPpath(board[ci][cj]) + ".svg"),
+ },
+ }
+ )
+ );
+ }
+ if (markArray.length > 0 && markArray[ci][cj])
+ {
+ elems.push(
+ h(
+ 'img',
+ {
+ 'class': {
+ 'mark-square': true,
+ },
+ attrs: {
+ src: "/images/mark.svg",
+ },
+ }
+ )
+ );
+ }
+ return h(
+ 'div',
+ {
+ 'class': {
+ 'board': true,
+ ['board'+V.size.y]: true,
+ 'light-square': (i+j)%2==0,
+ 'dark-square': (i+j)%2==1,
+ [this.st.bcolor]: true,
+ 'in-shadow': shadowArray.length > 0 && shadowArray[ci][cj],
+ },
+ },
+ elems
+ );
+ })
+ );
+ })
+ );
+ return diagDiv;
+ },
+ methods: {
+ parseFen: function(fen) {
+ const fenParts = fen.split(" ");
+ return {
+ position: fenParts[0],
+ marks: fenParts[1],
+ orientation: fenParts[2],
+ shadow: fenParts[3],
+ };
+ },
+ // Turn (human) marks into coordinates
+ getMarkArray: function(marks) {
+ if (!marks || marks == "-")
+ return [];
+ let markArray = ArrayFun.init(V.size.x, V.size.y, false);
+ const squares = marks.split(",");
+ for (let i=0; i<squares.length; i++)
+ {
+ const coords = V.SquareToCoords(squares[i]);
+ markArray[coords.x][coords.y] = true;
+ }
+ return markArray;
+ },
+ // Turn (human) shadow indications into coordinates
+ getShadowArray: function(shadow) {
+ if (!shadow || shadow == "-")
+ return [];
+ let shadowArray = ArrayFun.init(V.size.x, V.size.y, false);
+ const squares = shadow.split(",");
+ for (let i=0; i<squares.length; i++)
+ {
+ const rownum = V.size.x - parseInt(squares[i]);
+ if (!isNaN(rownum))
+ {
+ // Shadow a full row
+ for (let i=0; i<V.size.y; i++)
+ shadowArray[rownum][i] = true;
+ continue;
+ }
+ if (squares[i].length == 1)
+ {
+ // Shadow a full column
+ const colnum = V.ColumnToCoord(squares[i]);
+ for (let i=0; i<V.size.x; i++)
+ shadowArray[i][colnum] = true;
+ continue;
+ }
+ if (squares[i].indexOf("-") >= 0)
+ {
+ // Shadow a range of squares, horizontally or vertically
+ const firstLastSq = squares[i].split("-");
+ const range =
+ [
+ V.SquareToCoords(firstLastSq[0]),
+ V.SquareToCoords(firstLastSq[1])
+ ];
+ const step =
+ [
+ range[1].x == range[0].x
+ ? 0
+ : (range[1].x - range[0].x) / Math.abs(range[1].x - range[0].x),
+ range[1].y == range[0].y
+ ? 0
+ : (range[1].y - range[0].y) / Math.abs(range[1].y - range[0].y)
+ ];
+ // Convention: range always from smaller to larger number
+ for (let x=range[0].x, y=range[0].y; x <= range[1].x && y <= range[1].y;
+ x += step[0], y += step[1])
+ {
+ shadowArray[x][y] = true;
+ }
+ continue;
+ }
+ // Shadow just one square:
+ const coords = V.SquareToCoords(squares[i]);
+ shadowArray[coords.x][coords.y] = true;
+ }
+ return shadowArray;
+ },
+ },
+};
+</script>
--- /dev/null
+<!--<template :src="require(`@/rules/${vname}/${st.lang}.pug`)">
+</template>
+-->
+
+<template lang="pug">
+.section-content(v-html="content")
+</template>
+
+<script>
+import Diagrammer from "@/components/Diagrammer";
+import { store } from "@/store";
+export default {
+ name: "my-variant-rules",
+ components: {
+ Diagrammer,
+ },
+ props: ["vname"],
+ data: function() {
+ return {
+ st: store.state,
+ content: "",
+ };
+ },
+ watch: {
+ vname: function() {
+ this.loadVariantFile();
+ },
+ },
+ methods: {
+ loadVariantFile: function() {
+ if (this.vname != "_unknown")
+ {
+ // TODO (to understand): no loader required here ? Pug preset ?
+ const content = require("raw-loader!@/rules/" + this.vname + "/" + this.st.lang + ".pug");
+ console.log(content);
+ this.content = content;
+ }
+ },
+ },
+ created: function() {
+ this.loadVariantFile();
+ },
+};
+</script>
+
+<!--
+ TODO: template + script dans rules/Alice/en.pug (-> .vue), puis dynamic import ici ?!
+-->
figure.diagram-container
// TODO: sub-component + use pug-loader instead of raw-loader
- Diagram(:fen="rnbqkbnr/ppp1pppp/8/8/2p5/5O2/PP1PPPPP/RNBQKB1R")
- .diagram
+ Diagram(fen="rnbqkbnr/ppp1pppp/8/8/2p5/5O2/PP1PPPPP/RNBQKB1R" vname="Alice")
+ //.diagram
| fen:rnbqkbnr/ppp1pppp/8/8/2p5/5O2/PP1PPPPP/RNBQKB1R:
figcaption After the moves 1.Nf3 Pd5 2.Pc4 Sxc4
en arrivant sur une case occupée (avec une seule exception, détaillée plus bas).
figure.diagram-container
- .diagram
- | fen:rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR:
+ Diagrammer(fen="rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR" vname="Chess960")
figcaption Position de départ habituelle.
p.
+++ /dev/null
-import { ArrayFun } from "@/utils/array";
-
-// Turn (human) marks into coordinates
-function getMarkArray(marks)
-{
- if (!marks || marks == "-")
- return [];
- let markArray = ArrayFun.init(V.size.x, V.size.y, false);
- const squares = marks.split(",");
- for (let i=0; i<squares.length; i++)
- {
- const coords = V.SquareToCoords(squares[i]);
- markArray[coords.x][coords.y] = true;
- }
- return markArray;
-}
-
-// Turn (human) shadow indications into coordinates
-function getShadowArray(shadow)
-{
- if (!shadow || shadow == "-")
- return [];
- let shadowArray = ArrayFun.init(V.size.x, V.size.y, false);
- const squares = shadow.split(",");
- for (let i=0; i<squares.length; i++)
- {
- const rownum = V.size.x - parseInt(squares[i]);
- if (!isNaN(rownum))
- {
- // Shadow a full row
- for (let i=0; i<V.size.y; i++)
- shadowArray[rownum][i] = true;
- continue;
- }
- if (squares[i].length == 1)
- {
- // Shadow a full column
- const colnum = V.ColumnToCoord(squares[i]);
- for (let i=0; i<V.size.x; i++)
- shadowArray[i][colnum] = true;
- continue;
- }
- if (squares[i].indexOf("-") >= 0)
- {
- // Shadow a range of squares, horizontally or vertically
- const firstLastSq = squares[i].split("-");
- const range =
- [
- V.SquareToCoords(firstLastSq[0]),
- V.SquareToCoords(firstLastSq[1])
- ];
- const step =
- [
- range[1].x == range[0].x
- ? 0
- : (range[1].x - range[0].x) / Math.abs(range[1].x - range[0].x),
- range[1].y == range[0].y
- ? 0
- : (range[1].y - range[0].y) / Math.abs(range[1].y - range[0].y)
- ];
- // Convention: range always from smaller to larger number
- for (let x=range[0].x, y=range[0].y; x <= range[1].x && y <= range[1].y;
- x += step[0], y += step[1])
- {
- shadowArray[x][y] = true;
- }
- continue;
- }
- // Shadow just one square:
- const coords = V.SquareToCoords(squares[i]);
- shadowArray[coords.x][coords.y] = true;
- }
- return shadowArray;
-}
-
-// args: object with position (mandatory), and
-// orientation, marks, shadow (optional)
-export function getDiagram(args)
-{
- // Obtain the array of pieces images names:
- const board = V.GetBoard(args.position);
- const orientation = args.orientation || "w";
- const markArray = getMarkArray(args.marks);
- const shadowArray = getShadowArray(args.shadow);
- let boardDiv = "";
- const [startX,startY,inc] = orientation == 'w'
- ? [0, 0, 1]
- : [V.size.x-1, V.size.y-1, -1];
- for (let i=startX; i>=0 && i<V.size.x; i+=inc)
- {
- boardDiv += "<div class='row'>";
- for (let j=startY; j>=0 && j<V.size.y; j+=inc)
- {
- boardDiv += "<div class='board board" + V.size.y + " " +
- ((i+j)%2==0 ? "light-square-diag" : "dark-square-diag") +
- (shadowArray.length > 0 && shadowArray[i][j] ? " in-shadow" : "") +
- "'>";
- if (board[i][j] != V.EMPTY)
- {
- boardDiv += "<img :src='require(`@/assets/images/pieces/" +
- V.getPpath(board[i][j]) + ".svg`) class='piece'/>";
- }
- if (markArray.length > 0 && markArray[i][j])
- boardDiv += "<img src='/images/mark.svg' class='mark-square'/>";
- boardDiv += "</div>";
- }
- boardDiv += "</div>";
- }
- return boardDiv;
-}
| Beat the computer!
button(v-show="gameInProgress" @click="stopGame")
| Stop game
- div(v-show="display=='rules'" v-html="content" class="section-content")
+ VariantRules(v-show="display=='rules'" :vname="variant.name")
Game(v-show="display=='computer'" :gid-or-fen="fen"
:mode="mode" :sub-mode="subMode" :variant="variant"
@computer-think="gameInProgress=false" @game-over="stopGame")
<script>
import Game from "@/components/Game.vue";
import { store } from "@/store";
-import { getDiagram } from "@/utils/printDiagram";
+import VariantRules from "@/components/VariantRules";
export default {
name: 'my-rules',
components: {
Game,
+ VariantRules,
},
data: function() {
return {
st: store.state,
- variant: {id: 0, name: "Unknown"}, //...yet
- content: "",
+ variant: {id: 0, name: "_unknown"}, //...yet
display: "rules",
mode: "computer",
subMode: "", //'auto' for game CPU vs CPU
fen: "",
};
},
- mounted: async function() {
+ watch: {
+ $route: function(newRoute) {
+ this.tryChangeVariant(newRoute.params["vname"]);
+ },
+ },
+ created: async function() {
// NOTE: variant cannot be set before store is initialized
- const vname = this.$route.params["vname"];
- //const idxOfVar = this.st.variants.indexOf(e => e.name == vname);
- //this.variant = this.st.variants[idxOfVar]; //TODO: is it the right timing?!
- this.variant.name = vname;
- const vModule = await import("@/variants/" + vname + ".js");
- window.V = vModule.VariantRules;
- // Method to replace diagrams in loaded HTML
- const replaceByDiag = (match, p1, p2) => {
- const args = this.parseFen(p2);
- return getDiagram(args);
- };
- // (AJAX) Request to get rules content (plain text, HTML)
- // TODO: find a way to have Diagram(er) as a component,
- // thus allowing images import through require(), handled by Webpack
- // ==> the rules files should be less static
- this.content =
- // TODO: why doesn't this work? require("raw-loader!pug-plain-loader!@/rules/"...)
- require("raw-loader!@/rules/" + vname + "/" + this.st.lang + ".pug")
- .replace(/(fen:)([^:]*):/g, replaceByDiag);
+ this.tryChangeVariant(this.$route.params["vname"]);
},
methods: {
- parseFen(fen) {
- const fenParts = fen.split(" ");
- return {
- position: fenParts[0],
- marks: fenParts[1],
- orientation: fenParts[2],
- shadow: fenParts[3],
- };
+ tryChangeVariant: async function(vname) {
+ if (vname == "_unknown")
+ return;
+ if (this.st.variants.length > 0)
+ {
+ const idxOfVar = this.st.variants.findIndex(e => e.name == vname);
+ this.variant = this.st.variants[idxOfVar];
+ }
+ else
+ this.variant.name = vname;
+ const vModule = await import("@/variants/" + vname + ".js");
+ window.V = vModule.VariantRules;
},
startGame: function() {
if (this.gameInProgress)