Skip to content

Commit

Permalink
Merge pull request #2 from 0xBabacan/main
Browse files Browse the repository at this point in the history
Nice changes! I'm gonna do some little edits from here :)
  • Loading branch information
luloxi authored Jan 15, 2024
2 parents 41d9ffd + ff691fb commit 4af35af
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 8 deletions.
48 changes: 42 additions & 6 deletions packages/hardhat/contracts/TicTacToe.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
import "hardhat/console.sol";

/**
* @title TicTacToe
Expand All @@ -12,6 +13,7 @@ pragma solidity ^0.8.17;

contract TicTacToe {
uint256 public gameIdCounter = 0;
uint256 public immutable timeOutValue = 10 seconds;

enum GameState {
PENDING,
Expand All @@ -30,6 +32,7 @@ contract TicTacToe {
bool player2Withdrawn;
uint8[9] board; // 0 (no player): empty, 1 (player 1): X, 2 (player 2): O
uint8 moves; // Counter or the number of moves made
uint256 lastTimePlayed;
}

mapping(uint256 => Game) public games;
Expand All @@ -45,6 +48,10 @@ contract TicTacToe {
address indexed team1,
address indexed team2
);
event GameDeleted(
uint256 indexed gameId,
address indexed player1
);
event MoveMade(
uint256 indexed gameId,
address indexed player,
Expand Down Expand Up @@ -110,7 +117,8 @@ contract TicTacToe {
player1Withdrawn: false,
player2Withdrawn: false,
board: [0, 0, 0, 0, 0, 0, 0, 0, 0],
moves: 0
moves: 0,
lastTimePlayed : 0
});

// This event can be used by the frontend to know that something happened and react to it
Expand All @@ -129,25 +137,48 @@ contract TicTacToe {
game.bet == msg.value,
"You haven't sent the required ETH to accept"
);
// Set the initial time count to check the timeout
games[_gameId].lastTimePlayed = block.timestamp;

// Set the game state to PLAYING and emit an event
games[_gameId].state = GameState.PLAYING;
emit GameAccepted(_gameId, game.player1, game.player2);
}

function deleteGame(uint256 _gameId) external {
Game memory game = games[_gameId];
require(game.player1 == msg.sender, "You must be player 1 to delete the request");
require(
game.state == GameState.PENDING,
"Game must be PENDING to be deleted"
);
require(
block.timestamp - games[_gameId].lastTimePlayed <= timeOutValue,
"Timeout value hasnt been reached yet!"
);

games[_gameId].state = GameState.TIE;
uint256 paidBetAmount = calculatePrize(_gameId);
require(paidBetAmount > 0, "Invalid bet amount");
// Transfer the bet to the player
payable(msg.sender).transfer(paidBetAmount);
emit GameDeleted(_gameId, game.player1);
}

function makeMove(
uint256 _gameId,
uint8 position
) external onlyValidMove(_gameId, position) {
// Determine the current Player symbol
// 1 is player1, 2 is player2
uint8 playerSymbol = games[_gameId].moves % 2 == 0 ? 1 : 2;
// Add the corresponding mark in the position of the game board
games[_gameId].board[position] = playerSymbol;
// And add 1 to the number of moves made in the game
games[_gameId].moves++;
// Add the corresponding mark in the position of the game board
games[_gameId].board[position] = playerSymbol;
// And add 1 to the number of moves made in the game
games[_gameId].moves++;
games[_gameId].lastTimePlayed = block.timestamp;

emit MoveMade(_gameId, msg.sender, position);
emit MoveMade(_gameId, msg.sender, position);
// Check if after adding that symbol, a win is achieved, and react to it if that's the case
checkWin(_gameId, position, msg.sender);
}
Expand Down Expand Up @@ -203,6 +234,11 @@ contract TicTacToe {

/* INTERNAL FUNCTIONS */

function winByTimeout(uint256 _gameId) internal {
require(block.timestamp - games[_gameId].lastTimePlayed > timeOutValue, "Timeout value hasnt been reached yet!");
games[_gameId].moves % 2 == 0 ? finishGame(_gameId, games[_gameId].player2) : finishGame(_gameId, games[_gameId].player1);
}

function checkWin(
uint256 _gameId,
uint8 _position,
Expand Down
65 changes: 64 additions & 1 deletion packages/nextjs/contracts/deployedContracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { GenericContractsDeclaration } from "~~/utils/scaffold-eth/contract";
const deployedContracts = {
31337: {
TicTacToe: {
address: "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e",
address: "0x5FbDB2315678afecb367f032d93F642f64180aa3",
abi: [
{
anonymous: false,
Expand Down Expand Up @@ -65,6 +65,25 @@ const deployedContracts = {
name: "GameCreated",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "uint256",
name: "gameId",
type: "uint256",
},
{
indexed: true,
internalType: "address",
name: "player1",
type: "address",
},
],
name: "GameDeleted",
type: "event",
},
{
anonymous: false,
inputs: [
Expand Down Expand Up @@ -141,6 +160,19 @@ const deployedContracts = {
stateMutability: "payable",
type: "function",
},
{
inputs: [
{
internalType: "uint256",
name: "_gameId",
type: "uint256",
},
],
name: "deleteGame",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [],
name: "gameIdCounter",
Expand Down Expand Up @@ -199,6 +231,11 @@ const deployedContracts = {
name: "moves",
type: "uint8",
},
{
internalType: "uint256",
name: "lastTimePlayed",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
Expand Down Expand Up @@ -335,6 +372,32 @@ const deployedContracts = {
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [],
name: "timeOutValue",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{
internalType: "uint256",
name: "_gameId",
type: "uint256",
},
],
name: "winByTimeout",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{
Expand Down
2 changes: 1 addition & 1 deletion packages/nextjs/scaffold.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export type ScaffoldConfig = {

const scaffoldConfig = {
// The networks on which your DApp is live
targetNetworks: [chains.sepolia],
targetNetworks: [chains.hardhat],

// The interval at which your front-end polls the RPC servers for new data
// it has no effect if you only target the local network (default is 4000)
Expand Down

0 comments on commit 4af35af

Please sign in to comment.