// Contract: OneOnTen
// Target function: function enterRoom(uint8 maxPlayers) internal
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
 * @title OneOnTen
 *
 *
 * Decentralized gaming room contract that allows players to join rooms and compete.
 * 
 *
 * Two modes available : 
 * - 1v1 gives you 50% probability of winning ( you win 80% of the total pledge of all players ). This mode finishes as soon as the second player enter the room.
 * - 1v10 gives you 10% probability of winning ( you win 80% of the total pledge of all players ). This mode finishes as soon as the 10th player enters the room, or after around 1200 mined blocks - around 4h ( you are refunded after the timer ends if no other player's joined ).
 *
 *
 * In order to access a gaming room you just need to enter the desired ETH amount you want to play and select the game mode.
 *
 * Different rooms fees : 
 * - 0.01 ETH --> you win :
 * - - - - - - - - 0.016 ETH in 1v1
 * - - - - - - - - 0.08 ETH in 1v10
 *
 * - 0.03 ETH --> you win :
 * - - - - - - - - 0.048 ETH in 1v1
 * - - - - - - - - 0.24 ETH in 1v10
 *
 * - 0.1 ETH --> you win :
 * - - - - - - - - 0.16 ETH in 1v1
 * - - - - - - - - 0.8 ETH in 1v10
 *
 * - 1 ETH --> you win :
 * - - - - - - - - 1.6 ETH in 1v1
 * - - - - - - - - 8 ETH in 1v10
 *
 * - 10 ETH --> you win :
 * - - - - - - - - 16 ETH in 1v1
 * - - - - - - - - 80 ETH in 1v10
 *
 */
contract OneOnTen {
    struct Room {
        uint256 entryFee;
        uint8 maxPlayers;
        address[] players;
        uint256 startTimeBlock;
        bool isActive;
    }

    uint256 public constant BLOCKS_FOR_4_HOURS = 1200;
    uint256 public constant MAX_PLAYERS_1v1 = 2;
    uint256 public constant MAX_PLAYERS_1v10 = 10;
    uint256[] public activeRoomIds;

    Room[] internal rooms;
    mapping(uint8 => uint256) public roomTypeToEntryFee;

    event PlayerJoined(uint256 roomId, address player);
    event RoomCreated(uint256 roomId, uint256 entryFee, uint8 maxPlayers);
    event TimerStarted(uint256 roomId, uint256 startBlock);
    event TimerEnded(uint256 roomId);
    event PlayerRefunded(address player, uint256 amount);
    event WinnerPaid(address winner, uint256 amount);
    event RoomDeactivated(uint256 roomId);
    event MissingBlocks(uint256 roomId, uint256 missingBlocks);
    event Debug(string message, uint256 value);


    constructor() {
        roomTypeToEntryFee[1] = 0.01 ether;
        roomTypeToEntryFee[2] = 0.03 ether;
        roomTypeToEntryFee[3] = 0.1 ether;
        roomTypeToEntryFee[4] = 1 ether;
        roomTypeToEntryFee[5] = 10 ether;
    }

    /**
     * @dev External function allowing a player to enter a 1v1 room.
     *      This function is payable, meaning it can accept ether.
     *      It calls the internal {enterRoom} function with MAX_PLAYERS_1v1 as the parameter.
     *
     * @notice The transaction must include the required entry fee in ether.
     *
     * Emits all events through {enterRoom}.
     */
    function enterRoom1v1() external payable {
        enterRoom(uint8(MAX_PLAYERS_1v1));
    }

    /**
     * @dev External function allowing a player to enter a 1v10 room.
     *      This function is payable, meaning it can accept ether.
     *      It calls the internal {enterRoom} function with MAX_PLAYERS_1v10 as the parameter.
     *
     * @notice The transaction must include the required entry fee in ether.
     *
     * Emits all events through {enterRoom}.
     */
    function enterRoom1v10() external payable {
        enterRoom(uint8(MAX_PLAYERS_1v10));
    }