Real-time two-player Connect 4 using Via framework with: - Game creation and invite links - SSE-based live updates for both players - Win detection with animated highlighting - Session-based nickname persistence
61 lines
1.4 KiB
Go
61 lines
1.4 KiB
Go
package ui
|
|
|
|
import (
|
|
"github.com/ryanhamamura/c4/game"
|
|
"github.com/ryanhamamura/via/h"
|
|
)
|
|
|
|
// ColumnClickFn returns an h.H onClick attribute for a given column index
|
|
type ColumnClickFn func(col int) h.H
|
|
|
|
func BoardComponent(g *game.Game, columnClick ColumnClickFn, myColor int) h.H {
|
|
var cols []h.H
|
|
|
|
for col := 0; col < 7; col++ {
|
|
var cells []h.H
|
|
for row := 0; row < 6; row++ {
|
|
cellColor := g.Board[row][col]
|
|
isWinning := g.IsWinningCell(row, col)
|
|
cells = append(cells, Cell(cellColor, isWinning))
|
|
}
|
|
|
|
// Column is clickable only if it's player's turn and game is in progress
|
|
canClick := g.Status == game.StatusInProgress && g.CurrentTurn == myColor
|
|
cols = append(cols, Column(col, cells, columnClick, canClick))
|
|
}
|
|
|
|
boardAttrs := []h.H{h.Class("board")}
|
|
boardAttrs = append(boardAttrs, cols...)
|
|
return h.Div(boardAttrs...)
|
|
}
|
|
|
|
func Column(colIdx int, cells []h.H, columnClick ColumnClickFn, canClick bool) h.H {
|
|
class := "column"
|
|
if canClick {
|
|
class += " clickable"
|
|
}
|
|
|
|
attrs := []h.H{h.Class(class)}
|
|
|
|
if canClick && columnClick != nil {
|
|
attrs = append(attrs, columnClick(colIdx))
|
|
}
|
|
|
|
attrs = append(attrs, cells...)
|
|
return h.Div(attrs...)
|
|
}
|
|
|
|
func Cell(color int, isWinning bool) h.H {
|
|
class := "cell"
|
|
switch color {
|
|
case 1:
|
|
class += " red"
|
|
case 2:
|
|
class += " yellow"
|
|
}
|
|
if isWinning {
|
|
class += " winning"
|
|
}
|
|
return h.Div(h.Class(class))
|
|
}
|