Skip to content

Jds-23/tictactoe

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OnChain Tic-Tac-Toe

A gas-optimized Tic-Tac-Toe implementation on Ethereum using bit manipulation and assembly code. README.md by Claude Code

This project explores smart contract optimization techniques by implementing a simple game with minimal gas consumption. The entire game state is packed into 24 bits, demonstrating efficient storage patterns for blockchain applications.

What Makes This Different?

Key Features

  • 24 bits to store entire game state (vs. traditional 288+ bits)
  • Significant gas savings compared to standard implementations
  • Yul assembly for optimized operations
  • Efficient storage using bit manipulation

Technical Approach

Standard Implementation

// Traditional approach
mapping(uint256 => uint8[9]) public boards;  // 288 bits per game
mapping(uint256 => address) public currentPlayer;

Optimized Implementation

// Bit-packed approach
struct Game {
    bytes3 board;        // 24 bits total
    address player1;
    address player2;
}

Bit Layout

The game state is packed into 24 bits:

Bit Layout (24 bits total):
├─ Bits 0-8:   Player 1 marks (9 positions)
├─ Bits 9-17:  Player 2 marks (9 positions)  
├─ Bit 18-22:  Unused (future expansion)
└─ Bit 23:     Turn indicator (0=P1, 1=P2)

Example Game State:

Player 1 plays positions [0,4,8]: 0b100010001 (bits 0-8)
Player 2 plays positions [1,5]:   0b000100010 (bits 9-17, shifted)
Current turn: Player 2             0b1         (bit 23)

Combined: 0b1000001000100100010001 (binary)
         = 0x808121 (hex)

Implementation Details

Optimization Techniques

1. Bit Manipulation

// Check if position is occupied by either player
if (iszero(iszero(and(shl(index, 513), board)))) {
    revert() // 513 = 0b1000000001 - checks both player bits
}

2. Assembly Optimization

Critical functions use Yul assembly for gas efficiency:

// Get player's board state in assembly
switch iszero(and(shl(23, 1), board))
case 0 {
    // Player 2's turn - extract bits 9-17
    playerBoard := shl(223, and(261632, board))
}
default {  
    // Player 1's turn - extract bits 0-8
    playerBoard := shl(232, and(511, board))
}

3. Pre-computed Winning Patterns

Winning combinations are pre-computed for efficiency:

winningMarks[bytes3(0x000007)] = true; // [0,1,2] - top row
winningMarks[bytes3(0x000111)] = true; // [0,4,8] - diagonal
// ... all 8 winning combinations

4. Event-Driven Architecture

event NewGame(address indexed player1, address indexed player2, uint256 gameId);
event Played(uint256 indexed gameId, bytes3 board);

Architecture Analysis

Advantages

  1. Gas Efficiency

    • Reduced gas costs compared to standard implementations
    • Single SSTORE operation for moves
    • Bit-packed storage minimizes storage costs
  2. Performance

    • Board state fits in CPU registers
    • Atomic operations prevent race conditions
    • Predictable gas costs
  3. Scalability

    • Minimal storage per game
    • Supports multiple concurrent games
    • Suitable for high-frequency gaming
  4. Code Quality

    • Pure functions where possible
    • Predictable execution paths
    • Documented assembly code

Trade-offs

  1. Development Complexity

    • Requires understanding of bit manipulation
    • Assembly debugging is challenging
    • Higher learning curve for contributors
  2. Code Readability

    • Assembly code is less readable than Solidity
    • Bit operations require careful documentation
    • More complex to understand and maintain
  3. Flexibility Limitations

    • Difficult to modify game rules
    • Adding features requires careful planning
    • Less suitable for rapid prototyping

Testing Strategy

The project uses comprehensive fuzz testing to verify correctness:

Fuzz Testing Approach

function testFuzz_ValidMoves(uint8 position) public {
    vm.assume(position < 9);
    // Tests various game state combinations
}

Test Categories

  • Valid Scenarios: Legal moves and game flows
  • Invalid Positions: Out-of-bounds and occupied cells
  • Wrong Players: Unauthorized and out-of-turn attempts
  • Game Isolation: Multiple games don't interfere
  • State Invariants: Game state consistency
  • Event Emissions: Proper logging verification

Coverage

  • 15+ fuzz test functions
  • Extensive randomized test cases
  • Critical path coverage
  • Edge case detection

Getting Started

Prerequisites

  • Foundry installed
  • Basic understanding of Solidity and EVM

Build & Test

# Clone and build
git clone <repository>
cd tic-tac-toe

# Compile the contract
forge build

# Run the test suite
forge test

# Run with maximum verbosity for debugging
forge test -vvvv

# Generate coverage report
forge coverage

# Format code
forge fmt

Deploy to Testnet

# Deploy to your favorite testnet
forge script script/TicTacToe.s.sol --rpc-url $RPC_URL --private-key $PRIVATE_KEY --broadcast

🎮 How to Play

  1. Create Game: Call newGame(player1, player2)
  2. Make Moves: Call play(gameId, position) where position is 0-8
  3. Check State: Call getBoard(gameId) to see current state
  4. Find Winner: Call whoWon(gameId) after game ends
// Example game flow
uint256 gameId = ttt.newGame(alice, bob);
ttt.play(gameId, 4); // Alice plays center
ttt.play(gameId, 0); // Bob plays top-left
// ... continue until someone wins or draws

Technical Specifications

  • Solidity Version: ^0.8.13
  • Framework: Foundry
  • Dependencies: forge-std, solady
  • Gas Limit: ~50,000 per move
  • Storage: 1 slot per game (32 bytes)
  • Max Concurrent Games: Limited by Ethereum storage

Contributing

Contributions are welcome. When contributing:

  1. Understand the bit layout before making changes
  2. Test thoroughly - gas optimizations can be fragile
  3. Document assembly code clearly
  4. Benchmark changes to ensure performance is maintained

Future Improvements

  • NFT Integration: Game states as collectibles

Learn More


README.md by Claude Code

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published