Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- pragma solidity ^0.4.23;
- contract Game {
- mapping (address => uint) playerFees;
- mapping (address => bytes1) playersResults;
- uint public feeAmount = 0 ether;
- address[] players;
- uint8 public amount = 0;
- uint8 played = 0;
- address gameInitiator;
- uint public maxGameDuration = 10 minutes;
- uint public joinPrice = 0.5 ether;
- uint timeStarted = 0 seconds;
- //todo: add round duration
- struct roundStruct {
- uint8 number;
- uint rockPeople;
- uint scissorsPeople;
- uint paperPeople;
- }
- struct resultStruct {
- bytes8 value;
- uint amount;
- }
- roundStruct round;
- resultStruct finalResults;
- event gameStarted();
- event allPlayersVotedOrGameExpired(address receiver, bool isWinner); //verify if event sent to the right person
- event nextRound(address receiver);
- event log(uint msg);
- function setFee(uint fee) public {
- require(gameInitiator == msg.sender, "Fee can be set by game initiator");
- require(fee > joinPrice, "Fee might be only bigger than 0.5 eth");
- joinPrice = fee;
- }
- function join() public payable {
- require(msg.sender != gameInitiator, "There is already such player");
- require(msg.value > joinPrice, "Join price is invalid ");
- if(gameInitiator == address(0)) {
- gameInitiator = msg.sender;
- }
- playerFees[msg.sender] = msg.value;
- feeAmount += msg.value;
- players.push(msg.sender);
- amount++;
- }
- function makeAChoice(bytes1 result) public {
- require(contains(msg.sender), "Sender doesnot exist in list of players");
- bool gameExpired = block.timestamp - timeStarted >= maxGameDuration;
- if (gameExpired) {
- calculateResult(gameExpired);
- }
- require(!gameExpired, "Game expired");
- require(playersResults[msg.sender] == 0, "Your vote was already received");
- //encrypt the code
- playersResults[msg.sender] = result;
- roundStruct memory tempRound = round;
- if (result == 1) {//rock
- round = roundStruct(tempRound.number, tempRound.rockPeople++, tempRound.scissorsPeople, tempRound.paperPeople);
- }
- if (result == 2) {//scissors
- round = roundStruct(tempRound.number, tempRound.rockPeople, tempRound.scissorsPeople++, tempRound.paperPeople);
- }
- if (result == 3) {//paper
- round = roundStruct(tempRound.number, tempRound.rockPeople, tempRound.scissorsPeople, tempRound.paperPeople++);
- }
- played += 1;
- if (played == amount) {
- calculateResult(false);
- }
- }
- function startGame() public {
- require(amount > 1, "Players has to be more than one");
- require(timeStarted == 0x0, "Game was enabled already");
- timeStarted = block.timestamp;
- round = roundStruct(1,0,0,0);
- emit gameStarted();
- }
- //rules :
- //--rock crushes scissors
- //--paper covers rock
- //--scissors cuts paper
- function calculateResult(bool gameExpired) private{
- bool hasWinner = (round.rockPeople == 0 || round.scissorsPeople == 0 || round.paperPeople == 0) &&
- (played > round.rockPeople || played > round.scissorsPeople || played > round.paperPeople);
- bytes8 winner = 0;
- uint price = 0 ether;
- if (hasWinner) {
- finalResults = wins();
- winner = finalResults.value;
- uint resultAmount = finalResults.amount;
- if (resultAmount == 0) {
- resultAmount = 1;
- }
- price = (feeAmount - feeAmount / 20) / resultAmount;
- }
- for (uint i = 0; i < amount; i++) {
- if (hasWinner && winner > 0) {
- emit log(2);
- bool isWinner = playersResults[players[i]] == winner;
- emit allPlayersVotedOrGameExpired(players[i], isWinner);
- if (isWinner) {
- players[i].transfer(price);
- }
- } else if (!gameExpired) {
- emit nextRound(players[i]);
- round.number++;
- uint8 numb = round.number;
- round = roundStruct(numb, 0,0,0);
- }
- else {
- emit log(4);
- clearAllTheData();
- }
- }
- }
- function wins() private view returns (resultStruct) {
- if (round.rockPeople == 0 && round.scissorsPeople > 0 && round.paperPeople > 0) {
- return resultStruct(2, round.scissorsPeople);//scissors
- }
- if (round.rockPeople > 0 && round.scissorsPeople == 0 && round.paperPeople > 0) {
- return resultStruct(3, round.paperPeople);//paper
- }
- if (round.rockPeople > 0 && round.scissorsPeople > 0 && round.paperPeople == 0) {
- return resultStruct(1, round.rockPeople);//rock
- }
- return resultStruct(0,0);
- }
- function contains(address player) private view returns (bool){
- return playerFees[player] > 0;
- }
- function clearAllTheData() private {
- timeStarted = 0x0;
- amount = 0;
- played = 0;
- joinPrice = 0.5 ether;
- feeAmount = 0;
- for (uint i = 0; i < amount; i++) {
- delete playersResults[players[i]];
- delete playerFees[players[i]];
- delete players[i];
- }
- }
- }
Add Comment
Please, Sign In to add comment