刚上手练习,有兴趣的我们开个qq群
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
/** 以最后一个押注的人的时间戳的末尾数字的单双来计算 */
contract game {
struct Player {
address addr;
/** 单双,0是单,1是双 */
uint256 pan;
uint256 coin;
}
uint256 private interval = 1 * 60;
Player[] players;
address owner;
uint256 starttime;
uint256 public last;
constructor() {
owner = msg.sender;
}
modifier onlyOwner() {
require(owner == msg.sender, "only owner");
_;
}
modifier beforeGame() {
require(starttime == 0, "NOT before game");
_;
}
/** 游戏持续5分钟 */
modifier gaming() {
require(
block.timestamp >= starttime &&
block.timestamp < starttime + interval,
"NOT in game"
);
_;
}
modifier afterGame() {
require(
starttime != 0 && block.timestamp >= starttime + interval,
"NOT after game"
);
_;
}
/** 开始游戏 */
function start() public onlyOwner beforeGame {
starttime = block.timestamp;
}
/** 下注 */
function bet(uint256 pan) public payable gaming {
require(pan == 0 || pan == 1, "only 0 OR 1 ");
Player memory p = Player({addr: msg.sender, pan: pan, coin: msg.value});
players.push(p);
last = block.timestamp;
}
/** 计算出胜利的玩家 */
function calWinner() public payable afterGame {
uint256 pan = last % 8 >= 4 ? 0 : 1;
/** 失去代币的玩家的金额总和 */
uint256 lost = 0;
/** 赢得代币的玩家的金额总和 */
uint256 win = 0;
for (uint256 i = 0; i < players.length; i++) {
if (players[i].pan == pan) {
win += players[i].coin;
} else {
lost += players[i].coin;
}
}
// 抽水,2%
uint256 realLost = (lost * 49) / 50;
payable(owner).transfer(lost - realLost);
// 按照比例去切分获利
for (uint256 i = 0; i < players.length; i++) {
if (players[i].pan == pan) {
uint256 reward = realLost * (players[i].coin / win);
payable(players[i].addr).transfer(reward);
}
}
// 标记游戏可以被重新开启
starttime = 0;
for (; players.length > 0; ) {
players.pop();
}
last = 0;
}
}