Skip to content

Commit 7f38e6d

Browse files
committed
fix safari issue
1 parent 7cb10a1 commit 7f38e6d

File tree

1 file changed

+112
-138
lines changed

1 file changed

+112
-138
lines changed

components/visuals/bitboards/bitboard-visualizer.tsx

Lines changed: 112 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -2,137 +2,126 @@ import { useEffect, useState } from "react"
22
import Code from "../../code"
33

44
export interface BitboardStep {
5-
highlightLines: number[] // Which lines of code to highlight (1-based)
6-
board: bigint | string // Bitboard after this step (64-bit integer)
5+
highlightLines: number[] // Which lines of code to highlight (1-based)
6+
board: bigint | string // Bitboard after this step (64-bit integer)
77
}
88

99
interface BitboardVisualizerProps {
10-
codeLines: string[] // Static array of code lines (shown left-side)
11-
steps: BitboardStep[] // Step-by-step transitions (each step updates the board and highlights lines)
12-
stepDelay?: number // Optional delay between steps (ms), default = 2000
10+
codeLines: string[] // Static array of code lines (shown left-side)
11+
steps: BitboardStep[] // Step-by-step transitions (each step updates the board and highlights lines)
12+
stepDelay?: number // Optional delay between steps (ms), default = 2000
1313
}
1414

