427 lines
12 KiB
Go
427 lines
12 KiB
Go
package machine
|
|
|
|
import (
|
|
"encoding/json"
|
|
"github.com/tomas-qstarrs/boost/mathx"
|
|
"mongo.games.com/game/gamesrv/slotspkg/internal/generic/key"
|
|
"mongo.games.com/game/gamesrv/slotspkg/internal/module/shared"
|
|
"mongo.games.com/game/gamesrv/slotspkg/slots/entity"
|
|
"mongo.games.com/game/gamesrv/slotspkg/slots/intf"
|
|
"mongo.games.com/game/gamesrv/slotspkg/slots/reg"
|
|
"reflect"
|
|
)
|
|
|
|
// Close serialize the machine
|
|
func (m *Machine) Close() *shared.NodeTree {
|
|
m.Serialize()
|
|
m.Session.Remove(key.SessionMachine)
|
|
return m.NodeTree
|
|
}
|
|
|
|
// Close serialize the machine
|
|
func (m *Machine) PlayClose() *shared.NodeTree {
|
|
m.Serialize()
|
|
m.Session.Remove(key.SessionMachine)
|
|
return m.NodeTree
|
|
}
|
|
|
|
// SyncLiteClose serialize the machine and transform into lite node tree for sync
|
|
func (m *Machine) SyncLiteClose() *shared.LiteNodeTree {
|
|
m.Serialize()
|
|
m.Session.Remove(key.SessionMachine)
|
|
|
|
liteNodeTree := &shared.LiteNodeTree{
|
|
Step: m.NodeTree.Step,
|
|
Cursor: m.NodeTree.Cursor,
|
|
Next: m.NodeTree.Next,
|
|
Closing: m.NodeTree.Closing,
|
|
Theme: m.Theme,
|
|
}
|
|
|
|
liteNodeTree.Features = make([]*shared.LiteFeature, 0)
|
|
m.WalkTree(entity.WalkRootFirst, func(node *shared.Node) bool {
|
|
for _, feature := range node.Features {
|
|
switch node.ID {
|
|
case m.NodeTree.Cursor, m.NodeTree.Next, m.NodeTree.Root:
|
|
liteNodeTree.Features = append(liteNodeTree.Features,
|
|
&shared.LiteFeature{
|
|
NodeID: feature.NodeID,
|
|
FormationID: feature.FormationID,
|
|
Type: feature.Type,
|
|
Custom: feature.Custom,
|
|
Win: feature.Win,
|
|
})
|
|
}
|
|
}
|
|
|
|
// Continue collecting.
|
|
return false
|
|
})
|
|
|
|
formationIDs := make([]int64, 0)
|
|
liteNodeTree.Formations = make([]*shared.LiteFormation, 0)
|
|
for _, formation := range m.NextNode().Formations {
|
|
formationIDs = append(formationIDs, formation.ID)
|
|
liteNodeTree.Formations = append(liteNodeTree.Formations,
|
|
&shared.LiteFormation{
|
|
ID: formation.ID,
|
|
SpinType: formation.SpinType,
|
|
NodeType: formation.NodeType,
|
|
NodeID: formation.NodeID,
|
|
InitSymbols: formation.InitSymbols,
|
|
LinkPositions: formation.LinkPositions,
|
|
FinalSymbols: formation.FinalSymbols,
|
|
Win: formation.Win,
|
|
RandPositions: formation.RandPositions,
|
|
MatrixForm: formation.MatrixForm,
|
|
NewNodeType: formation.NewNodeType,
|
|
})
|
|
}
|
|
for _, formation := range m.NodeTree.ImageFormations {
|
|
if mathx.In(formation.ID, formationIDs) {
|
|
continue
|
|
}
|
|
liteNodeTree.Formations = append(liteNodeTree.Formations,
|
|
&shared.LiteFormation{
|
|
ID: formation.ID,
|
|
SpinType: formation.SpinType,
|
|
NodeType: formation.NodeType,
|
|
NodeID: formation.NodeID,
|
|
FinalSymbols: formation.FinalSymbols,
|
|
LinkPositions: formation.LinkPositions,
|
|
Win: formation.Win,
|
|
RandPositions: formation.RandPositions,
|
|
MatrixForm: formation.MatrixForm,
|
|
NewNodeType: formation.NewNodeType,
|
|
})
|
|
}
|
|
|
|
liteNodeTree.Nodes = make([]*shared.LiteNode, 0)
|
|
for _, node := range m.NodeTree.Nodes {
|
|
liteNodeTree.Nodes = append(liteNodeTree.Nodes,
|
|
&shared.LiteNode{
|
|
ID: node.ID,
|
|
Parent: node.Parent,
|
|
Children: node.Children,
|
|
Type: node.Type,
|
|
SpinType: node.SpinType,
|
|
Win: node.Win,
|
|
TotalWin: node.TotalWin,
|
|
ChildrenTotalWin: node.ChildrenTotalWin,
|
|
ProgressValue: node.ProgressValue,
|
|
ProgressMax: node.ProgressMax,
|
|
Bet: node.Bet,
|
|
})
|
|
}
|
|
|
|
return liteNodeTree
|
|
}
|
|
|
|
// PlayLiteClose serialize the machine and transform into lite node tree for play
|
|
func (m *Machine) PlayLiteClose() *shared.LiteNodeTree {
|
|
m.Serialize()
|
|
//m.Session.Remove(key.SessionMachine)
|
|
|
|
liteNodeTree := &shared.LiteNodeTree{
|
|
Step: m.NodeTree.Step,
|
|
Cursor: m.NodeTree.Cursor,
|
|
Next: m.NodeTree.Next,
|
|
Closing: m.NodeTree.Closing,
|
|
BetCoin: m.NodeTree.BetCoin,
|
|
Theme: m.Theme,
|
|
}
|
|
|
|
liteNodeTree.Features = make([]*shared.LiteFeature, 0)
|
|
m.WalkTree(entity.WalkRootFirst, func(node *shared.Node) bool {
|
|
for _, feature := range node.Features {
|
|
if !feature.Visiable {
|
|
// Prune invisiable feature.
|
|
continue
|
|
}
|
|
switch node.ID {
|
|
case m.NodeTree.Cursor, m.NodeTree.Next, m.NodeTree.Root:
|
|
liteNodeTree.Features = append(liteNodeTree.Features,
|
|
&shared.LiteFeature{
|
|
NodeID: feature.NodeID,
|
|
FormationID: feature.FormationID,
|
|
Type: feature.Type,
|
|
Custom: feature.Custom,
|
|
Win: feature.Win,
|
|
})
|
|
}
|
|
}
|
|
|
|
// Continue collecting.
|
|
return false
|
|
})
|
|
|
|
formationIDs := make([]int64, 0)
|
|
liteNodeTree.Formations = make([]*shared.LiteFormation, 0)
|
|
for _, formation := range m.CursorNode().Formations {
|
|
formationIDs = append(formationIDs, formation.ID)
|
|
liteNodeTree.Formations = append(liteNodeTree.Formations,
|
|
&shared.LiteFormation{
|
|
ID: formation.ID,
|
|
SpinType: formation.SpinType,
|
|
NodeType: formation.NodeType,
|
|
NodeID: formation.NodeID,
|
|
DisplaySymbols: formation.DisplaySymbols,
|
|
FinalSymbols: formation.FinalSymbols,
|
|
LinkPositions: formation.LinkPositions,
|
|
Win: formation.Win,
|
|
RandPositions: formation.RandPositions,
|
|
MatrixForm: formation.MatrixForm,
|
|
RewardInfo: formation.RewardInfo,
|
|
NewNodeType: formation.NewNodeType,
|
|
})
|
|
}
|
|
for _, formation := range m.NextNode().Formations {
|
|
if mathx.In(formation.ID, formationIDs) {
|
|
continue
|
|
}
|
|
liteNodeTree.Formations = append(liteNodeTree.Formations,
|
|
&shared.LiteFormation{
|
|
ID: formation.ID,
|
|
SpinType: formation.SpinType,
|
|
NodeType: formation.NodeType,
|
|
NodeID: formation.NodeID,
|
|
InitSymbols: formation.InitSymbols,
|
|
LinkPositions: formation.LinkPositions,
|
|
FinalSymbols: formation.FinalSymbols,
|
|
Win: formation.Win,
|
|
RandPositions: formation.RandPositions,
|
|
MatrixForm: formation.MatrixForm,
|
|
RewardInfo: formation.RewardInfo,
|
|
NewNodeType: formation.NewNodeType,
|
|
})
|
|
}
|
|
|
|
liteNodeTree.Nodes = make([]*shared.LiteNode, 0)
|
|
for _, node := range m.NodeTree.Nodes {
|
|
liteNodeTree.Nodes = append(liteNodeTree.Nodes,
|
|
&shared.LiteNode{
|
|
ID: node.ID,
|
|
Parent: node.Parent,
|
|
Children: node.Children,
|
|
Type: node.Type,
|
|
SpinType: node.SpinType,
|
|
Win: node.Win,
|
|
TotalWin: node.TotalWin,
|
|
ChildrenTotalWin: node.ChildrenTotalWin,
|
|
ProgressValue: node.ProgressValue,
|
|
ProgressMax: node.ProgressMax,
|
|
Bet: node.Bet,
|
|
})
|
|
}
|
|
|
|
return liteNodeTree
|
|
}
|
|
|
|
// QuitLiteClose serialize the machine
|
|
func (m *Machine) QuitLiteClose() *shared.LiteNodeTree {
|
|
m.Serialize()
|
|
m.Session.Remove(key.SessionMachine)
|
|
|
|
liteNodeTree := &shared.LiteNodeTree{
|
|
Step: m.NodeTree.Step,
|
|
Cursor: m.NodeTree.Cursor,
|
|
Next: m.NodeTree.Next,
|
|
Closing: m.NodeTree.Closing,
|
|
Theme: m.Theme,
|
|
}
|
|
|
|
liteNodeTree.Features = make([]*shared.LiteFeature, 0)
|
|
m.WalkTree(entity.WalkRootFirst, func(node *shared.Node) bool {
|
|
for _, feature := range node.Features {
|
|
if !feature.Visiable {
|
|
// Prune invisiable feature.
|
|
continue
|
|
}
|
|
switch node.ID {
|
|
case m.NodeTree.Cursor, m.NodeTree.Next, m.NodeTree.Root:
|
|
liteNodeTree.Features = append(liteNodeTree.Features,
|
|
&shared.LiteFeature{
|
|
NodeID: feature.NodeID,
|
|
FormationID: feature.FormationID,
|
|
Type: feature.Type,
|
|
Custom: feature.Custom,
|
|
Win: feature.Win,
|
|
})
|
|
}
|
|
}
|
|
|
|
// Continue collecting.
|
|
return false
|
|
})
|
|
|
|
formationIDs := make([]int64, 0)
|
|
liteNodeTree.Formations = make([]*shared.LiteFormation, 0)
|
|
for _, formation := range m.NextNode().Formations {
|
|
formationIDs = append(formationIDs, formation.ID)
|
|
liteNodeTree.Formations = append(liteNodeTree.Formations,
|
|
&shared.LiteFormation{
|
|
ID: formation.ID,
|
|
SpinType: formation.SpinType,
|
|
NodeType: formation.NodeType,
|
|
NodeID: formation.NodeID,
|
|
InitSymbols: formation.InitSymbols,
|
|
LinkPositions: formation.LinkPositions,
|
|
FinalSymbols: formation.FinalSymbols,
|
|
Win: formation.Win,
|
|
RandPositions: formation.RandPositions,
|
|
NewNodeType: formation.NewNodeType,
|
|
})
|
|
}
|
|
for _, formation := range m.NodeTree.ImageFormations {
|
|
if mathx.In(formation.ID, formationIDs) {
|
|
continue
|
|
}
|
|
liteNodeTree.Formations = append(liteNodeTree.Formations,
|
|
&shared.LiteFormation{
|
|
ID: formation.ID,
|
|
SpinType: formation.SpinType,
|
|
NodeType: formation.NodeType,
|
|
NodeID: formation.NodeID,
|
|
FinalSymbols: formation.FinalSymbols,
|
|
LinkPositions: formation.LinkPositions,
|
|
Win: formation.Win,
|
|
RandPositions: formation.RandPositions,
|
|
NewNodeType: formation.NewNodeType,
|
|
})
|
|
}
|
|
|
|
liteNodeTree.Nodes = make([]*shared.LiteNode, 0)
|
|
for _, node := range m.NodeTree.Nodes {
|
|
liteNodeTree.Nodes = append(liteNodeTree.Nodes,
|
|
&shared.LiteNode{
|
|
ID: node.ID,
|
|
Parent: node.Parent,
|
|
Children: node.Children,
|
|
Type: node.Type,
|
|
SpinType: node.SpinType,
|
|
Win: node.Win,
|
|
TotalWin: node.TotalWin,
|
|
ChildrenTotalWin: node.ChildrenTotalWin,
|
|
ProgressValue: node.ProgressValue,
|
|
ProgressMax: node.ProgressMax,
|
|
Bet: node.Bet,
|
|
})
|
|
}
|
|
|
|
return liteNodeTree
|
|
}
|
|
|
|
// GetNodeTree returns raw node tree
|
|
func (m *Machine) GetNodeTree() *shared.NodeTree {
|
|
return m.NodeTree
|
|
}
|
|
|
|
// Play plays once
|
|
func (m *Machine) Play(act *shared.Act) {
|
|
m.UpdateAct(act)
|
|
|
|
if m.NodeTree.Act.Stay {
|
|
m.Stay()
|
|
} else {
|
|
m.Step()
|
|
}
|
|
}
|
|
|
|
// Summary is called on simulator summary
|
|
func (m *Machine) Summary() string {
|
|
if _, ok := reg.Plugins[m.Theme]; !ok {
|
|
return ""
|
|
}
|
|
for _, t := range reg.Plugins[m.Theme] {
|
|
reflect.New(t.Elem()).Interface().(intf.Plugin).OnSummary(m)
|
|
}
|
|
return m.String("Summary")
|
|
}
|
|
|
|
// GetSymbolLinkPays passes formation symbol link pay info to simulator
|
|
func (m *Machine) GetSymbolLinkPays() []map[int64]map[int64]float64 {
|
|
symbolLinkPays := make([]map[int64]map[int64]float64, 0)
|
|
for _, originFormation := range m.OriginFormations {
|
|
symbolLinkPays = append(symbolLinkPays, originFormation.SymbolLinkPay)
|
|
}
|
|
return symbolLinkPays
|
|
}
|
|
|
|
// CursorType gets cursor node type
|
|
func (m *Machine) CursorType() string {
|
|
return m.CursorNode().Type
|
|
}
|
|
|
|
// NextType gets next node type
|
|
func (m *Machine) NextType() string {
|
|
return m.NextNode().Type
|
|
}
|
|
|
|
// ParentType gets parent node type
|
|
func (m *Machine) ParentType() string {
|
|
return m.ParentNode().Type
|
|
}
|
|
|
|
// AncestorType gets ancestor node type
|
|
func (m *Machine) AncestorType() string {
|
|
return m.AncestorNode().Type
|
|
}
|
|
|
|
func (m *Machine) UserData() *shared.UserData {
|
|
return m.NodeTree.UserData
|
|
}
|
|
|
|
func (m *Machine) GetVector(minRatio, maxRatio float64, isForceWin bool) (int64, []int64) {
|
|
return m.MachineDesc.GetVector(m.Choice(), minRatio, maxRatio, isForceWin)
|
|
}
|
|
|
|
func (m *Machine) GetDisplaySymbolsListString() string {
|
|
var dispaySymbolsList [][]int64
|
|
for _, formation := range m.CursorNode().Formations {
|
|
dispaySymbolsList = append(dispaySymbolsList, formation.DisplaySymbols)
|
|
}
|
|
dispaySymbolsListBytes, err := json.Marshal(dispaySymbolsList)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return string(dispaySymbolsListBytes)
|
|
}
|
|
|
|
func (m *Machine) GetFinalSymbolsListString() string {
|
|
var finalSymbolsList [][]int64
|
|
for _, formation := range m.CursorNode().Formations {
|
|
finalSymbolsList = append(finalSymbolsList, formation.FinalSymbols)
|
|
}
|
|
finalSymbolsListBytes, err := json.Marshal(finalSymbolsList)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return string(finalSymbolsListBytes)
|
|
}
|
|
|
|
func (m *Machine) GetFeaturesString() string {
|
|
var features []string
|
|
m.WalkTree(entity.WalkRootFirst, func(node *shared.Node) bool {
|
|
for _, feature := range node.Features {
|
|
if !feature.Visiable {
|
|
continue
|
|
}
|
|
|
|
if mathx.In(feature.Type, features) {
|
|
continue
|
|
}
|
|
|
|
features = append(features, feature.Type)
|
|
}
|
|
|
|
return false
|
|
})
|
|
|
|
featuresBytes, err := json.Marshal(features)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return string(featuresBytes)
|
|
}
|