Accurate slot game in EOS (Proof of concept)
Posted: Thu May 13, 2021 7:58 pm
I got inspired after seeing Super Loser Slot by Shymaroon, to create a proof of concept for an accurate slot in EOS.
https://milovana.com/webteases/showteas ... 9db20e5c96
It features reels with repeating symbols and specific paylines, such as straight lines, V shapes and W shapes. It also has different payouts depending on the type and number of symbols on a payline.
Things can be tweaked easily such as the number of columns and rows, the paylines, the symbols on the reels and their values.
If you're interested in implementing this into a tease, feel free to send me a message if you need help.
Source code:
https://milovana.com/webteases/showteas ... 9db20e5c96
It features reels with repeating symbols and specific paylines, such as straight lines, V shapes and W shapes. It also has different payouts depending on the type and number of symbols on a payline.
Things can be tweaked easily such as the number of columns and rows, the paylines, the symbols on the reels and their values.
If you're interested in implementing this into a tease, feel free to send me a message if you need help.
Source code:
Code: Select all
// The current RTP (return to player) is at around 259% meaning the player will earn more and more over time
// Most online slot games have an RTP of around 96%, meaning the player will loose more than they win over time
// The win values for each symbol,
// the array values represents 1 of a kind, 2 of a kind, 3 of a kind and so on.
// Each array should include the same number of values as the symbolCount
var symbolValues = {
"💎": [0, 0, 25, 100, 500],
"🔔": [0, 0, 10, 50, 200],
"🍓": [0, 0, 3, 25, 100],
"🍒": [0, 0, 2, 15, 50],
"🍈": [0, 0, 1, 5, 20],
"🍇": [0, 0, 1, 5, 20]
}
// Each array represents a diffrent pay line
// with each value in the array representing the symbol row on each column
var paylines = [
[0, 0, 0, 0, 0], // - Straight row 0
[1, 1, 1, 1, 1], // - Straight row 1
[2, 2, 2, 2, 2], // - Straight row 2
[3, 3, 3, 3, 3], // - Straight row 3
[0, 1, 2, 1, 0], // v Shape rows 0,1,2
[1, 2, 3, 2, 1], // v Shape rows 1,2,3
[2, 1, 0, 1, 2], // ^ Shape rows 0,1,2
[3, 2, 1, 2, 3], // ^ Shape rows 1,2,3
[0, 1, 0, 1, 0], // w Shape rows 0,1
[1, 2, 1, 2, 1], // w Shape rows 1,2
[2, 3, 2, 3, 2], // w Shape rows 2,3
[1, 0, 1, 0, 1], // ^^ Shape rows 0,1
[2, 1, 2, 1, 2], // ^^ Shape rows 1,2
[3, 2, 3, 2, 3] // ^^ Shape rows 2,3
]
// Used when displaying payline wins for symbols that are not apart of the win
var blankSymbol = "⬛"
// All the symbols on a reel, in the order that they appear in at any stopping position
var reel = ["💎", "🍓", "🍒", "🔔", "🍇", "🍈", "🍈", "🍒", "🍈", "🍓", "🍇", "🍈", "🍒", "🍇", "🍇", "🔔", "🍓", "🍒", "🍈", "🍇"]
// The number of reels that will spin
var rowCount = 4
// The number of symbols visible on the machine for each reel
var columnCount = 5
// The number of reels that have been stopped
var stoppedReelCount = 0
// All the symbols that the machine will stop on in a 2D array
var symbols = []
// Array of objects with columns and win
var wins = []
// The combined win value from all payline wins
var totalWin = 0
// Current payline win to display
var currentWinIndex = -1
// Initializes the symbols and wins, should be called on a page that starts the spin
function startSpin() {
spinSymbols()
updateWins()
}
// Sets the symbols that the machine will stop on
function spinSymbols() {
symbols = []
stoppedReelCount = 0
for (var col = 0; col < columnCount; col++) {
symbols.push([])
var startIndex = randomInt(0, reel.length - 1)
for (var row = 0; row < rowCount; row++) {
symbols[col].push(getReelSymbol(startIndex + row))
}
}
}
// Stops the next reel, should be called on page that repeats until all reels have been stopped
function stopNextReel() {
stoppedReelCount++
}
// Goes to the next win, should be called on a page that repeats until all payline wins have been presented
function gotoNextWin() {
currentWinIndex++
}
// Returns true if all reels have been stopped
function isAllReelsStopped() {
return stoppedReelCount === columnCount
}
// Returns true if there was any payline wins
function isWin() {
return wins.length > 0
}
// Returns true if we have presented all payline wins
function hasPresentedAllWins() {
return currentWinIndex >= this.wins.length - 1
}
// Updates the wins based on the symbols
function updateWins() {
currentWinIndex = -1
wins = []
totalWin = 0
for (var paylineIndex = 0; paylineIndex < paylines.length; paylineIndex++) {
var firstRow = paylines[paylineIndex][0]
var firstSymbol = symbols[0][firstRow]
var paylineRows = [firstRow]
for (var col = 1; col < columnCount; col++) {
var row = paylines[paylineIndex][col]
var symbol = symbols[col][row]
if (symbol === firstSymbol) {
paylineRows.push(row)
} else {
break
}
}
var winAmount = symbolValues[firstSymbol][paylineRows.length - 1]
if (winAmount > 0) {
totalWin += winAmount
wins.push({
rows: paylineRows,
win: winAmount,
symbol: firstSymbol
})
}
}
}
// Calculates the return to player, meaning how much they will win on average over time,
// more than 1 means the player will win more than they loose
function calculateRTP(spins) {
console.log("Depending on the amount of spins, calculating the RTP may take a while")
// For an accurate RTP, use at least 1000000 spins
var totalWinFromAllSpins = 0
for (var i = 0; i < spins; i++) {
startSpin()
totalWinFromAllSpins += totalWin
}
console.log("RTP:", totalWinFromAllSpins / spins)
}
// Displays the symbols on a given row
function displaySymbols(row) {
var symbolsToDisplay = []
for (var col = 0; col < columnCount; col++) {
if (col < stoppedReelCount) {
symbolsToDisplay.push(symbols[col][row])
} else {
symbolsToDisplay.push(blankSymbol)
}
}
return symbolsToDisplay.join(" ")
}
// Displays the symbols on a given row that are part of a specific win
function displayWinningSymbols(row) {
var symbolsToDisplay = []
var winRows = wins[currentWinIndex].rows
for (var col = 0; col < columnCount; col++) {
if (winRows.length > col && winRows[col] === row) {
symbolsToDisplay.push(symbols[col][row])
} else {
symbolsToDisplay.push(blankSymbol)
}
}
return symbolsToDisplay.join(" ")
}
// Displays the symbol you won on, how many and how much you won for it
function displayWinInfo() {
var ofAKind = ""
if (wins[currentWinIndex].rows.length === 3) {
ofAKind = "Three of a kind "
} else if (wins[currentWinIndex].rows.length === 4) {
ofAKind = "Four of a kind "
} else {
ofAKind = "Five of a kind "
}
return ofAKind + wins[currentWinIndex].symbol + ": " + wins[currentWinIndex].win
}
// Returns the symbol on the reel at a given index, wraps around if the index is out of range
function getReelSymbol(index) {
return reel[index % reel.length]
}
// Returns a random whole number from min up to and including max
function randomInt(min, max) {
return min + Math.floor(Math.random() * (max - min + 1))
}