1515
export default function BitboardVisualizer({ codeLines, steps, stepDelay = 2000 }: BitboardVisualizerProps) {
16-
const [currentStepIndex, setCurrentStepIndex] = useState(0)
17-
const [bitIndices, setBitIndices] = useState<number[]>([])
18-
19-
// Ensure we have valid steps and a valid current step
20-
const currentStep = steps && steps.length > 0 ? steps[currentStepIndex] : { highlightLines: [], board: BigInt(0) }
21-
const boardValue =
22-
currentStep && typeof currentStep.board === "string" ? BigInt(currentStep.board) : currentStep?.board || BigInt(0)
23-
24-
// Convert bitboard to binary string (padded to 64 bits)
25-
const binaryString = boardValue.toString(2).padStart(64, "0")
26-
// Split binary string into groups of 8 bits with spaces between
27-
const formattedBinary = binaryString.match(/.{1,8}/g)?.join(" ") || binaryString
28-
29-
// Calculate which bits are set (1)
30-
useEffect(() => {
31-
const indices: number[] = []
32-
const boardValueBigInt = typeof boardValue === 'string' ? BigInt(boardValue) : boardValue
33-
for (let i = 0; i < 64; i++) {
34-
if ((boardValueBigInt & (BigInt(1) << BigInt(i))) !== BigInt(0)) {
35-
indices.push(i)
36-
}
37-
}
38-
setBitIndices(indices)
39-
}, [boardValue])
40-
41-
// Auto-advance steps
42-
useEffect(() => {
43-
const timer = setTimeout(() => {
44-
setCurrentStepIndex((prevIndex) => (prevIndex + 1) % steps.length)
45-
}, stepDelay)
46-
47-
return () => clearTimeout(timer)
48-
}, [currentStepIndex, stepDelay, steps.length])
49-
50-
// Check if a bit is set at a specific position
51-
const isBitSet = (position: number) => {
52-
const boardValueBigInt = typeof boardValue === 'string' ? BigInt(boardValue) : boardValue
53-
return (boardValueBigInt & (BigInt(1) << BigInt(position))) !== BigInt(0)
16+
const [currentStepIndex, setCurrentStepIndex] = useState(0)
17+
const [bitIndices, setBitIndices] = useState<number[]>([])
18+
19+
// Ensure we have valid steps and a valid current step
20+
const currentStep = steps && steps.length > 0 ? steps[currentStepIndex] : { highlightLines: [], board: BigInt(0) }
21+
const boardValue =
22+
currentStep && typeof currentStep.board === "string" ? BigInt(currentStep.board) : currentStep?.board || BigInt(0)
23+
24+
// Convert bitboard to binary string (padded to 64 bits)
25+
const binaryString = boardValue.toString(2).padStart(64, "0")
26+
// Split binary string into groups of 8 bits with spaces between
27+
const formattedBinary = binaryString.match(/.{1,8}/g)?.join(" ") || binaryString
28+
29+
// Calculate which bits are set (1)
30+
useEffect(() => {
31+
const indices: number[] = []
32+
const boardValueBigInt = typeof boardValue === 'string' ? BigInt(boardValue) : boardValue
33+
for (let i = 0; i < 64; i++) {
34+
if ((boardValueBigInt & (BigInt(1) << BigInt(i))) !== BigInt(0)) {
35+
indices.push(i)
36+
}
5437
}
55-
56-
// Get file letter (A-H) from column index (0-7)
57-
const getFile = (col: number) => String.fromCharCode(72 - col) // H to A (reversed)
58-
59-
// Get rank number (1-8) from row index (0-7)
60-
const getRank = (row: number) => 8 - row // 8 to 1 (reversed)
61-
62-
return (
63-
<div className="visualizer-container">
64-
{/* Main content - responsive layout */}
65-
<div className="visualizer-content">
66-
{/* Left side - Code display */}
67-
<pre>
68-
<Code options={{ highlightLines: currentStep?.highlightLines.map(line => line - 1) }}
69-
language="javascript"
70-
children={codeLines.join("\n")}
71-
/>
72-
</pre>
73-
74-
<div className="board-container">
75-
<div className="chessboard">
76-
77-
{/* Chessboard view */}
78-
<div className="board-grid">
79-
{Array.from({ length: 64 }).map((_, index) => {
80-
const row = Math.floor(index / 8)
81-
const col = index % 8
82-
const position = row * 8 + col
83-
const isDarkSquare = (row + col) % 2 === 1
84-
const bitValue = isBitSet(position)
85-
86-
return (
87-
<div
88-
key={index}
89-
className={
90-
isDarkSquare
91-
? bitValue
92-
? "square dark-square bit-set"
93-
: "square dark-square"
94-
: bitValue
95-
? "square light-square bit-set"
96-
: "square light-square"
97-
}
98-
>
99-
<div className={bitValue ? "bit-overlay visible" : "bit-overlay"} />
100-
<span className="square-coord">
101-
{getFile(col)}
102-
{getRank(row)}
103-
</span>
104-
<span className="square-index">{position}</span>
105-
</div>
106-
)
107-
})}
108-
</div>
109-
110-
{/* Bitboard representations */}
111-
<div className="bitboard-info">
112-
<div className="info-item">
113-
<span className="info-label">Binary: </span>
114-
<span className="info-value binary">{formattedBinary}</span>
115-
</div>
116-
<div className="info-item">
117-
<span className="info-label">Set bits: </span>
118-
<span className="info-value">{bitIndices.length > 0 ? bitIndices.join(", ") : "none"}</span>
119-
</div>
120-
</div>
121-
</div>
38+
setBitIndices(indices)
39+
}, [boardValue])
40+
41+
// Auto-advance steps
42+
useEffect(() => {
43+
const timer = setTimeout(() => {
44+
setCurrentStepIndex((prevIndex) => (prevIndex + 1) % steps.length)
45+
}, stepDelay)
46+
47+
return () => clearTimeout(timer)
48+
}, [currentStepIndex, stepDelay, steps.length])
49+
50+
// Check if a bit is set at a specific position
51+
const isBitSet = (position: number) => {
52+
const boardValueBigInt = typeof boardValue === 'string' ? BigInt(boardValue) : boardValue
53+
return (boardValueBigInt & (BigInt(1) << BigInt(position))) !== BigInt(0)
54+
}
55+
56+
// Get file letter (A-H) from column index (0-7)
57+
const getFile = (col: number) => String.fromCharCode(72 - col) // H to A (reversed)
58+
59+
// Get rank number (1-8) from row index (0-7)
60+
const getRank = (row: number) => 8 - row // 8 to 1 (reversed)
61+
62+
return (
63+
<div className="visualizer-container">
64+
<pre>
65+
<Code options={{ highlightLines: currentStep?.highlightLines.map(line => line - 1) }}
66+
language="javascript"
67+
children={codeLines.join("\n")}
68+
/>
69+
</pre>
70+
71+
<div className="board-container">
72+
<div className="chessboard">
73+
74+
<div className="board-grid">
75+
{Array.from({ length: 64 }).map((_, index) => {
76+
const row = Math.floor(index / 8)
77+
const col = index % 8
78+
const position = row * 8 + col
79+
const isDarkSquare = (row + col) % 2 === 1
80+
const bitValue = isBitSet(position)
81+
82+
return (
83+
<div
84+
key={index}
85+
className={
86+
isDarkSquare
87+
? bitValue
88+
? "square dark-square bit-set"
89+
: "square dark-square"
90+
: bitValue
91+
? "square light-square bit-set"
92+
: "square light-square"
93+
}
94+
>
95+
<div className={bitValue ? "bit-overlay visible" : "bit-overlay"} />
96+
<span className="square-coord">
97+
{getFile(col)}
98+
{getRank(row)}
99+
</span>
100+
<span className="square-index">{position}</span>
122101
</div>
123-
</div>
102+
)
103+
})}
104+
</div>
105+
</div>
106+
<div className="bitboard-info">
107+
<div className="info-item">
108+
<span className="info-label">Binary: </span>
109+
<span className="info-value binary">{formattedBinary}</span>
110+
</div>
111+
<div className="info-item">
112+
<span className="info-label">Set bits: </span>
113+
<span className="info-value">{bitIndices.length > 0 ? bitIndices.join(", ") : "none"}</span>
114+
</div>
115+
</div>
116+
</div>
124117

125-
<style jsx>{`
118+
<style jsx>{`
126119
.visualizer-container {
127120
width: 100%;
128121
max-width: 1200px;
129122
margin: 0 auto;
130123
}
131124
132-
.visualizer-content {
133-
display: block;
134-
}
135-
136125
.code-line.highlighted {
137126
background-color: #fef3c7;
138127
border-left: 4px solid #f59e0b;
@@ -205,37 +194,22 @@ export default function BitboardVisualizer({ codeLines, steps, stepDelay = 2000
205194
}
206195
207196
.bitboard-info {
197+
margin-left: auto;
198+
margin-right: auto;
199+
width: 100%;
200+
max-width: 448px;
208201
margin-top: 0.25rem;
209-
margin-bottom: 0.25rem;
210-
display: flex;
211-
flex-direction: column;
212-
gap: 0.25rem;
213202
font-family: "IBM Plex Mono", monospace;
214203
font-size: 0.875rem;
215-
width: 100%;
216-
max-width: 448px;
217-
margin-left: auto;
218-
margin-right: auto;
219204
}
220205
221206
.info-item {
222207
padding: 0.5rem;
223208
background-color: #f9fafb;
224209
border-radius: 0.25rem;
225-
}
226-
227-
.info-item.binary {
228-
overflow-x: auto;
229-
}
230-
231-
.info-value {
232-
white-space: normal;
233-
}
234-
235-
.info-value.binary {
236-
overflow-x: auto;
210+
margin-bottom: 0.25rem;
237211
}
238212
`}</style>
239-
</div>
240-
)
213+
</div>
214+
)
241215
}

0 commit comments

Comments
 (0)