1.dApp的名称:二十一点/Black Jack
2.dApp的介绍:
简介:
黑杰克,也称为 21 点,是世界上最受欢迎的游戏之一。黑杰克是一种玩家与庄家对阵的纸牌游戏。黑杰克使用一副扑克牌进行游戏。
规则:
玩家的目标是使自己的手牌分数达到 21 点,或达到一个比庄家更高且不超过 21 点的分数。
开始时,玩家向桌上投放赌注,庄家为玩家分配两张牌。J、Q 和 K 每张按 10 点计分。A 对于庄家和玩家均按 1 点或 11 点计分。其他纸牌均按纸牌上所显示的对应数值计分。
得到初始的两张牌后,将两张牌所代表的数值相加。之后玩家可以选择“加牌”以获得更多的牌,或选择“停牌”并停止获得新的牌。在指定的回合中,玩家或庄家达到 21 点或分数小于 21 点但大于对方即为胜。得分高于 21 点(称为“爆牌”)即为败。如庄家爆牌,玩家手牌分数为任何小于 21 点的分数,则玩家胜。
如相加后庄家和玩家手牌分数相等,则该局为和局并称为“push”。和局中玩家不会赢得或输掉任何筹码。
玩家操作:
以下是初始两张牌分发后玩家可采取的操作的列表:
要牌: 从庄家处得到一张牌。
开牌: 保留现有手牌数,不再加牌。
投降: 如果发牌后您不想继续玩了,可以选择放弃。当玩家选择放弃时,庄家赢得玩家所下注的赌金的一半,而另一半则返还给玩家。
3.上线状态: 否
4.dApp的合约地址: vite_2755a753c3db610a3f910b35b10e6166f7440b8b705a723ee4
5.合约代码如下:
pragma soliditypp ^0.4.3;
contract ViteBet{
address owner;
struct GameData {
tokenId tkid;
uint256 betAmount;
bool isStart;
uint256 cardsOnTable;
uint256 playerCards;
uint256 playerSum;
uint256 npcCards;
uint256 npcSum;
}
mapping(address => GameData) public gameDataMap;
event blackjack(address indexed addr, uint256 playerCards, uint256 npcCards, uint8 result, uint256 reward);
constructor() public {
owner = msg.sender;
}
onMessage () payable {
}
onMessage DrawMoney(uint256 amount) {
require(owner == msg.sender);
msg.sender.transfer(msg.tokenid, amount);
}
onMessage startGame() payable {
require(msg.amount > 0 && msg.amount <= 1000000000000000000000);
gameDataMap[msg.sender].betAmount = msg.amount;
gameDataMap[msg.sender].isStart = true;
gameDataMap[msg.sender].cardsOnTable = 0;
gameDataMap[msg.sender].tkid = msg.tokenid;
gameDataMap[msg.sender].playerCards = 0;
gameDataMap[msg.sender].playerSum = 0;
gameDataMap[msg.sender].npcCards = 0;
gameDataMap[msg.sender].npcSum = 0;
uint256 card1 = giveCard(msg.sender,true);
uint256 card2 = giveCard(msg.sender,true);
uint256 card3 = giveCard(msg.sender,false);
uint256 sum = calculateSum(gameDataMap[msg.sender].playerCards,gameDataMap[msg.sender].playerSum);
if(sum == 21)
autoFinishGame(msg.sender,0);
else
emit blackjack(msg.sender,gameDataMap[msg.sender].playerCards,gameDataMap[msg.sender].npcCards, 0 , 0);
}
onMessage gameAction(uint8 action) {
require(gameDataMap[msg.sender].isStart);
uint8 result;
if(action == 11){
uint256 card = giveCard(msg.sender,true);
uint256 sum = calculateSum(gameDataMap[msg.sender].playerCards,gameDataMap[msg.sender].playerSum);
if(sum < 21){
emit blackjack(msg.sender,gameDataMap[msg.sender].playerCards,gameDataMap[msg.sender].npcCards, 0 , 0);
return;
}else if(sum > 21)
result = 2;
}else if(action == 14)
result = 4;
autoFinishGame(msg.sender, result);
}
function autoFinishGame(address addr,uint8 result) public {
uint256 transferAmount;
if(result == 0){
uint256 npcSum = calculateSum(gameDataMap[addr].npcCards,gameDataMap[addr].npcSum);
while (npcSum < 17){
giveCard(addr,false);
npcSum = calculateSum(gameDataMap[addr].npcCards,gameDataMap[addr].npcSum);
}
uint256 playerSum = calculateSum(gameDataMap[addr].playerCards,gameDataMap[addr].playerSum);
if (playerSum > 21)
result = 2;
else if (npcSum > 21)
result = 1;
else if (playerSum == npcSum)
result = 3;
else
result = playerSum > npcSum ? 1 : 2;
if(result == 1)
transferAmount = gameDataMap[addr].betAmount * 19 / 10;
else if(result == 3)
transferAmount = gameDataMap[addr].betAmount;
}else if(result == 4){
transferAmount = gameDataMap[msg.sender].betAmount / 2;
}
gameDataMap[addr].isStart = false;
if(transferAmount > 0)
addr.transfer(gameDataMap[addr].tkid,transferAmount);
tokenId vgc = "tti_3ccb0fe9845a720b65039e9e";
addr.transfer(vgc, gameDataMap[msg.sender].betAmount * 5 / 100);
emit blackjack(addr,gameDataMap[addr].playerCards,gameDataMap[addr].npcCards, result , transferAmount);
}
function giveCard(address addr,bool toPlayer) public returns(uint256) {
uint256 card;
uint256 retCard;
(gameDataMap[addr].cardsOnTable,card) = nextCard(gameDataMap[addr].cardsOnTable);
retCard = card;
card = (card % 13);
uint256 toAdd;
if (card >= 9)
toAdd = 10;
else
toAdd = card + 1;
if(toPlayer){
gameDataMap[addr].playerCards |= ( 1 << retCard);
gameDataMap[addr].playerSum += toAdd;
}else{
gameDataMap[addr].npcCards |= ( 1 << retCard);
gameDataMap[addr].npcSum += toAdd;
}
return retCard;
}
function nextCard(uint256 cardsOnTable) public returns(uint256,uint256) {
//uint64 index = nextrandom();
uint64 index = random64();
index = index % 52;
uint256 card = 0;
for (uint8 i = 0; i < 52; ++i){
index = (index + i) % 52;
uint256 j = (1 << index);
if ((cardsOnTable & j) == 0){
card = index;
cardsOnTable = cardsOnTable | j;
break;
}
}
return (cardsOnTable,card);
}
function calculateSum(uint256 cards,uint256 sum) public returns(uint256) {
bool hasAcer = ((cards & (1 << 0)) !=0) ||
((cards & (1 << 13)) !=0) ||
((cards & (1 << 26)) !=0) ||
((cards & (1 << 39)) !=0);
if (hasAcer && (sum + 10) <= 21)
return sum + 10;
return sum;
}
}