Skip to content

Commit

Permalink
novomatic/dynastyofra game added.
Browse files Browse the repository at this point in the history
  • Loading branch information
schwarzlichtbezirk committed Jan 31, 2025
1 parent 0ac497b commit 4841752
Show file tree
Hide file tree
Showing 12 changed files with 644 additions and 38 deletions.
15 changes: 7 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,22 @@ Slots games server. Releases functionality for AGT, Novomatic, NetEnt, BetSoft,
Server provides HTTP-based API for popular slots and have well-optimized performance for thousands requests per second. Can be deployed on dedicated server or as portable application for Linux or Windows.

```text
total: 171 games, 83 algorithms, 9 providers
total: 173 games, 84 algorithms, 9 providers
AGT: 56 games
Aristocrat: 4 games
BetSoft: 3 games
Megajack: 4 games
NetEnt: 20 games
Novomatic: 70 games
Novomatic: 72 games
Play'n GO: 3 games
Playtech: 7 games
Slotopol: 4 games
```

*Last added games*:

* '[Dynasty of Ra](https://www.slotsmate.com/software/novomatic/dynasty-of-ra)' Novomatic 5x3 videoslot
* '[Fruits'n Royals](https://www.slotsmate.com/software/novomatic/fruits-n-royals)' Novomatic 5x3 videoslot
* '[Ultra Sevens](https://www.slotsmate.com/software/novomatic/ultra-sevens)' Novomatic 5x4 videoslot with 3 jackpots
* '[Plenty of Jewels 20 hot](https://www.slotsmate.com/software/novomatic/plenty-of-jewels-20-hot)' Novomatic 5x3 videoslot
* '[Dragon's Deep](https://www.slotsmate.com/software/novomatic/dragons-deep)' Novomatic 5x3 videoslot
Expand Down Expand Up @@ -183,11 +185,6 @@ curl -H "Content-Type: application/json" -H "Authorization: Bearer {{token}}" -d

Endpoint receives `alias` identifier to game that represents as concatenation of provider name and game name with slash. For example, `NetEnt/Tiki Wonders`. Whole list of all supported games can be obtained by [list](docs/list-all.md) command. Identifier turns to lowercase without spaces.

* Get information about opened game. Recivies GID. Response has game name, game state, last spin ID, user ID, club ID, and user balance at this club.

```sh
curl -H "Content-Type: application/json" -H "Authorization: Bearer {{token}}" -d '{"gid":1}' -X POST localhost:8080/game/info

* Change number of selected bet lines.

```sh
Expand All @@ -200,6 +197,8 @@ curl -H "Content-Type: application/json" -H "Authorization: Bearer {{token}}" -d
curl -H "Content-Type: application/json" -H "Authorization: Bearer {{token}}" -d '{"gid":1}' -X POST localhost:8080/slot/spin
```

At parameters can be also given new bet value and number of selected lines, if there is no free spins now. So, data at the query can be seen such as `{"gid":1,"bet":2,"sel":5}`. Its can be useful for conversations only by spin-queries.

* Double-up. If presents `gain` after spin, it can be multiplied by gamble. `mult` at argument is multiplier, and it will be `2` for red-black cards game. Returned `gain` will be multiplied on win, and zero on lose. `wallet` represents new balance of user.

```sh
Expand All @@ -212,7 +211,7 @@ curl -H "Content-Type: application/json" -H "Authorization: Bearer {{token}}" -d
curl -H "Content-Type: application/json" -H "Authorization: Bearer {{token}}" -d '{"gid":1}' -X POST localhost:8080/slot/collect
```

* Get information about current game scene.
* Get information about opened game. Recivies GID. Response has game name, game state, last spin ID, user ID, club ID, and user balance at this club.

```sh
curl -H "Content-Type: application/json" -H "Authorization: Bearer {{token}}" -d '{"gid":1}' -X POST localhost:8080/game/info
Expand Down
1 change: 1 addition & 0 deletions cmd/links.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
_ "github.com/slotopol/server/game/slot/novomatic/columbus"
_ "github.com/slotopol/server/game/slot/novomatic/dolphinspearl"
_ "github.com/slotopol/server/game/slot/novomatic/dragonsdeep"
_ "github.com/slotopol/server/game/slot/novomatic/dynastyofra"
_ "github.com/slotopol/server/game/slot/novomatic/fruitilicious"
_ "github.com/slotopol/server/game/slot/novomatic/helena"
_ "github.com/slotopol/server/game/slot/novomatic/inferno"
Expand Down
8 changes: 5 additions & 3 deletions docs/list-all.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
'Down Under' Novomatic 5x3 videoslot
'Dragon's Deep' Novomatic 5x3 videoslot
'Dynasty Of Ming' Novomatic 5x3 videoslot
'Dynasty of Ra' Novomatic 5x3 videoslot
'Egypt' AGT 5x3 videoslot
'Excalibur' NetEnt 5x3 videoslot
'Extra Spin III' AGT 5x3 videoslot
Expand All @@ -68,6 +69,7 @@
'Fortune Teller' Play'n GO 5x3 videoslot
'Fruit Shop' NetEnt 5x3 videoslot
'Fruitilicious' Novomatic 5x3 videoslot
'Fruits'n Royals' Novomatic 5x3 videoslot
'Funky Seventies' NetEnt 5x4 videoslot
'Gate of Ra Deluxe' Novomatic 5x3 videoslot
'Geisha Wonders' NetEnt 5x3 videoslot
Expand Down Expand Up @@ -164,7 +166,7 @@
'Ultra Gems' Novomatic 3x3 videoslot
'Ultra Hot Deluxe' Novomatic 3x3 videoslot
'Ultra Hot' Novomatic 3x3 videoslot
'Ultra Sevens' Novomatic 5x3 videoslot
'Ultra Sevens' Novomatic 5x4 videoslot
'Unicorn Magic' Novomatic 5x3 videoslot
'Valentine's Day' AGT 5x3 videoslot
'Valkyrie' AGT 5x3 videoslot
Expand All @@ -174,13 +176,13 @@
'Wild Witches' NetEnt 5x3 videoslot
'Wizard' AGT 5x4 videoslot
total: 171 games, 83 algorithms, 9 providers
total: 173 games, 84 algorithms, 9 providers
AGT: 56 games
Aristocrat: 4 games
BetSoft: 3 games
Megajack: 4 games
NetEnt: 20 games
Novomatic: 70 games
Novomatic: 72 games
Play'n GO: 3 games
Playtech: 7 games
Slotopol: 4 games
Expand Down
38 changes: 12 additions & 26 deletions game/slot/novomatic/bookofra/bookofra_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ var LinePay = [10][5]float64{
{0, 0, 5, 25, 100}, // 7 queen
{0, 0, 5, 25, 100}, // 8 jack
{0, 0, 5, 25, 100}, // 9 ten
{0, 0, 0, 0, 0}, // 10 tomb
{}, // 10 tomb
}

// Scatters payment.
Expand Down Expand Up @@ -106,31 +106,17 @@ func (g *Game) ScanLined(wins *slot.Wins) {
}
}

