# Exercise #3: CCIP Tic Tac Toe

## Getting started

For the final example of this Masterclass, we are going to deploy and play the CCIP Tic Tac Toe game.

To play the game, we will need to deploy the TicTacToe smart contract on two different blockchains. By sending a transaction on the source chain, which can be either "start" or "move," the state of the game board will be modified, and these states will be "synchronized" by Chainlink CCIP on the other chain.

It is developed using Hardhat, so you will need to prepare the environment by cloning the repository from GitHub by running the following command:

```sh
git clone https://github.com/smartcontractkit/ccip-tic-tac-toe
```

Then install packages:

```sh
npm install
```

And finally, compile smart contracts:

```sh
npx hardhat compile
```

## Set environment variables

We are going to use the [`@chainlink/env-enc`](https://www.npmjs.com/package/@chainlink/env-enc) package for extra security. It encrypts sensitive data instead of storing them as plain text in the `.env` file by creating a new `.env.enc` file. Although pushing this file online is not recommended, if that accidentally happens, your secrets will still be encrypted.

Set a password for encrypting and decrypting the environment variable file. You can change it later by typing the same command.

```sh
npx env-enc set-pw
```

Now set the following environment variables:

```
PRIVATE_KEY=""
ETHEREUM_SEPOLIA_RPC_URL=""
OPTIMISM_GOERLI_RPC_URL=""
ARBITRUM_TESTNET_RPC_URL=""
AVALANCHE_FUJI_RPC_URL=""
POLYGON_MUMBAI_RPC_URL=""
```

To set these variables, type the following command and follow the instructions in the terminal:

```sh
npx env-enc set
```

After you are done, the `.env.enc` file will be automatically generated.

If you want to validate your inputs, you can always run the next command:

```sh
npx env-enc view
```

## Deploy TicTacToe smart contract

```
npx hardhat run ./scripts/deployTicTacToe.ts --network <blockchain>
npx hardhat run ./scripts/deployTicTacToe.ts --network <blockchain>
```

Where the list of supported chains consists of (case sensitive):

* ethereumSepolia
* optimismGoerli
* arbitrumTestnet
* avalancheFuji
* polygonMumbai

For example, if you want to deploy contracts to Ethereum Sepolia and Avalanche Fuji, run the following commands:

```
npx hardhat run ./scripts/deployTicTacToe.ts --network ethereumSepolia
npx hardhat run ./scripts/deployTicTacToe.ts --network avalancheFuji
```

## Transfer native tokens to the TicTacToe smart contract

After the deployment of the contract, you must transfer native tokens to these two contracts, respectively.

For example, if you deployed contracts to Avalanche Fuji and Ethereum Sepolia, please transfer 2 AVAX and 0.01 ETH to contracts on Avalanche Fuji and Ethereum Sepolia, respectively.

## Update router

Please use the commands below to update the Router address for `ccipSend`.

```
npx hardhat ttt-update-router --blockchain ethereumSepolia --contract <address of TicTacToe on Ethereum Sepolia> --router 0xd0daae2231e9cb96b94c8512223533293c3693bf
npx hardhat ttt-update-router --blockchain avalancheFuji --contract <address of TicTacToe on Avalanche Fuji> --router 0x554472a2720e5e7d5d3c817529aba05eed5f82d8
```

Router addresses are listed below:

* Ethereum Sepolia: 0xd0daae2231e9cb96b94c8512223533293c3693bf
* Polygon Mumbai: 0x70499c328e1e2a3c41108bd3730f6670a44595d1
* Optimism Goerli: 0xeb52e9ae4a9fb37172978642d4c141ef53876f26
* Avalanche Fuji: 0x554472a2720e5e7d5d3c817529aba05eed5f82d8
* Arbitrum Goerli: 0x88e492127709447a5abefdab8788a15b4567589e

## Player 1 starts a game

You can start a new game through a TicTacToe contract on any chain. The player who starts a game is player 1. Player 1 needs to send a transaction to create a session, allowing the other player on the other chain to join that session and make a move.

Start a game with the command below:

```
npx hardhat ttt-start --source-blockchain ethereumSepolia --sender <address of TicTacToe on Ethereum Sepolia> --destination-blockchain avalancheFuji --receiver <address of TicTacToe on Avalanche Fuji>
```

You will see the message below in the terminal, and that means the message is sent by CCIP.

```
✅ Message sent, game session created! transaction hash: 0x1f65e17eef0fd9664c389d825db317ec385fe5b1f79baa62aded05583f980e1a
```

While the message is sent to CCIP, the status will not be synced until the message is finalized on the source chain and written into the contract on the other chain. Check the information in CCIP Explorer and find the message below to make sure the message is sent to the dest chain.

## Get session ID by index

In order to join a game, a player needs to know the session ID of the game.

Get the session ID of the game by index with the command below:

```
npx hardhat ttt-get-sessionId --blockchain ethereumSepolia --contract <address of TicTacToe on Ethereum Sepolia> --index 0
```

## Player 2 makes a move in Blockchain 2

Player 2, on the other chain, can make a move within the game session. The player needs to select a position with x and y coordinates(the range of x and y are from 0 to 2) with the command below:

```
npx hardhat ttt-move --x <x coordinate> --y <y coordinate> --player 2 --session-id <sessionId> --source-blockchain avalancheFuji --sender <address of TicTacToe on Avalanche Fuji> --destination-blockchain ethereumSepolia --receiver <address of TicTacToe on Ethereum Sepolia>
```

The x and y are coordinates on the board. eg:

<figure><img src="https://github.com/smartcontractkit/ccip-tic-tac-toe/raw/main/img/xyCoordinates.png" alt="" width="375"><figcaption></figcaption></figure>

## Player 1 makes a move in Blockchain 1

After player 2 made the move, player 1 can make the move with x and y coordinates. Please note that transaction will fail if the position represented by x and y coordinates is occupied.

Player 1 makes a move with the command below:

```
npx hardhat ttt-move --x <x coordinate> --y <y coordinate> --player 2 --session-id <sessionId> --source-blockchain ethereumSepolia --sender <address of TicTacToe on Ethereum Sepolia> --destination-blockchain avalancheFuji --receiver <address of TicTacToe on Avalanche Fuji>
```

## Repeat the previous two steps until the game is over

Repeat the previous two steps until either combination of player 1 or player 2 matches a winning combination.

## Check the winner

Check the winner by command:

```
npx hardhat ttt-check-winner --blockchain ethereumSepolia --contract <address of TicTacToe on Ethereum Sepolia> --session-id <sessionId>
```

You can also check the winner from the contract on the other blockchain with the command:

```
npx hardhat ttt-check-winner --blockchain avalancheFuji --contract <address of TicTacToe on Avalanche Fuji> --session-id <sessionId>
```

## Front-end of Tic-Tac-Toe

This project has a frontend implementation of a decentralized, multiplayer Tic-Tac-Toe game built with React, Wagmi, and Alchemy SDK.

### Features

* The game state is stored in the blockchain, enabling transparent and trustless gameplay.
* Real-time interaction between two players from different blockchain networks.
* Responsive design for a comfortable gaming experience on various devices.
* An integrated game log to inform users about the game's progress.

### Run

Change the directory by running the following command:

```sh
cd frontend
```

Install the dependencies:

```sh
npm install
```

Start the local server:

```sh
npm run dev
```

You can now access the application at the `http://localhost:3000` in your browser.

<figure><img src="https://2422224061-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEm7Dwh3rUCIyHWLvZwRo%2Fuploads%2FONkG6djtOAPezmjPP68C%2Ftic%20tac%20toe.png?alt=media&#x26;token=0d62c781-609a-4826-99ab-4ad98344ab01" alt=""><figcaption><p>Tic Tac Toe UI</p></figcaption></figure>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://cll-devrel.gitbook.io/chainlink-ccip/ccip-masterclass/exercise-3-ccip-tic-tac-toe.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
