Experimental in-page analyze + show rules from Game page
[vchess.git] / client / src / utils / printDiagram.js
1 import { ArrayFun } from "@/utils/array";
2
3 // Turn (human) marks into coordinates
4 function getMarkArray(marks) {
5 if (!marks || marks == "-") return [];
6 let markArray = ArrayFun.init(V.size.x, V.size.y, false);
7 const squares = marks.split(",");
8 for (let i = 0; i < squares.length; i++) {
9 const coords = V.SquareToCoords(squares[i]);
10 markArray[coords.x][coords.y] = true;
11 }
12 return markArray;
13 }
14
15 // Turn (human) shadow indications into coordinates
16 function getShadowArray(shadow) {
17 if (!shadow || shadow == "-") return [];
18 let shadowArray = ArrayFun.init(V.size.x, V.size.y, false);
19 const squares = shadow.split(",");
20 for (let i = 0; i < squares.length; i++) {
21 const rownum = V.size.x - parseInt(squares[i]);
22 if (!isNaN(rownum)) {
23 // Shadow a full row
24 for (let i = 0; i < V.size.y; i++) shadowArray[rownum][i] = true;
25 continue;
26 }
27 if (squares[i].length == 1) {
28 // Shadow a full column
29 const colnum = V.ColumnToCoord(squares[i]);
30 for (let i = 0; i < V.size.x; i++) shadowArray[i][colnum] = true;
31 continue;
32 }
33 if (squares[i].indexOf("-") >= 0) {
34 // Shadow a range of squares, horizontally or vertically
35 const firstLastSq = squares[i].split("-");
36 const range = [
37 V.SquareToCoords(firstLastSq[0]),
38 V.SquareToCoords(firstLastSq[1])
39 ];
40 const step = [
41 range[1].x == range[0].x
42 ? 0
43 : (range[1].x - range[0].x) / Math.abs(range[1].x - range[0].x),
44 range[1].y == range[0].y
45 ? 0
46 : (range[1].y - range[0].y) / Math.abs(range[1].y - range[0].y)
47 ];
48 // Convention: range always from smaller to larger number
49 for (
50 let x = range[0].x, y = range[0].y;
51 x <= range[1].x && y <= range[1].y;
52 x += step[0], y += step[1]
53 ) {
54 shadowArray[x][y] = true;
55 }
56 continue;
57 }
58 // Shadow just one square:
59 const coords = V.SquareToCoords(squares[i]);
60 shadowArray[coords.x][coords.y] = true;
61 }
62 return shadowArray;
63 }
64
65 // args: object with position (mandatory), and
66 // orientation, marks, shadow (optional)
67 export function getDiagram(args) {
68 // Obtain the array of pieces images names:
69 const board = V.GetBoard(args.position);
70 const orientation = args.orientation || "w";
71 const markArray = getMarkArray(args.marks);
72 const shadowArray = getShadowArray(args.shadow);
73 const vr = new V(); //just for pieces images paths
74 let boardDiv = "";
75 const [startX, startY, inc] =
76 orientation == "w" ? [0, 0, 1] : [V.size.x - 1, V.size.y - 1, -1];
77 for (let i = startX; i >= 0 && i < V.size.x; i += inc) {
78 boardDiv += "<div class='row'>";
79 for (let j = startY; j >= 0 && j < V.size.y; j += inc) {
80 boardDiv +=
81 "<div class='board board" +
82 V.size.y +
83 " " +
84 ((i + j) % 2 == 0 ? "light-square-diag" : "dark-square-diag") +
85 (shadowArray.length > 0 && shadowArray[i][j] ? " in-shadow" : "") +
86 "'>";
87 if (board[i][j] != V.EMPTY) {
88 boardDiv +=
89 "<img " +
90 "src='/images/pieces/" +
91 vr.getPpath(board[i][j], null, null, orientation) +
92 V.IMAGE_EXTENSION + "' " +
93 "class='piece'/>";
94 }
95 if (markArray.length > 0 && markArray[i][j])
96 boardDiv += "<img src='/images/diag_mark.svg' class='mark-square'/>";
97 boardDiv += "</div>";
98 }
99 boardDiv += "</div>";
100 }
101 return boardDiv;
102 }
103
104 // Method to replace diagrams in loaded HTML
105 export function replaceByDiag(match, p1, p2) {
106 const diagParts = p2.split(" ");
107 return getDiagram({
108 position: diagParts[0],
109 marks: diagParts[1],
110 orientation: diagParts[2],
111 shadow: diagParts[3]
112 });
113 }