The Board Is Data
Before a game can be played, it has to exist somewhere. The most important idea in game development is that the game lives in data, and the screen is just a picture of that data. Get this right and every game you ever build is the same shape.
The one idea
A tic-tac-toe game is not nine boxes on a screen. It's a list of nine values:
const board = [
"", "X", "",
"", "O", "",
"", "", "X"
];
That array is the game. The boxes you see are a rendering of it. This separation is the heartbeat of game dev:
state (the data) → render (draw it) → input (player acts) → update (change the data) → render again…
Today we build only the first two arrows: hold the board in an array, and draw it. Input comes in Lesson 2. We're keeping the step tiny on purpose.
Live demo
This board below is driven entirely by a JS array. The buttons change the data; notice the squares follow automatically. You never touch the squares directly.
That is the whole lesson in motion: a
render() function reads the array and paints the
screen. Change the array, call render(), and the
view catches up. You will write exactly this pattern next.
Build it yourself
Make a new folder and three files. (Three separate files keeps structure, style, and behavior apart, the standard web split.)
1. index.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="board"></div>
<script src="script.js"></script>
</body>
</html>
The empty <div id="board"> is your canvas.
JavaScript fills it. Put the <script> at the
end of <body> so the div exists by the time
the script runs.
2. style.css
#board {
display: grid;
grid-template-columns: repeat(3, 80px);
grid-template-rows: repeat(3, 80px);
gap: 6px;
}
.cell {
background: #eee;
display: flex;
align-items: center;
justify-content: center;
font-size: 2rem;
}
CSS Grid
turns the div into a 3×3 layout for free.
repeat(3, 80px) means "three columns, each 80px
wide."
3. script.js — the part that matters
// 1. STATE: the game is this array.
const board = [
"", "X", "",
"", "O", "",
"", "", "X"
];
// 2. RENDER: read state, draw it.
const boardEl = document.querySelector("#board");
function render() {
boardEl.innerHTML = ""; // clear first
for (const value of board) {
const cell = document.createElement("div");
cell.className = "cell";
cell.textContent = value; // "", "X", or "O"
boardEl.appendChild(cell);
}
}
render(); // draw once
Open index.html in your browser. You should see the
X's and O's exactly where the array put them.
That's your win.
Change the board array so it shows a full row
of "O" across the top, and leave the rest
blank. Refresh. Did the screen follow the data?
You never touched the HTML to do it —
that's the whole point. Then try: what happens if the array
has only 8 items? Reason about why before you look.
What you just learned
- The game's truth lives in state (an array), not in the DOM.
- A render function turns state into what you see. Re-running it after state changes keeps the screen honest.
-
You met four DOM tools:
querySelector,createElement,textContent, andappendChild.
render() to see your X appear. That closes the loop
from state to interaction.