The Easy Way To Build A Tic Tac Toe Game!
Tags: svelte, javascript, webdev, tictactoe
Published: 2022-05-25 11:30:00

## What Is Svelte?

Svelte is a radical new approach to building user interfaces with less code. No more complex state management libraries — Svelte brings reactivity to JavaScript itself. 

In this tutorial, you'll need basic understanding of HTML, CSS and JavaScript to build your own Tic Tac Toe Game with Svelte. 

## Getting Started

Go ahead and initialise our new project with the following command:

```
# Creating a new project
npx degit sveltejs/template 

# Install the dependencies...
npm install
```
...then start Rollup.

```
# Npm Command
npm run dev 
```
Navigate to localhost:8080 and you should see your app running. Edit a component file in src, save it, and reload the page to see your changes.

## Basic Structure 

Components in Svelte are written use `.svelte` files which contain HTML, CSS and JavaScript. Now let's create our `Board.svelte` file and modify our `App.svelte` file with the following structure. 

```
<script>
<!-- JavaScript Logic -->
</script>

<style>
<!-- CSS Styles -->
</style>

<div>
<!-- HTML Markup -->
</div>
```

Before we get started let's replace our `main.js` with the following: 

```
import App from './App.svelte'

const app = new App({
  target: document.body,
})

export default app
```

## Our App Component

Now we will edit the `App.svelte` with the following to complete our App Component. 

```
<script>
  import Board from "./Board.svelte";
</script>

<div class="app">
<div class ="container">
<Board />
</div>
 </div>

```
Here we've imported `Board.svelte` and initalised our Board Component in `App.svelte` using HTML Markup. 

## Our Board Component

We'll open up `Board.svelte` and implement the JavaScript Logic for our Board Component.

```
<script>
  let userTurn = "X";
  let squares = new Array(9).fill(null);
  let winner = null;
  function restartGame() {
    userTurn = "X";
    squares = new Array(9).fill(null);
    winner = null;
  }
  function handleClick(i) {
    if (!squares[i] && !winner) {
      squares[i] = userTurn;
      switchTurn();
      winner = calculateWinner(squares);
      if (winner) userTurn = null;
    }
  }
  function switchTurn() {
    if (userTurn === "X") userTurn = "O";
    else userTurn = "X";
  }
  function calculateWinner(squares) {
    const winningCombinations = [
      [0, 1, 2],
      [3, 4, 5],
      [6, 7, 8],
      [0, 3, 6],
      [1, 4, 7],
      [2, 5, 8],
      [0, 4, 8],
      [2, 4, 6]
    ];
    for (let i = 0; i < winningCombinations.length; i++) {
      const [a, b, c] = winningCombinations[i];
      if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c])
        return `Winner: ${squares[a].toUpperCase()}`;
    }
    const isDraw = squares.every(square => square !== null);
    return isDraw ? "It's a draw" : null;
  }
</script>
```

Now we can implement the HTML Markup for our `Board.svelte` component. 

```
<div>
{#if winner}
  <h1>{winner}</h1>
  <button class="restart" on:click={restartGame}>Restart Game</button>
{:else}
  <h1>Next Player : {userTurn}</h1>
{/if}
</div>
<div class={userTurn != null ? userTurn + ' board' : 'board'}>
  {#each squares as square, i}
    <div
      class={square != null ? square + ' cell' : 'cell'}
      on:click={() => handleClick(i)} />
  {/each}
</div>
```

Next step is to add the following styles to complete our `Board.Svelte` file.

```
<style>
	:root {
	  --cell-size: 100px;
	  --mark-size: calc(var(--cell-size) * 0.5);
	}
	.board {
	  display: grid;
	  justify-content: center;
	  justify-items: center;
	  align-content: center;
	  align-items: center;
	  grid-template-columns: repeat(3, auto);
	}
	.cell {
	  width: var(--cell-size);
	  height: var(--cell-size);
	  border: 1px solid black;
	  display: flex;
	  justify-content: center;
	  align-items: center;
	  position: relative;
	  cursor: pointer;
	}
	.cell:first-child,
	.cell:nth-child(2),
	.cell:nth-child(3) {
	  border-top: none;
	}
	.cell:nth-child(3n + 1) {
	  border-left: none;
	}
	.cell:nth-child(3n + 3) {
	  border-right: none;
	}
	.cell:last-child,
	.cell:nth-child(8),
	.cell:nth-child(7) {
	  border-bottom: none;
	}
	.cell.X,
	.cell.O {
	  cursor: not-allowed;
	}
	.cell.X::before,
	.cell.X::after,
	.cell.O::before {
	  background-color: black;
	}
	.board.X .cell:not(.X):not(.O):hover::before,
	.board.X .cell:not(.X):not(.O):hover::after,
	.board.O .cell:not(.X):not(.O):hover::before {
	  background-color: lightgrey;
	}
	.cell.X::before,
	.cell.X::after,
	.board.X .cell:not(.X):not(.O):hover::before,
	.board.X .cell:not(.X):not(.O):hover::after {
	  content: "";
	  position: absolute;
	  width: calc(var(--mark-size) * 0.15);
	  height: var(--mark-size);
	}
	.cell.X::before,
	.board.X .cell:not(.X):not(.O):hover::before {
	  transform: rotate(45deg);
	}
	.cell.X::after,
	.board.X .cell:not(.X):not(.O):hover::after {
	  transform: rotate(-45deg);
	}
	.cell.O::before,
	.cell.O::after,
	.board.O .cell:not(.X):not(.O):hover::before,
	.board.O .cell:not(.X):not(.O):hover::after {
	  content: "";
	  position: absolute;
	  border-radius: 50%;
	}
	.cell.O::before,
	.board.O .cell:not(.X):not(.O):hover::before {
	  width: var(--mark-size);
	  height: var(--mark-size);
	}
	.cell.O::after,
	.board.O .cell:not(.X):not(.O):hover::after {
	  width: calc(var(--mark-size) * 0.7);
	  height: calc(var(--mark-size) * 0.7);
	  background-color: white;
	}
	h1 {
	  text-align: center;
	  text-decoration: underline;
	  text-decoration-color: red;
	  margin: 2rem;
	  padding: 1rem;
	}
	.restart {
	  font-weight: bold;
	  position: absolute;
	  top: 50%;
	  padding: 20px;
	  margin: 200px 500px;
	}
</style>
```

Note 💡 - You should now have a complete Tic Tac Toe game using Svelte. 

![Winner](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7662po7gtn36jvg2tf65.PNG)


Cool! Now if you made it this far, then I am linking the code to my [Sandbox](https://g1r4tn.csb.app/) for you to fork or clone and then the job's done.

## License: 📝
This project is under the MIT License (MIT). See the LICENSE for more information.

## Contributions
Contributions are always welcome...

- Fork the repository
- Improve current program by
- improving functionality
- adding a new feature
- bug fixes
- Push your work and Create a Pull Request

## Useful Resources
- [sveltestrapJS](https://sveltestrap.js.org/)
- [svelte.dev](https://svelte.dev/)
- [github.com/sveltjs/template](https://github.com/sveltejs/template)
- [Time Travel Repl](https://svelte.dev/repl/6d0b78edbe0440fcb4e3ccbf1709501d?version=3.15.0version=3.20.1)
- [Tic Tac Toe Repl] (https://svelte.dev/repl/fd5d45a774a54c85bb3db1199c07b42a?version=3.12.1)