|
129 | 129 | const labelColor = getLabelColor(boardColorHex); |
130 | 130 |
|
131 | 131 | // Constants from jade |
132 | | - const gridSize = 15; |
133 | | - const squareSize = 5; |
| 132 | + const gridSize = {{.BoardDimension}}; |
| 133 | + const squareSize = 5 * 15 / gridSize; // Scale so total board footprint is always 75 units |
134 | 134 | const boardThickness = 2; |
135 | 135 | const gridHeight = 1; |
136 | | - const tileDepth = 1.5; |
| 136 | + const tileDepth = 1.5 * 15 / gridSize; |
137 | 137 | const offset = (gridSize * squareSize) / 2 - squareSize / 2; |
138 | 138 | const boardTileZPos = boardThickness / 2 + gridHeight; |
139 | 139 |
|
|
143 | 143 | const rackDepth = 7; |
144 | 144 | const rackYPos = -38; |
145 | 145 |
|
146 | | - // Bonus square layout (Scrabble standard) |
147 | | - const gridLayout = [ |
148 | | - "= ' = ' =", |
149 | | - ' - " " - ', |
150 | | - " - ' ' - ", |
151 | | - "' - ' - '", |
152 | | - " - - ", |
153 | | - ' " " " " ', |
154 | | - " ' ' ' ' ", |
155 | | - "= ' - ' =", |
156 | | - " ' ' ' ' ", |
157 | | - ' " " " " ', |
158 | | - " - - ", |
159 | | - "' - ' - '", |
160 | | - " - ' ' - ", |
161 | | - ' - " " - ', |
162 | | - "= ' = ' =" |
163 | | - ]; |
| 146 | + // Bonus square layout (from game board) |
| 147 | + const gridLayout = {{.BoardLayout}}; |
164 | 148 |
|
165 | 149 | const bonusColors = { |
166 | 150 | '=': 0xcc5555, // Triple word (desaturated red) |
|
384 | 368 | if (score > 0) { |
385 | 369 | const scoreGeometry = new TextGeometry(score.toString(), { |
386 | 370 | font: font, |
387 | | - size: 1, |
| 371 | + size: squareSize * 0.2, |
388 | 372 | height: 0.1 // Some versions use 'height' instead of 'depth' |
389 | 373 | }); |
390 | 374 | const scoreMesh = new THREE.Mesh(scoreGeometry, letterMaterial); |
|
635 | 619 | // Grid configuration |
636 | 620 | const tilesPerRow = 5; |
637 | 621 | const tileSpacing = squareSize + 0.5; |
638 | | - const startX = offset + squareSize * 4.25; // Shift 2.25 tile widths to the right |
| 622 | + const startX = 55 + squareSize * 0.25; // Start just outside the circular board base (radius 55) |
639 | 623 | const startY = offset; // Start from top |
640 | 624 | const tableTopZ = -boardThickness / 2; // Table surface height |
641 | 625 |
|
|
707 | 691 | scene.add(base); |
708 | 692 |
|
709 | 693 | const gridBottomZPos = boardThickness / 2; |
710 | | - const wallThickness = 0.25; |
711 | | - const wallHeight = 0.55; |
| 694 | + const wallThickness = squareSize * 0.05; |
| 695 | + const wallHeight = squareSize * 0.11; |
712 | 696 |
|
713 | 697 | // Create grid squares |
714 | 698 | for (let i = 0; i < gridSize; i++) { |
|
782 | 766 | const labelText = bonusLabels[bonusType]; |
783 | 767 | const labelGeom = new TextGeometry(labelText, { |
784 | 768 | font: font, |
785 | | - size: 1.4, |
| 769 | + size: squareSize * 0.28, |
786 | 770 | height: 0.02, // Some versions use 'height' instead of 'depth' |
787 | 771 | curveSegments: 4, |
788 | 772 | bevelEnabled: false |
|
805 | 789 | } |
806 | 790 | } |
807 | 791 |
|
808 | | - // Add column labels (A-O) |
809 | | - const columns = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O']; |
| 792 | + // Add column labels (A through the board dimension) |
| 793 | + const columns = Array.from({ length: gridSize }, (_, i) => String.fromCharCode(65 + i)); |
810 | 794 | columns.forEach((letter, index) => { |
811 | 795 | const geometry = new TextGeometry(letter, { |
812 | 796 | font: font, |
813 | | - size: 1.875, |
| 797 | + size: squareSize * 0.375, |
814 | 798 | height: 0.05, // Some versions use 'height' instead of 'depth' |
815 | 799 | curveSegments: 8, |
816 | 800 | bevelEnabled: false |
|
826 | 810 | }); |
827 | 811 |
|
828 | 812 | // Add row labels (1-15) |
829 | | - for (let i = 0; i < 15; i++) { |
| 813 | + for (let i = 0; i < gridSize; i++) { |
830 | 814 | const number = (i + 1).toString(); |
831 | 815 | const geometry = new TextGeometry(number, { |
832 | 816 | font: font, |
833 | | - size: 1.875, |
| 817 | + size: squareSize * 0.375, |
834 | 818 | height: 0.05, // Some versions use 'height' instead of 'depth' |
835 | 819 | curveSegments: 8, |
836 | 820 | bevelEnabled: false |
837 | 821 | }); |
838 | 822 | const material = new THREE.MeshBasicMaterial({ color: labelColor }); |
839 | 823 | const mesh = new THREE.Mesh(geometry, material); |
840 | | - const textWidth = number.length * 1.5; |
| 824 | + const textWidth = number.length * squareSize * 0.3; |
841 | 825 | mesh.position.set( |
842 | 826 | -offset - squareSize * 0.65 - textWidth, |
843 | | - (14 - i) * squareSize - offset - squareSize / 4, |
| 827 | + (gridSize - 1 - i) * squareSize - offset - squareSize / 4, |
844 | 828 | boardThickness / 2 + 0.01 |
845 | 829 | ); |
846 | 830 | scene.add(mesh); |
|
0 commit comments