Розробка гри Dice на блокчейні
Dice — базова казино гра: гравець вибирає число (поріг) і напрямок (roll over / roll under), робить ставку. Якщо результат броска відповідає умові — виграш. Найпростіша механіка, але реалізація вимагає уваги до математики house edge і обов'язкового verifiable randomness.
Математика Dice
Стандартний діапазон: 1-100 (або 0.00-99.99 дробовий).
Roll over 50: шанс виграти = 50%, справедливий множник = 2x. Реальний з 1% house edge = 1.98x.
Формула: multiplier = (100 - houseEdge) / winProbability
Roll over 75: winProbability = 25%, multiplier = 99/25 = 3.96x. Roll under 10: winProbability = 9%, multiplier = 99/9 = 11x.
Допустимий діапазон: roll over 2-97 і roll under 3-98 (щоб house edge залишався розумним).
Smart contract
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
contract BlockchainDice is VRFConsumerBaseV2Plus {
uint256 public houseEdge = 100; // 1% в basis points
struct DiceBet {
address player;
uint256 amount;
uint8 target; // 1-99
bool isOver; // roll over або roll under
uint256 potentialPayout;
bool settled;
}
mapping(uint256 => DiceBet) public bets;
function roll(uint8 target, bool isOver) external payable returns (uint256 requestId) {
require(msg.value >= MIN_BET && msg.value <= getMaxBet(), "Invalid bet");
require(target >= 2 && target <= 98, "Invalid target");
uint256 payout = calculatePayout(msg.value, target, isOver);
require(address(this).balance >= payout, "Insufficient bankroll");
requestId = _requestVRF();
bets[requestId] = DiceBet({
player: msg.sender,
amount: msg.value,
target: target,
isOver: isOver,
potentialPayout: payout,
settled: false,
});
}
function calculatePayout(
uint256 betAmount,
uint8 target,
bool isOver
) public view returns (uint256) {
uint256 winProbability;
if (isOver) {
winProbability = 100 - uint256(target);
} else {
winProbability = uint256(target) - 1;
}
require(winProbability > 0 && winProbability < 100, "Invalid probability");
uint256 multiplier = ((10000 - houseEdge) * 100) / winProbability;
return (betAmount * multiplier) / 10000;
}
function fulfillRandomWords(uint256 requestId, uint256[] calldata randomWords)
internal override
{
DiceBet storage bet = bets[requestId];
require(!bet.settled, "Already settled");
bet.settled = true;
// Генерируємо число 1-100
uint8 roll = uint8((randomWords[0] % 100) + 1);
bool win = bet.isOver ? roll > bet.target : roll < bet.target;
if (win) {
payable(bet.player).transfer(bet.potentialPayout);
}
}
function getMaxBet() public view returns (uint256) {
return address(this).balance / 100;
}
}
High-Low варіант
Гравець вибирає діапазон (наприклад, від 25 до 75), виграває якщо roll в діапазоні. Більш інтуїтивний UI.
UX для швидкого gameplay
Dice — швидка гра. Гравці роблять десятки ставок в хвилину. UX повинен це підтримувати:
- Швидкі пресети (½x, 2x ставка, max bet)
- Автоматичний режим з настроюваними стратегіями
- Миттєвий feedback (анімація кубиків, звуки)
- Історія ставок з результатами
На L2 (Arbitrum, Polygon): VRF delay 3-15 сек — прийнятно. На Ethereum mainnet може бути дискомфортно.
Розробка Dice контракту з VRF — 2-3 тижні. З frontend (React + анімаціями) і auto режимом — 4-5 тижнів.







