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) }