171 lines
5.5 KiB
Go
171 lines
5.5 KiB
Go
package entity
|
|
|
|
import (
|
|
"github.com/tomas-qstarrs/boost/randx"
|
|
"math"
|
|
"math/rand"
|
|
"mongo.games.com/game/gamesrv/slotspkg/internal/generic/key"
|
|
"mongo.games.com/game/gamesrv/slotspkg/internal/module/shared"
|
|
"mongo.games.com/goserver/core/logger"
|
|
)
|
|
|
|
type RandState struct {
|
|
randx *randx.Randx
|
|
source rand.Source
|
|
tracker *shared.RandxTracker
|
|
enableTracker bool
|
|
}
|
|
|
|
func NewRandState() *RandState {
|
|
return &RandState{
|
|
tracker: &shared.RandxTracker{},
|
|
}
|
|
}
|
|
|
|
func (e *Entity) Randx() *randx.Randx {
|
|
return e.RandState.randx
|
|
}
|
|
|
|
func (e *Entity) PrepareRand() {
|
|
var mode string
|
|
switch {
|
|
case e.NextNode().Type != key.BaseSpin:
|
|
mode = e.NodeTree.Mode // 不是BaseSpin 延续上一次的随机情况
|
|
case e.NodeTree.Act.Stay:
|
|
mode = key.MachineModeLive
|
|
case e.NodeTree.Act.Mode == "":
|
|
mode = key.MachineModeLive
|
|
default:
|
|
mode = e.NodeTree.Act.Mode
|
|
}
|
|
|
|
e.NodeTree.Mode = mode
|
|
|
|
var source rand.Source
|
|
switch mode {
|
|
case key.MachineModeLive:
|
|
source = e.source()
|
|
case key.MachineModeRecorder:
|
|
if e.NextNode().Type == key.BaseSpin {
|
|
// 录制开始
|
|
if e.NodeTree.Act.Vector != nil {
|
|
e.NodeTree.RandVector.Vector = e.NodeTree.Act.Vector
|
|
e.NodeTree.RandVector.VectorIndex = e.NodeTree.Act.VectorIndex
|
|
e.NodeTree.RandVector.VectorType = e.NodeTree.Act.VectorType
|
|
} else {
|
|
e.NodeTree.RandVector.Vector = []int64{e.source().Int63()}
|
|
}
|
|
e.NodeTree.Act.Vector = nil
|
|
e.NodeTree.Act.VectorIndex = 0
|
|
e.NodeTree.Act.VectorType = 0
|
|
e.NodeTree.RandVector.Index = 0
|
|
}
|
|
source = randx.NewLcgVectorPlayer(e.NodeTree.RandVector.Vector, int(e.NodeTree.RandVector.Index))
|
|
case key.MachineModePlayer:
|
|
if e.NextNode().Type == key.BaseSpin {
|
|
// 播放开始
|
|
e.NodeTree.RandVector.Index = 0
|
|
e.NodeTree.RandVector.Vector = e.NodeTree.Act.Vector
|
|
e.NodeTree.RandVector.VectorIndex = e.NodeTree.Act.VectorIndex
|
|
e.NodeTree.RandVector.VectorType = e.NodeTree.Act.VectorType
|
|
e.NodeTree.RandVector.ExpectedWinCoin = e.NodeTree.Act.ExpectedWinCoin
|
|
|
|
e.NodeTree.Act.Vector = nil
|
|
e.NodeTree.Act.VectorIndex = 0
|
|
e.NodeTree.Act.VectorType = 0
|
|
e.NodeTree.Act.ExpectedWinCoin = 0
|
|
}
|
|
source = randx.NewLcgVectorPlayer(e.NodeTree.RandVector.Vector, int(e.NodeTree.RandVector.Index))
|
|
default:
|
|
logger.Logger.Errorf("slots unknown mode: %s", mode)
|
|
}
|
|
|
|
e.RandState.source = source
|
|
e.RandState.randx = randx.New(source)
|
|
|
|
switch mode {
|
|
case key.MachineModeLive:
|
|
e.NodeTree.RandVector.EnableRandxTracker = false
|
|
e.NodeTree.RandVector.RandxTracker = &shared.RandxTracker{}
|
|
e.NodeTree.RandVector.RecorderRandxTracker = &shared.RandxTracker{}
|
|
case key.MachineModeRecorder:
|
|
if e.NextNode().Type == key.BaseSpin {
|
|
e.NodeTree.RandVector.EnableRandxTracker = e.NodeTree.Act.EnableRandxTracker
|
|
e.NodeTree.Act.EnableRandxTracker = false
|
|
e.NodeTree.RandVector.RandxTracker = &shared.RandxTracker{}
|
|
e.NodeTree.RandVector.RecorderRandxTracker = &shared.RandxTracker{}
|
|
}
|
|
case key.MachineModePlayer:
|
|
if e.NextNode().Type == key.BaseSpin {
|
|
e.NodeTree.RandVector.EnableRandxTracker = e.NodeTree.Act.EnableRandxTracker
|
|
e.NodeTree.Act.EnableRandxTracker = false
|
|
e.NodeTree.RandVector.RandxTracker = &shared.RandxTracker{}
|
|
e.NodeTree.RandVector.RecorderRandxTracker = e.NodeTree.Act.RecorderRandxTracker
|
|
e.NodeTree.Act.RecorderRandxTracker = &shared.RandxTracker{}
|
|
}
|
|
default:
|
|
logger.Logger.Errorf("slots unknown mode: %s", mode)
|
|
}
|
|
|
|
e.RandState.enableTracker = e.NodeTree.RandVector.EnableRandxTracker
|
|
e.RandState.tracker = e.NodeTree.RandVector.RandxTracker
|
|
}
|
|
|
|
func (e *Entity) source() rand.Source {
|
|
var source rand.Source
|
|
if v := e.Session.Value(key.SessionMachineSource); v == nil {
|
|
seed := randx.Int63n(math.MaxInt64)
|
|
source = rand.NewSource(seed)
|
|
e.Session.Set(key.SessionMachineSource, source)
|
|
} else {
|
|
source = v.(rand.Source)
|
|
}
|
|
return source
|
|
}
|
|
func (e *Entity) RandxTracker() *shared.RandxTracker {
|
|
return e.RandState.tracker
|
|
}
|
|
func (e *Entity) CompareRandx() (bool, string, string) {
|
|
if !e.RandState.enableTracker {
|
|
return false, "", ""
|
|
}
|
|
playerTracker := e.RandState.tracker
|
|
recorderTracker := e.NodeTree.RandVector.RecorderRandxTracker
|
|
if len(recorderTracker.Items) < len(playerTracker.Items) {
|
|
for i, item := range recorderTracker.Items {
|
|
if item.Index != playerTracker.Items[i].Index {
|
|
return true, recorderTracker.Items[i-1].Tag, item.Tag
|
|
}
|
|
}
|
|
return true, playerTracker.Items[len(recorderTracker.Items)-1].Tag, playerTracker.Items[len(recorderTracker.Items)].Tag
|
|
} else if len(recorderTracker.Items) > len(playerTracker.Items) {
|
|
for i, item := range playerTracker.Items {
|
|
if item.Index != recorderTracker.Items[i].Index {
|
|
return true, playerTracker.Items[i-1].Tag, item.Tag
|
|
}
|
|
}
|
|
return true, recorderTracker.Items[len(playerTracker.Items)-1].Tag, recorderTracker.Items[len(playerTracker.Items)].Tag
|
|
} else {
|
|
for i, item := range recorderTracker.Items {
|
|
if item.Index != playerTracker.Items[i].Index {
|
|
return true, recorderTracker.Items[i-1].Tag, item.Tag
|
|
}
|
|
}
|
|
}
|
|
return false, "", ""
|
|
}
|
|
|
|
func (e *Entity) SyncRand() {
|
|
switch e.NodeTree.Mode {
|
|
case key.MachineModeRecorder, key.MachineModePlayer:
|
|
e.NodeTree.RandVector.Vector = e.RandState.source.(*randx.LcgVectorPlayer).Vector
|
|
e.NodeTree.RandVector.Index = int64(e.RandState.source.(*randx.LcgVectorPlayer).Index)
|
|
e.NodeTree.RandVector.RandxTracker = e.RandState.tracker
|
|
e.NodeTree.RandVector.EnableRandxTracker = e.RandState.enableTracker
|
|
case key.MachineModeLive:
|
|
// Do nothing
|
|
default:
|
|
logger.Logger.Errorf("slots unknown mode: %s", e.NodeTree.Mode)
|
|
}
|
|
}
|