Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
4.3 kB
6
Indexable
Never
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract SolahParchiThap {
    error Unauthorized();
    error Invalid_player();
    error Invalid_distribution();
    error Gameon();
    error Gameoff();

    address immutable owner;
    uint256 constant duration = 1 hours;
    uint8 turn;

    address[4] private players;
    uint8[4][4] private chits; 
    uint256 startTime;

    mapping(address => uint256) wins;

    constructor() {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        if(msg.sender != owner) {
            revert Unauthorized();
        }
        _;
    }

    modifier isGameEnded() {
        if(startTime != 0) {
            revert Gameon();
        }
        _;
    }
    
    modifier isGameStarted() {
        if(startTime == 0) {
            revert Gameoff();
        }
        _;
    }

    
    // To set and start the game
    function setState(address[4] memory _players, uint8[4][4] memory _parchis) public onlyOwner isGameEnded {
        for (uint8 i; i<4; ){
            if(_players[i] == address(0) || _players[i] == owner) {
                revert Invalid_player();
            }

            uint8 sum;
            for(uint8 j; j<4;){
                uint8 num = _parchis[i][j];
                sum = sum + num;
                if(num > 4) {
                    revert Invalid_distribution();
                }
                unchecked {
                    j = j+1;
                }
            }

            if(i==0 && sum > 4) {
                revert Invalid_distribution();
            }

            unchecked {
                i = i+1;
            }
        }

        players = _players;
        chits = _parchis;

        startTime = block.timestamp;
    }

    // To pass the parchi to next player
    function passParchi(uint8 _parchi) public isGameStarted {
        if(msg.sender != players[turn] || chits[turn][_parchi-1] < 1) {
            revert Unauthorized();
        }

        uint8 _turn = turn;
        chits[_turn][_parchi-1] -= 1;
        turn = (_turn + 1) % 4;
        chits[turn][_parchi-1] += 1;

        if(chits[turn][_parchi-1] > 4) {
            revert Invalid_distribution();
        }
    }

    // To claim win
    function claimWin() public isGameStarted {
        for (uint8 i; i<4;) {
            if (players[i] == msg.sender) {
                for (uint8 j; j < 4; ) {
                    if (chits[i][j] == 4) {
                        wins[msg.sender] += 1;
                        startTime = 0;
                        return;
                    }
                    unchecked {
                        j = j+1;
                    }
                }
            }

            unchecked {
                i = i+1;
            }
        }
        revert Unauthorized();
    }

    // To end the game
    function endGame() public {
        for(uint8 i; i<4;) {
            if (players[i] == msg.sender) {
                if(block.timestamp >= (startTime + duration)){
                    startTime = 0;
                    return;
                }
            }
            unchecked {
                i = i + 1;
            }
        }
        revert Unauthorized();
    }

    // To see the number of wins
    function getWins(address add) public view returns (uint256) {
        for (uint8 i; i<4;) {
            if (players[i] == add) {
                return wins[add];
            }
            unchecked{
                i = i+1;
            }
        }
        revert Unauthorized();
    }

    // To see the parchis held by the caller of this function
    function myParchis() public isGameStarted view returns (uint8[4] memory)  {
        for (uint8 i; i<4;) {
            if (msg.sender == players[i]) {
                return chits[i];
            }

            unchecked {
                i = i+1;
            }
        }
        revert Unauthorized();
    }

    // To get the state of the game
    function getState() public view onlyOwner isGameStarted returns (address[4] memory, address, uint8[4][4] memory) {
        return (players, players[turn], chits);
    }
}