Created
January 3, 2019 18:33
-
-
Save RyanHendricks/9dbc2fb648de284f723010e1c8b5b998 to your computer and use it in GitHub Desktop.
Union Poker
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.5.0; | |
contract UnionPoker { | |
struct UnionPokerGame { | |
bool started; /// has the game started | |
bool ended; /// has the game ended | |
uint256 totalBuyIns; /// total of all buy ins | |
uint256 totalCashOuts; /// total of all cash outs | |
uint256 totalBalance; /// total amount in play (buyins minus cashouts) | |
mapping(address => uint256) playerTotalBalance; /// balance of each player | |
mapping(address => uint256) playerBuyIns; /// buy in total for each player | |
mapping(address => uint256) playerCashOuts; /// cash out total for each player | |
} | |
struct UnionPokerPlayer { | |
uint256 playerTotalBalance; /// balance of player if player is in the positive | |
uint256 playerTotalOwed; /// negative balance of player if in the negative | |
uint256 playerTotalBuyIns; /// total of all buyins made by the player for all games | |
uint256 playerTotalCashOuts; /// total of all cashouts made by the player for all games | |
} | |
/// mapping if player has registered in the contract via bool mapped to address | |
mapping(address => bool) public isPlayer; | |
/// mapping UnionPokerPlayer to their address | |
mapping(address => UnionPokerPlayer) public playerStats; | |
/// array of gameHistory | |
UnionPokerGame[] public gameHistory; | |
/// array of UnionPokerPlayers | |
UnionPokerPlayer[] public unionPokerPlayers; | |
/// current game in progress | |
bool public gameInProgress; | |
/// struct with state of current game | |
UnionPokerGame public currentGame; | |
/// constructor setting game in progress to false | |
constructor () public { | |
gameInProgress = false; | |
} | |
/** | |
* @dev newPlayer adds a new player to the contract | |
* @param _newPlayer address of the new Union Poker Player | |
*/ | |
function newPlayer(address _newPlayer) public { | |
require(isPlayer[_newPlayer] == false, "player not new"); /// make sure player is new | |
/// create a new player struct | |
UnionPokerPlayer memory player; | |
/// set balances to 0 | |
player.playerTotalBalance = 0; | |
player.playerTotalOwed = 0; | |
player.playerTotalBuyIns = 0; | |
player.playerTotalCashOuts = 0; | |
/// register the player | |
isPlayer[_newPlayer] = true; | |
/// push player struct to the unionPokerPlayers array | |
unionPokerPlayers.push(player); | |
/// map the player stat struct to the new player's address | |
playerStats[_newPlayer] = player; | |
} | |
/** | |
* @dev newPokerGame creates and starts a new poker game | |
* @dev can only be started if no game in progress | |
* @dev can be started by anyone but only registered players can buy in | |
*/ | |
function newPokerGame() public { | |
require(gameInProgress == false, "game in progress"); | |
// new UnionPokerGame(); | |
UnionPokerGame memory newGame; | |
newGame.started = true; | |
newGame.ended = false; | |
newGame.totalBuyIns = 0; | |
newGame.totalCashOuts = 0; | |
newGame.totalBalance = 0; | |
currentGame = newGame; | |
gameInProgress = true; | |
} | |
/** | |
* @dev buyIn allows a registered player to buy in to the current game | |
* @param _amount uint256 buy in amount | |
*/ | |
function buyIn(uint256 _amount) public { | |
require(gameInProgress == true, "create a game first"); | |
require(isPlayer[msg.sender] == true, "not a registered player"); | |
currentGame.totalBuyIns += _amount; | |
currentGame.totalBalance += _amount; | |
currentGame.playerTotalBalance[msg.sender] += _amount; | |
currentGame.playerBuyIns[msg.sender] += _amount; | |
playerStats[msg.sender].playerTotalOwed += _amount; | |
playerStats[msg.sender].playerTotalBuyIns += _amount; | |
rebalancePlayerFunds(msg.sender); | |
} | |
/** | |
* @dev cashOut allows player to cash out | |
* @param _amount uint256 amount to cash out | |
*/ | |
function cashOut(uint256 _amount) public { | |
uint256 deposits = currentGame.totalBuyIns; | |
uint256 withdraws = currentGame.totalCashOuts; | |
uint256 gameBalance = currentGame.totalBalance; | |
require(gameBalance == (deposits - withdraws), "error"); | |
require((_amount <= deposits + withdraws) && (_amount <= gameBalance), "error"); | |
currentGame.totalCashOuts += _amount; | |
currentGame.totalBalance -= _amount; | |
currentGame.playerTotalBalance[msg.sender] -= _amount; | |
currentGame.playerCashOuts[msg.sender] += _amount; | |
playerStats[msg.sender].playerTotalBalance += _amount; | |
playerStats[msg.sender].playerTotalCashOuts += _amount; | |
rebalancePlayerFunds(msg.sender); | |
if (currentGame.totalBalance == 0 && currentGame.totalCashOuts == currentGame.totalBuyIns) { | |
gameInProgress = false; | |
currentGame.ended = true; | |
gameHistory.push(currentGame); | |
} | |
} | |
/** | |
* @dev rebalancePlayerFunds reconciles player balance vs player owed amount | |
* @dev this function is called internally following a buy in or cash out | |
* @param _player address of the player | |
*/ | |
function rebalancePlayerFunds(address _player) internal { | |
if(playerStats[_player].playerTotalBalance >= playerStats[_player].playerTotalOwed) { | |
playerStats[_player].playerTotalBalance -= playerStats[_player].playerTotalOwed; | |
playerStats[_player].playerTotalOwed = 0; | |
} else { | |
playerStats[_player].playerTotalOwed -= playerStats[_player].playerTotalBalance; | |
playerStats[_player].playerTotalBalance = 0; | |
} | |
} | |
function playerCurrentGameStats() public view returns(uint256, uint256, uint256) { | |
return(currentGame.playerTotalBalance[msg.sender], currentGame.playerCashOuts[msg.sender], currentGame.playerBuyIns[msg.sender]); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment