import React, { useEffect, useRef, useState } from "https://esm.sh/react"
import { createRoot } from "https://esm.sh/react-dom/client"
const BOARD_SIZE = 5
const HUE_DIFF = 25
function getColor(value: number): string {
const power = Math.log2(value / 2)
const hue = (power * HUE_DIFF) % 360
return `hsl(${hue}, 50%, 50%)`
}
function App() {
const [board, setBoard] = useState<number[][]>([])
const [selectedCells, setSelectedCells] = useState<[number, number][]>([])
const [score, setScore] = useState(0)
const [isDragging, setIsDragging] = useState(false)
const [animatingCells, setAnimatingCells] = useState<[number, number][]>([])
const [newCells, setNewCells] = useState<[number, number][]>([])
const [showInfo, setShowInfo] = useState(false)
const boardRef = useRef<HTMLDivElement>(null)
useEffect(() => {
initializeBoard()
}, [])
const initializeBoard = () => {
const newBoard = Array(BOARD_SIZE).fill(null).map(() =>
Array(BOARD_SIZE).fill(null).map(() => Math.pow(2, Math.floor(Math.random() * 5) + 1))
)
setBoard(newBoard)
setSelectedCells([])
setScore(0)
setNewCells(newBoard.flatMap((row, i) => row.map((_, j) => [i, j] as [number, number])))
setTimeout(() => setNewCells([]), 500)
}
const handleTouchStart = (row: number, col: number) => {
setIsDragging(true)
setSelectedCells([[row, col]])
}
const handleTouchMove = (e: React.TouchEvent) => {
if (!isDragging || !boardRef.current) return
const touch = e.touches[0]
const board = boardRef.current
const rect = board.getBoundingClientRect()
const x = touch.clientX - rect.left
const y = touch.clientY - rect.top
const cellSize = rect.width / BOARD_SIZE
const row = Math.floor(y / cellSize)
const col = Math.floor(x / cellSize)
if (row >= 0 && row < BOARD_SIZE && col >= 0 && col < BOARD_SIZE) {
handleCellEnter(row, col)
}
}
const handleTouchEnd = () => {
setIsDragging(false)
if (selectedCells.length > 1) {
processChain()
} else {
setSelectedCells([])
}
}
const handleMouseDown = (row: number, col: number) => {
setIsDragging(true)
setSelectedCells([[row, col]])
}
const handleMouseEnter = (row: number, col: number) => {
if (!isDragging) return
handleCellEnter(row, col)
}
const handleMouseUp = () => {
handleTouchEnd()
}
const handleCellEnter = (row: number, col: number) => {
setSelectedCells(prev => {
if (prev.length === 0) return [[row, col]]
const lastSelected = prev[prev.length - 1]
if (
isValidCell(lastSelected) && isValidCell([row, col])
&& isAdjacent(lastSelected, [row, col])
&& board[row][col] === board[lastSelected[0]][lastSelected[1]]
&& !prev.some(cell => isValidCell(cell) && cell[0] === row && cell[1] === col)
) {
return [...prev, [row, col]]
}
return prev