Skip to content

Commit d0b6f97

Browse files
committed
allow render of super boards
1 parent 097f7ca commit d0b6f97

File tree

2 files changed

+36
-33
lines changed

2 files changed

+36
-33
lines changed

shell/api.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ type RenderTemplateData struct {
6161
PlayerOnTurn int // 0 or 1 - which player is on turn
6262
LastPlay string // Last play summary
6363
AlphabetScores template.JS // JSON map of letter → score for the current alphabet
64+
BoardLayout template.JS // JSON array of strings, one per row, using bonus square symbols
65+
BoardDimension int // Board size (15 for standard, 21 for super)
6466
}
6567

6668
type Response struct {
@@ -1429,6 +1431,21 @@ func (sc *ShellController) render3D(cmd *shellcmd) (*Response, error) {
14291431
alphabetScoresJSON = []byte("{}")
14301432
}
14311433

1434+
// Build board layout from the actual game board bonuses
1435+
dim := board.Dim()
1436+
layoutRows := make([]string, dim)
1437+
for row := 0; row < dim; row++ {
1438+
rowBytes := make([]byte, dim)
1439+
for col := 0; col < dim; col++ {
1440+
rowBytes[col] = byte(board.GetBonus(row, col))
1441+
}
1442+
layoutRows[row] = string(rowBytes)
1443+
}
1444+
boardLayoutJSON, err := json.Marshal(layoutRows)
1445+
if err != nil {
1446+
boardLayoutJSON = []byte("[]")
1447+
}
1448+
14321449
// Prepare template data
14331450
data := RenderTemplateData{
14341451
FEN: fen,
@@ -1447,6 +1464,8 @@ func (sc *ShellController) render3D(cmd *shellcmd) (*Response, error) {
14471464
PlayerOnTurn: sc.game.PlayerOnTurn(),
14481465
LastPlay: lastPlay,
14491466
AlphabetScores: template.JS(alphabetScoresJSON),
1467+
BoardLayout: template.JS(boardLayoutJSON),
1468+
BoardDimension: dim,
14501469
}
14511470

14521471
// Parse and execute template

shell/render_template.html

Lines changed: 17 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,11 @@
129129
const labelColor = getLabelColor(boardColorHex);
130130

131131
// 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
134134
const boardThickness = 2;
135135
const gridHeight = 1;
136-
const tileDepth = 1.5;
136+
const tileDepth = 1.5 * 15 / gridSize;
137137
const offset = (gridSize * squareSize) / 2 - squareSize / 2;
138138
const boardTileZPos = boardThickness / 2 + gridHeight;
139139

@@ -143,24 +143,8 @@
143143
const rackDepth = 7;
144144
const rackYPos = -38;
145145

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}};
164148

165149
const bonusColors = {
166150
'=': 0xcc5555, // Triple word (desaturated red)
@@ -384,7 +368,7 @@
384368
if (score > 0) {
385369
const scoreGeometry = new TextGeometry(score.toString(), {
386370
font: font,
387-
size: 1,
371+
size: squareSize * 0.2,
388372
height: 0.1 // Some versions use 'height' instead of 'depth'
389373
});
390374
const scoreMesh = new THREE.Mesh(scoreGeometry, letterMaterial);
@@ -635,7 +619,7 @@
635619
// Grid configuration
636620
const tilesPerRow = 5;
637621
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)
639623
const startY = offset; // Start from top
640624
const tableTopZ = -boardThickness / 2; // Table surface height
641625

@@ -707,8 +691,8 @@
707691
scene.add(base);
708692

709693
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;
712696

713697
// Create grid squares
714698
for (let i = 0; i < gridSize; i++) {
@@ -782,7 +766,7 @@
782766
const labelText = bonusLabels[bonusType];
783767
const labelGeom = new TextGeometry(labelText, {
784768
font: font,
785-
size: 1.4,
769+
size: squareSize * 0.28,
786770
height: 0.02, // Some versions use 'height' instead of 'depth'
787771
curveSegments: 4,
788772
bevelEnabled: false
@@ -805,12 +789,12 @@
805789
}
806790
}
807791

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));
810794
columns.forEach((letter, index) => {
811795
const geometry = new TextGeometry(letter, {
812796
font: font,
813-
size: 1.875,
797+
size: squareSize * 0.375,
814798
height: 0.05, // Some versions use 'height' instead of 'depth'
815799
curveSegments: 8,
816800
bevelEnabled: false
@@ -826,21 +810,21 @@
826810
});
827811

828812
// Add row labels (1-15)
829-
for (let i = 0; i < 15; i++) {
813+
for (let i = 0; i < gridSize; i++) {
830814
const number = (i + 1).toString();
831815
const geometry = new TextGeometry(number, {
832816
font: font,
833-
size: 1.875,
817+
size: squareSize * 0.375,
834818
height: 0.05, // Some versions use 'height' instead of 'depth'
835819
curveSegments: 8,
836820
bevelEnabled: false
837821
});
838822
const material = new THREE.MeshBasicMaterial({ color: labelColor });
839823
const mesh = new THREE.Mesh(geometry, material);
840-
const textWidth = number.length * 1.5;
824+
const textWidth = number.length * squareSize * 0.3;
841825
mesh.position.set(
842826
-offset - squareSize * 0.65 - textWidth,
843-
(14 - i) * squareSize - offset - squareSize / 4,
827+
(gridSize - 1 - i) * squareSize - offset - squareSize / 4,
844828
boardThickness / 2 + 0.01
845829
);
846830
scene.add(mesh);

0 commit comments

Comments
 (0)