Fix display of Hiddenqueen diags in corr games
[vchess.git] / client / src / utils / printDiagram.js
CommitLineData
d7083722 1import { ArrayFun } from "@/utils/array";
4f524197 2import { store } from "@/store";
d7083722
BA
3
4// Turn (human) marks into coordinates
6808d7a1
BA
5function getMarkArray(marks) {
6 if (!marks || marks == "-") return [];
dac39588
BA
7 let markArray = ArrayFun.init(V.size.x, V.size.y, false);
8 const squares = marks.split(",");
6808d7a1 9 for (let i = 0; i < squares.length; i++) {
dac39588
BA
10 const coords = V.SquareToCoords(squares[i]);
11 markArray[coords.x][coords.y] = true;
12 }
13 return markArray;
d7083722
BA
14}
15
16// Turn (human) shadow indications into coordinates
6808d7a1
BA
17function getShadowArray(shadow) {
18 if (!shadow || shadow == "-") return [];
dac39588
BA
19 let shadowArray = ArrayFun.init(V.size.x, V.size.y, false);
20 const squares = shadow.split(",");
6808d7a1 21 for (let i = 0; i < squares.length; i++) {
e50a8025 22 const rownum = V.size.x - parseInt(squares[i], 10);
6808d7a1 23 if (!isNaN(rownum)) {
dac39588 24 // Shadow a full row
6808d7a1 25 for (let i = 0; i < V.size.y; i++) shadowArray[rownum][i] = true;
dac39588
BA
26 continue;
27 }
6808d7a1 28 if (squares[i].length == 1) {
dac39588
BA
29 // Shadow a full column
30 const colnum = V.ColumnToCoord(squares[i]);
6808d7a1 31 for (let i = 0; i < V.size.x; i++) shadowArray[i][colnum] = true;
dac39588
BA
32 continue;
33 }
6808d7a1 34 if (squares[i].indexOf("-") >= 0) {
dac39588
BA
35 // Shadow a range of squares, horizontally or vertically
36 const firstLastSq = squares[i].split("-");
6808d7a1 37 const range = [
dac39588
BA
38 V.SquareToCoords(firstLastSq[0]),
39 V.SquareToCoords(firstLastSq[1])
40 ];
6808d7a1 41 const step = [
dac39588
BA
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
6808d7a1
BA
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 ) {
dac39588
BA
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;
d7083722
BA
64}
65
66// args: object with position (mandatory), and
67// orientation, marks, shadow (optional)
4f524197
BA
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?
6808d7a1 72export function getDiagram(args) {
dac39588
BA
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);
7b6306a8 78 const vr = new V(); //TODO: just for pieces images paths
dac39588 79 let boardDiv = "";
6808d7a1
BA
80 const [startX, startY, inc] =
81 orientation == "w" ? [0, 0, 1] : [V.size.x - 1, V.size.y - 1, -1];
7b6306a8
BA
82 let lightOddity = (V.size.x + V.size.y) % 2;
83 if (V.DarkBottomRight) lightOddity = 1 - lightOddity;
6808d7a1 84 for (let i = startX; i >= 0 && i < V.size.x; i += inc) {
4f524197
BA
85 boardDiv += "<div class='row";
86 if (i == startX && V.Monochrome) boardDiv += " border-top";
87 boardDiv += "'>";
6808d7a1 88 for (let j = startY; j >= 0 && j < V.size.y; j += inc) {
4f524197
BA
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 }
7b6306a8
BA
95 else if ((i + j) % 2 == lightOddity) boardDiv += "light-square";
96 else boardDiv += "dark-square";
4f524197
BA
97 boardDiv += " " + store.state.settings.bcolor;
98 if (shadowArray.length > 0 && shadowArray[i][j])
99 boardDiv += " in-shadow";
100 boardDiv += "'>";
6808d7a1
BA
101 if (board[i][j] != V.EMPTY) {
102 boardDiv +=
103 "<img " +
104 "src='/images/pieces/" +
81452d4d 105 vr.getPpath(board[i][j], args.color, args.score, orientation) +
14edde72 106 V.IMAGE_EXTENSION + "' " +
d7083722 107 "class='piece'/>";
dac39588
BA
108 }
109 if (markArray.length > 0 && markArray[i][j])
2f8dce6a 110 boardDiv += "<img src='/images/diag_mark.svg' class='mark-square'/>";
dac39588
BA
111 boardDiv += "</div>";
112 }
113 boardDiv += "</div>";
114 }
115 return boardDiv;
d7083722 116}
07052665
BA
117
118// Method to replace diagrams in loaded HTML
119export 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}