import React, { useState } from "react"; import "./Board.css"; const base = process.env.PUBLIC_URL; const assetsPath = `${base}/assets`; const Board = ({ game }) => { const rows = [3, 4, 5, 4, 3, 2]; /* The final row of 2 is to place roads and corners */ const [signature, setSignature] = useState(""); const [pips, setPips] = useState(<>); const [borders, setBorders] = useState(<>); const [tiles, setTiles] = useState(<>); const [corners, setCorners] = useState(<>); const [roads, setRoads] = useState(<>); const [transform, setTransform] = useState(1); const hexRatio = 1.1547, tileWidth = 67, tileHalfWidth = tileWidth * 0.5, tileHeight = tileWidth * hexRatio, tileHalfHeight = tileHeight * 0.5, radius = tileHeight * 2, borderOffset = 86; /* ~1/10th border image width... hand tuned */ /* Actual sizing */ const tileImageWidth = 90, /* Based on hand tuned and image width */ tileImageHeight = tileImageWidth/hexRatio, borderImageWidth = (2 + 2/3) * tileImageWidth, /* 2.667 * .Tile.width */ borderImageHeight = borderImageWidth * 0.29; /* 0.29 * .Border.height */ const Road = ({road}) => { const onClick = (event) => { console.log(`Road clicked: ${road.index}`); const nodes = document.querySelectorAll('.Road.Selected'); for (let i = 0; i < nodes.length; i++) { const el = nodes[i]; if (el !== event.target) { el.classList.remove('Selected'); } } event.target.classList.toggle('Selected'); }; return
; }; const Corner = ({corner}) => { const onClick = (event) => { console.log(`Corner clicked: ${corner.index}`); const nodes = document.querySelectorAll('.Corner.Selected'); for (let i = 0; i < nodes.length; i++) { const el = nodes[i]; if (el !== event.target) { el.classList.remove('Selected'); } } event.target.classList.toggle('Selected'); }; return
; }; const generateRoads = () => { let row = 0, rowCount = 0; let y = -2.5 + tileHalfWidth - (rows.length - 1) * 0.5 * tileWidth, x = -tileHalfHeight -(rows[row] - 1) * 0.5 * tileHeight; let index = 0; let road; const corners = []; for (let i = 0; i < 21; i++) { const lastRow = row === rows.length - 1; if (row > 2 && rowCount === 0) { road = { index: index++, angle: -60, top: y-0.5*tileHalfHeight, left: x-tileHalfHeight }; corners.push(); } road = { index: index++, angle: 240, top: y, left: x }; corners.push(); road = { index: index++, angle: -60, top: y-0.5*tileHalfHeight, left: x+tileHalfHeight }; corners.push(); if (!lastRow) { road = { index: index++, angle: 0, top: y, left: x }; corners.push(); } if (++rowCount === rows[row]) { if (!lastRow) { road = { index: index++, angle: 0, top: y, left: x+2.*tileHalfHeight }; corners.push(); } if (row > 2) { road = { index: index++, angle: 60, top: y-0.5*tileHalfHeight, left: x+3.*tileHalfHeight }; corners.push(); } row++; rowCount = 0; y += tileHeight - 10.5; x = -tileHalfHeight - (rows[row] - 1) * 0.5 * tileHeight; } else { x += tileHeight; } } return corners; } const generateCorners = () => { let row = 0, rowCount = 0; let y = -8 + 0.5 * tileHalfWidth - (rows.length - 1) * 0.5 * tileWidth, x = -tileHalfHeight -(rows[row] - 1) * 0.5 * tileHeight; let index = 0; const corners = []; let corner; for (let i = 0; i < 21; i++) { if (row > 2 && rowCount === 0) { corner = { index: index++, top: y-0.5*tileHalfHeight, left: x-tileHalfHeight }; corners.push(); } corner = { index: index++, top: y, left: x }; corners.push(); corner = { index: index++, top: y-0.5*tileHalfHeight, left: x+tileHalfHeight }; corners.push(); if (++rowCount === rows[row]) { corner = { index: index++, top: y, left: x+2.*tileHalfHeight }; corners.push(); if (row > 2) { corner = { index: index++, top: y-0.5*tileHalfHeight, left: x+3.*tileHalfHeight }; corners.push(); } row++; rowCount = 0; y += tileHeight - 10.5; x = -tileHalfHeight - (rows[row] - 1) * 0.5 * tileHeight; } else { x += tileHeight; } } return corners; } const generatePips = () => { let row = 0, rowCount = 0; let y = tileHalfWidth - (rows.length - 1) * 0.5 * tileWidth, x = -(rows[row] - 1) * 0.5 * tileHeight; return game.pipOrder.map(order => { const pip = game.pips[order]; const div =
; if (++rowCount === rows[row]) { row++; rowCount = 0; y += tileWidth; x = - (rows[row] - 1) * 0.5 * tileHeight; } else { x += tileHeight; } return div; }); }; const generateTiles = () => { let row = 0, rowCount = 0; let y = tileHalfWidth - (rows.length - 1) * 0.5 * tileWidth, x = -(rows[row] - 1) * 0.5 * tileHeight; return game.tileOrder.map(order => { const tile = game.tiles[order]; let div =
; if (++rowCount === rows[row]) { row++; rowCount = 0; y += tileWidth; x = - (rows[row] - 1) * 0.5 * tileHeight; } else { x += tileHeight; } return div; }); }; const generateBorders = () => { const sides = 6; let side = -1; return game.borderOrder.map(order => { const border = game.borders[order]; side++; let x = Math.sin(Math.PI - side / sides * 2. * Math.PI) * radius, y = Math.cos(Math.PI - side / sides * 2. * Math.PI) * radius; let prev = (order === 0) ? 6 : order; const file = `borders-${order+1}.${prev}.png`; return
; }); }; /* If the game is loaded, and the signature is different, * regenerate everything */ if (game && game.signature !== signature) { console.log(`Generate for ${game.signature}`); setPips(generatePips); setBorders(generateBorders); setTiles(generateTiles); setCorners(generateCorners); setRoads(generateRoads); setSignature(game.signature); } else { if (!game) { console.log(`No game in Board`); } } /* Adjust the 'transform: scale' for the BoardBox * so the board fills the Board */ const board = document.querySelector('.Board'); if (board) { const width = board.offsetWidth, height = board.offsetHeight; let _transform; if (width * hexRatio > height) { _transform = height / (450. * hexRatio); } else { _transform = width / (450. * hexRatio); } if (_transform !== transform) { const boardBox = board.querySelector('.BoardBox'); if (boardBox) { console.log(`Setting transofrm scale to ${_transform}`); boardBox.style.transform = `scale(${_transform})`; } setTransform(_transform); } } return (
{ borders } { tiles } { pips } { game && <>
{ corners }
{ roads }
}
); }; export default Board;