var payw, payl float64
if numw > 0 {
payw = LinePay[book-1][numw-1]
}
if numl > 0 && syml > 0 {
payl = LinePay[syml-1][numl-1]
}
if payl > payw {
*wins = append(*wins, slot.WinItem{
Pay: g.Bet * payl,
Mult: 1,
Sym: syml,
Num: numl,
Line: li,
XY: line.CopyL(numl),
})
} else if payw > 0 {
*wins = append(*wins, slot.WinItem{
Pay: g.Bet * payw,
Mult: 1,
Sym: book,
Num: numw,
Line: li,
XY: line.CopyL(numw),
})
if syml > 0 {
if payl := LinePay[syml-1][numl-1]; payl > 0 {
*wins = append(*wins, slot.WinItem{
Pay: g.Bet * payl,
Mult: 1,
Sym: syml,
Num: numl,
Line: li,
XY: line.CopyL(numl),
})
}
}
}

Expand Down
11 changes: 11 additions & 0 deletions game/slot/novomatic/dynastyofra/dynastyofra_bon.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

# reels lengths [34, 34, 34, 34, 34], total reshuffles 45435424
# symbols: 507.35(lined) + 1.8018(scatter) = 509.147554%
# free spins 2722680, q = 0.059924, sq = 1/(1-q) = 1.063744
# free games frequency: 1/166.88
# RTP = sq*rtp(sym) = 1.0637*509.15 = 541.602642%
- [10, 3, 9, 5, 6, 3, 7, 5, 9, 7, 6, 9, 2, 8, 4, 6, 8, 2, 10, 1, 9, 10, 8, 1, 7, 6, 4, 8, 3, 11, 5, 10, 4, 7] # 34
- [4, 9, 2, 7, 8, 5, 6, 1, 9, 3, 10, 7, 4, 10, 11, 7, 6, 8, 2, 7, 5, 9, 6, 8, 3, 10, 1, 6, 4, 8, 3, 9, 5, 10] # 34
- [6, 11, 5, 7, 9, 1, 10, 9, 3, 7, 4, 8, 2, 6, 5, 10, 1, 6, 8, 4, 10, 7, 8, 3, 6, 10, 5, 9, 3, 8, 9, 4, 7, 2] # 34
- [9, 7, 4, 8, 3, 9, 11, 4, 6, 10, 7, 3, 8, 10, 3, 6, 5, 9, 8, 2, 7, 1, 10, 5, 6, 1, 8, 2, 9, 4, 10, 5, 7, 6] # 34
- [9, 3, 8, 6, 4, 10, 8, 6, 5, 10, 4, 7, 2, 11, 4, 9, 8, 1, 7, 9, 3, 10, 5, 9, 1, 7, 8, 5, 6, 10, 3, 6, 7, 2] # 34
68 changes: 68 additions & 0 deletions game/slot/novomatic/dynastyofra/dynastyofra_calc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package dynastyofra

