// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; contract NumberGame { struct Player { string name; uint256 probability; uint8 losses; } struct GameInfo { string gameName; Player[] players; uint8 gamesPlayed; } mapping(uint8 => GameInfo) existingGames; mapping(string => uint8) nameToGame; uint8 numGames; mapping(address => bool) isWhitelisted; constructor() { isWhitelisted[msg.sender] = true; } error NotWhitelisted(); modifier onlyWhitelist() { if (isWhitelisted[msg.sender] != true) revert NotWhitelisted(); _; } function createGame(string calldata _name) public onlyWhitelist returns (uint8) { uint8 gameId = numGames++; GameInfo storage game = existingGames[gameId]; game.gameName = _name; game.gamesPlayed = 0; nameToGame[_name] = gameId; return gameId; } function addToGame(uint8 _gameId, string[] calldata _names) public onlyWhitelist { GameInfo storage game = existingGames[_gameId]; uint256 len = _names.length; for (uint8 i = 0; i < len; i++) { game.players.push(Player(_names[i], 1, 0)); } } error GameDoesNotExist(); function playTheGame(uint8 gameId) public onlyWhitelist returns (string memory) { if (gameId > numGames) revert GameDoesNotExist(); GameInfo memory game = existingGames[gameId]; ++game.gamesPlayed; uint256 q_particiants = game.players.length; uint8 random_index = pseudoRandom(q_particiants); Player memory loser = game.players[random_index]; for (uint8 i = 0; i < q_particiants; i++) { Player storage _p = (existingGames[gameId]).players[i]; if (random_index != i) { _p.probability = (_p.probability * 2); } else { ++_p.losses; } } return loser.name; } function pseudoRandom(uint256 _len) private view returns (uint8) { return uint8( uint256( keccak256( abi.encode( block.timestamp, msg.sender, block.difficulty ) ) ) % _len ); } function getGameInfo(uint8 gameId) public view returns (GameInfo memory) { return existingGames[gameId]; } function getGameId(string calldata name) public view returns (uint8) { return nameToGame[name]; } }
0.5.1