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