Rethinking Gameboards
Tags: javascript, webdev, beginners, css
Published: 2021-10-04 02:28:16

## The Plan
This is an evolution of an idea. At first, I wanted to see if it would be possible to use grid-areas to set up a minimalist chessboard (both positioning and movement), and it was. Then, I got into reading Eric Elliott's **Composing Software**, and I really wanted to toy with the idea of functionally composed elements, so the pieces on the board happened. Then I had a conversation on The Odin Project about defining *interfaces* for factory functions, and the Gameboard as a whole became a factory using the pieces' interface methods. It didn't happen all at once, and I won't write about it all at once.

But if you'd like to see this thing as it stands at this point in its evolution, take a look at [the repl](https://replit.com/@TobiasParent/BonyEvilSquares).

I plan on a three- or four-part series, depending. This one explains the theory behind the board. The next should cover the Piece factory, which covers the generic methods all pieces share. The third will explain some of how the moves are handled for each piece, exploring composed functions along the way, and finally getting into how the whole thing plays together.

I do hope you enjoy the ride!

## The what

Often, when we are going through online curricula, there is a project involving building a game. Might be tic-tac-toe, might be chess, might be Battleship, but a game design happens. In this case, we'll build a chessboard.

Being fearless devs, we dive into coding, building an HTML mockup and figuring our CSS, and let's see what it might look like:

```html
<body>
  <main class='gameboard'>
    <div class='cell'></div>
    <div class='cell'></div>
    <!-- and repeat that to make an eight-by-eight... -->
  </main>
</body>
```html
And the css:
```css
.gameboard {
  width: 80vw;
  height: 80vw;
  display: flex;
  flex-wrap: wrap;
}
.cell {
  width: 12.5%;
  height: 12.5%;
  box-sizing: border-box;
  border: 1px solid silver;
}
```
But at that point, we have to think about this: the cells have to alternate color. We could use a css rule, something like `:nth-of-child()` with some funky css magic to color alternating squares, but we have an easier solution: we can simply make the board image a background on the `.gameboard`, and make those cells the same size as our image cells!

At this point, I had to stop. We **could** do this. This works, and it's the most common way. Make all the cells contained within the board, and set the pieces on the particular cell div as needed. Works fine.

But I don't particularly like it. It's not the way a chessboard works.

## The why

Let's imagine we just went to the game store, bought a new chess set. When we open it, do we have a board, 32 chess pieces, and 64 cells? No, we do not. We have a board, and we have the pieces.

**So why do we feel we need to code those cells**? 

We might see it as reasonable to have the cells to handle the click in a particular one, but most of us will likely use event delegation, so the clicks are happening on the board, not the cell.

Perhaps we see it as reasonable to have the cells there, in order to appropriately position the chess pieces. And this, right here, is why I want to write this article.

## The how

CSS3 gave us a great many power-tools, and we don't always use them to their fullest. But this article is about using one of them in ways that can simplify things like, for example, gameboard development.

I'm talking about grids. And in particular, about the `grid-area` css rule. Consider this HTML:

```html
<div class="chessboard">
  <div class="chess-piece rook black queens"></div>
  <div class="chess-piece knight black queens"></div>
  <div class="chess-piece bishop black queens"></div>
  <div class="chess-piece queen black" ></div>
  <div class="chess-piece king black"></div>
  <div class="chess-piece bishop black kings"></div>
  <div class="chess-piece knight black kings"></div>
  <div class="chess-piece rook black kings"></div>
  <div class="chess-piece rook white queens"></div>
  <div class="chess-piece knight white queens"></div>
  <div class="chess-piece bishop white queens"></div>
  <div class="chess-piece queen white"></div>
  <div class="chess-piece king white"></div>
  <div class="chess-piece bishop white kings"></div>
  <div class="chess-piece knight white kings"></div>
  <div class="chess-piece rook white kings"></div>
</div>
```

And that's it. It contains everything we need to make a playable chessboard (leaving off the pawns for brevity, but the idea remains). We have a board, which contains the pieces. The pieces have class names that are pretty descriptive, we know which one's the "black queen's rook" at a glance.

Now, for the board's CSS:

```css
.chessboard {
  width: 80vmin;
  height: 80vmin;

  background-image: url('./quad-grid.svg');
  background-position: 0 0;
  background-size: 25%;
  background-repeat: repeat;

  /* This is the bit to watch! */
  display: grid;
  grid-template-columns: repeat(8, 12.5%);
  grid-template-rows: repeat(8, 12.5%);
  gap: 0px 0px;
  grid-template-areas:
    "A1 B1 C1 D1 E1 F1 G1 H1"
    "A2 B2 C2 D2 E2 F2 G2 H2"
    "A3 B3 C3 D3 E3 F3 G3 H3"
    "A4 B4 C4 D4 E4 F4 G4 H4"
    "A5 B5 C5 D5 E5 F5 G5 H5"
    "A6 B6 C6 D6 E6 F6 G6 H6"
    "A7 B7 C7 D7 E7 F7 G7 H7"
    "A8 B8 C8 D8 E8 F8 G8 H8"
;
}
```

So this sizes the board, places the background image in which gives us the actual board appearance, and sets up the css grid. The grid is set up with named `grid-template-areas`, named using chess notation.

And the fun part? The pieces are placed using that same chess notation!

```css
/****
 * There is some sizing and styling of the pieces,
 *   but this is mostly about positioning.
 ****/

/* Black pieces */
.black.queens.rook {
  grid-area: A8;
}
.black.queens.knight {
  grid-area: B8;
}
.black.queens.bishop {
  grid-area: C8;
}
.black.queen {
  grid-area: D8;
}
.black.king {
  grid-area: E8;
}
.black.kings.bishop {
  grid-area: F8;
}
.black.kings.knight {
  grid-area: G8;
}
.black.kings.rook {
  grid-area: H8;
}

/* White side pieces */
.white.queens.rook {
  grid-area: A1;
}
.white.queens.knight {
  grid-area: B1;
}
.white.queens.bishop {
  grid-area: C1;
}
.white.queen {
  grid-area: D1;
}
.white.king {
  grid-area: E1;
}
.white.kings.bishop {
  grid-area: F1;
}
.white.kings.knight {
  grid-area: G1;
}
.white.kings.rook {
  grid-area: H1;
}
```
So each piece is positioned on the board by an initial `grid-area`. And further, we can later do this:

```js
document.querySelector(".white.kings.knight").style.gridArea="F2";
```
And that moves the piece on the board. No worrying about calculating offsets or moving the piece, simply tell it, by css, where to move.