import (
"context"
"fmt"
"time"

"github.com/slotopol/server/game/slot"
)

func CalcStatBon(ctx context.Context) float64 {
var reels = ReelsBon
var g = NewGame()
var sln float64 = 1
g.Sel = int(sln)
g.FSR = 10 // set free spins mode
var s slot.Stat

var dur = slot.ScanReels5x(ctx, &s, g, reels,
time.Tick(2*time.Second), time.Tick(2*time.Second))

var reshuf = float64(s.Reshuffles)
var lrtp, srtp = s.LinePay / reshuf / sln * 100, s.ScatPay / reshuf / sln * 100
var rtpsym = lrtp + srtp
var q = float64(s.FreeCount) / reshuf
var sq = 1 / (1 - q)
var rtp = sq * rtpsym
fmt.Printf("completed %.5g%%, selected %d lines, time spent %v\n", reshuf/float64(s.Planned())*100, g.Sel, dur)
fmt.Printf("reels lengths [%d, %d, %d, %d, %d], total reshuffles %d\n",
len(reels.Reel(1)), len(reels.Reel(2)), len(reels.Reel(3)), len(reels.Reel(4)), len(reels.Reel(5)), reels.Reshuffles())
fmt.Printf("symbols: %.5g(lined) + %.5g(scatter) = %.6f%%\n", lrtp, srtp, rtpsym)
fmt.Printf("free spins %d, q = %.5g, sq = 1/(1-q) = %.6f\n", s.FreeCount, q, sq)
fmt.Printf("free games frequency: 1/%.5g\n", reshuf/float64(s.FreeHits))
fmt.Printf("RTP = sq*rtp(sym) = %.5g*%.5g = %.6f%%\n", sq, rtpsym, rtp)
return rtp
}

func CalcStatReg(ctx context.Context, mrtp float64) float64 {
fmt.Printf("*bonus reels calculations*\n")
var rtpfs = CalcStatBon(ctx)
if ctx.Err() != nil {
return 0
}
fmt.Printf("*regular reels calculations*\n")
var reels, _ = slot.FindClosest(ReelsMap, mrtp)
var g = NewGame()
var sln float64 = 1
g.Sel = int(sln)
var s slot.Stat

var dur = slot.ScanReels5x(ctx, &s, g, reels,
time.Tick(2*time.Second), time.Tick(2*time.Second))

var reshuf = float64(s.Reshuffles)
var lrtp, srtp = s.LinePay / reshuf / sln * 100, s.ScatPay / reshuf / sln * 100
var rtpsym = lrtp + srtp
var q = float64(s.FreeCount) / reshuf
var sq = 1 / (1 - q)
var rtp = rtpsym + q*rtpfs
fmt.Printf("completed %.5g%%, selected %d lines, time spent %v\n", reshuf/float64(s.Planned())*100, g.Sel, dur)
fmt.Printf("reels lengths [%d, %d, %d, %d, %d], total reshuffles %d\n",
len(reels.Reel(1)), len(reels.Reel(2)), len(reels.Reel(3)), len(reels.Reel(4)), len(reels.Reel(5)), reels.Reshuffles())
fmt.Printf("symbols: %.5g(lined) + %.5g(scatter) = %.6f%%\n", lrtp, srtp, rtpsym)
fmt.Printf("free spins %d, q = %.5g, sq = 1/(1-q) = %.6f\n", s.FreeCount, q, sq)
fmt.Printf("free games frequency: 1/%.5g\n", reshuf/float64(s.FreeHits))
fmt.Printf("RTP = %.5g(sym) + %.5g*%.5g(fg) = %.6f%%\n", rtpsym, q, rtpfs, rtp)
return rtp
}
28 changes: 28 additions & 0 deletions game/slot/novomatic/dynastyofra/dynastyofra_link.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//go:build !prod || full || novomatic

package dynastyofra

import (
"github.com/slotopol/server/game"
)

var Info = game.GameInfo{
Aliases: []game.GameAlias{
{Prov: "Novomatic", Name: "Dynasty of Ra"}, // see: https://www.slotsmate.com/software/novomatic/dynasty-of-ra
},
GP: game.GPsel |
game.GPretrig |
game.GPfgreel |
game.GPscat |
game.GPwild,
SX: 5,
SY: 3,
SN: len(LinePay),
LN: len(BetLines),
BN: 0,
RTP: game.MakeRtpList(ReelsMap),
}

func init() {
Info.SetupFactory(func() any { return NewGame() }, CalcStatReg)
}
Loading

0 comments on commit 4841752

Please sign in to comment.