package entity import ( "github.com/tomas-qstarrs/boost/randx" "github.com/tomas-qstarrs/boost/timex" "mongo.games.com/game/gamesrv/slotspkg/internal/generic/errors" "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/desc" "mongo.games.com/game/gamesrv/slotspkg/slots/formation" ) const ( initSymbolsMethodNone int64 = iota initSymbolsMethodConst initSymbolsMethodRandom initSymbolsMethodCopy initSymbolsMethodImage ) // GetFormation gets specific formation by node id & seq id // panic if no formation func (e *Entity) GetFormation(nodeID int64, seqID int64) *shared.Formation { node := e.GetNode(nodeID) if seqID > int64(len(node.Formations)) { panic(errors.FormationNotFound.ErrorWith(seqID)) } return node.Formations[seqID-1] } // GetFormations gets all formations by node id func (e *Entity) GetFormations(nodeID int64) []*shared.Formation { node := e.GetNode(nodeID) return node.Formations } // ConvertFormations sets formations into node formations func (e *Entity) ConvertFormations() { for idx, originFormation := range e.OriginFormations { linkPositions := make([]*shared.LinkPositions, 0, len(originFormation.LinkPositions)) for _, positions := range originFormation.LinkPositions { linkPositions = append(linkPositions, &shared.LinkPositions{ Positions: positions, }) } finalSymbols := make([]int64, len(originFormation.Symbols)) copy(finalSymbols, originFormation.Symbols) cliFormation := e.CursorNode().Formations[idx] cliFormation.SeqID = originFormation.SeqID cliFormation.DisplaySymbols = originFormation.DisplaySymbols cliFormation.FinalSymbols = finalSymbols cliFormation.LinkPositions = linkPositions cliFormation.Win = int64(originFormation.Pay * float64(e.CursorNode().SingleBet)) cliFormation.ReelForm = originFormation.ReelForm cliFormation.MatrixForm = originFormation.MatrixForm cliFormation.RandPositions = originFormation.RandPositions cliFormation.RewardInfo = originFormation.RewardInfo for _, info := range cliFormation.RewardInfo { info.Reward *= float64(e.CursorNode().SingleBet) } } } // PrepareOriginFormations prepares origin Formations for current node func (e *Entity) PrepareOriginFormations() { e.OriginFormations = make([]*formation.Formation, 0) for _, desc := range e.NodeDesc.FormationSeqsDesc { formation, err := formation.NewFormation(e.NodeDesc, desc.SeqID) if err != nil { panic(err) } e.OriginFormations = append(e.OriginFormations, formation) } } // PrepareOriginFormations prepares origin Formations for next node func (e *Entity) PrepareNextOriginFormations() { e.OriginFormations = make([]*formation.Formation, 0) for _, desc := range e.NextNodeDesc.FormationSeqsDesc { formation, err := formation.NewFormation(e.NextNodeDesc, desc.SeqID) if err != nil { panic(err) } e.OriginFormations = append(e.OriginFormations, formation) } } // Rand rands for all origin formations func (e *Entity) Rand() { for _, formation := range e.OriginFormations { if formation.Empty() { continue } formation.Rand(e.RandState.randx) } } // Display sets formation for display func (e *Entity) Display() { for _, formation := range e.OriginFormations { if formation.Empty() { continue } formation.Display() } } // Link links for all origin formations func (e *Entity) Link() { for _, formation := range e.OriginFormations { if formation.Empty() { continue } formation.Link() } } // UpdateImageFormations saves image info from formations to image formations func (e *Entity) UpdateImageFormations() { for _, formation := range e.CursorNode().Formations { for idx, imageFormation := range e.NodeTree.ImageFormations { if imageFormation.ID == formation.ID { e.NodeTree.ImageFormations[idx] = formation return } } e.NodeTree.ImageFormations = append(e.NodeTree.ImageFormations, formation) } } // InitNextFormations inits init symbols for next node func (e *Entity) InitNextFormations() { for _, nextFormation := range e.NextNode().Formations { e.genInitSymbols(nextFormation) } } func (e *Entity) genInitSymbols(nextFormation *shared.Formation) { var initSymbols []int64 defer func() { nextFormation.InitSymbols = make([]int64, len(initSymbols)) copy(nextFormation.InitSymbols, initSymbols) }() desc := e.getNextFormationDesc(nextFormation) if desc == nil { // No formation in next node return } // Try to copy symbols from cursor node for _, cursorFormation := range e.CursorNode().Formations { if nextFormation.ID == cursorFormation.ID { initSymbols = cursorFormation.FinalSymbols return } } // Next node is progressed, just read history if e.NextNode().ProgressValue > 0 { initSymbols = e.getImageSymbols(e.NextNode(), desc) return } method := e.getNexFormationMethod(e.NextNode(), desc) // Switch method to get all kinds of init symbols source switch method { case initSymbolsMethodNone: // do nothing case initSymbolsMethodConst: initSymbols = e.getConstSymbols(e.NextNode(), desc) case initSymbolsMethodRandom: initSymbols = e.getRandomSymbols(e.NextNode(), desc) case initSymbolsMethodCopy: initSymbols = e.getCopySymbols(e.NextNode(), desc) case initSymbolsMethodImage: initSymbols = e.getImageSymbols(e.NextNode(), desc) default: panic(errors.With(method).Errorf("unsupported init symbols method")) } } func (e *Entity) getNextFormationDesc(formation *shared.Formation) *desc.FormationSeqDesc { for _, desc := range e.NextNodeDesc.FormationSeqsDesc { if desc.NodeType == formation.NodeType && desc.SeqID == formation.SeqID { return desc } } return nil } func (e *Entity) getNexFormationMethod(node *shared.Node, desc *desc.FormationSeqDesc) int64 { formation := node.Formations[desc.SeqID-1] for _, imageFormation := range e.NodeTree.ImageFormations { if imageFormation.ID == formation.ID { return desc.OtherInitMethod } } return desc.FirstInitMethod } func (e *Entity) getConstSymbols(node *shared.Node, desc *desc.FormationSeqDesc) []int64 { formation := node.Formations[desc.SeqID-1] for _, imageFormation := range e.NodeTree.ImageFormations { if imageFormation.ID == formation.ID { return desc.OtherInitSymbols } } return desc.FirstInitSymbols } func (e *Entity) getRandomSymbols(_ *shared.Node, desc *desc.FormationSeqDesc) []int64 { originFormation, err := formation.NewFormation(e.NextNodeDesc, desc.SeqID) if err != nil { panic(err) } originFormation.Rand(randx.New(timex.Now().UnixNano())) return originFormation.Symbols } func (e *Entity) getCopySymbols(node *shared.Node, desc *desc.FormationSeqDesc) []int64 { for { node = e.GetNode(node.Parent) if node.ID == e.NodeTree.Root { return nil } if desc.SeqID > int64(len(node.Formations)) { continue } return node.Formations[desc.SeqID-1].FinalSymbols } } func (e *Entity) getImageSymbols(node *shared.Node, desc *desc.FormationSeqDesc) []int64 { formation := node.Formations[desc.SeqID-1] for _, imageFormation := range e.NodeTree.ImageFormations { if imageFormation.ID == formation.ID { return imageFormation.FinalSymbols } } return nil } func (e *Entity) getLineCount() int64 { lineCount := int64(0) for _, originFormation := range e.OriginFormations { lineCount += originFormation.FormationDesc.MatrixDesc.LineCount } return lineCount } func (e *Entity) GetLineCountByType(nodeType string) int64 { nodeDesc := e.NewNodeDescWithNodeType(nodeType) e.SelectFormationSeqsDesc(nodeDesc) formationSeqsDesc := nodeDesc.GetFormationSeqDescs(key.BaseSpin) var lineCount int64 = 0 for _, desc := range formationSeqsDesc { formation, err := formation.NewFormation(nodeDesc, desc.SeqID) if err != nil { panic(err) } lineCount += formation.FormationDesc.MatrixDesc.LineCount } return lineCount } // IsWinInBeforeDisplay must in BeforeDisplay func (e *Entity) IsWinInBeforeDisplay() bool { if e.OriginFormations != nil { //newOriginFormations := deepcopy.Copy(e.OriginFormations).([]*formation.Formation) //newOriginFormations := e.OriginFormations for i := 1; i <= 100; i++ { for _, formation := range e.OriginFormations { if formation.Empty() { continue } formation.Display() formation.LinkOnWin() //logx.Error("formation.Symbols----------- ", formation.Symbols) if formation.Pay > 0 { //logx.Error("formation.Symbols---22-------- ", formation.Symbols) //e.OriginFormations[k].Symbols = make([]int64, len(formation.Symbols)) //copy(e.OriginFormations[k].Symbols, formation.Symbols) //if e.OriginFormations[k].Symbols[0] == 0 { // fmt.Println() //} return true } formation.ResetRandSymbolsByIndex(e.Randx()) } } } return true } // IsWinInBeforeDisplayBySymbols must in BeforeDisplay func (e *Entity) IsWinInBeforeDisplayBySymbols(symbols [][]int64) int { if e.OriginFormations != nil { for _, f := range e.OriginFormations { if f.Empty() { continue } symbolsCopy := make([]int64, len(f.Symbols)) copy(symbolsCopy, f.Symbols) f.Symbols = formation.DeformatSymbols(symbols) //f.Display() f.LinkOnWin() f.Symbols = symbolsCopy if f.Pay > 0 { return 1 } } //newOriginFormations := deepcopy.Copy(e.OriginFormations).([]*formation.Formation) //for _, newOriginFormation := range newOriginFormations { // if newOriginFormation.Empty() { // continue // } // newOriginFormation.Symbols = formation.DeformatSymbols(symbols) // // newOriginFormation.DisplaySymbols = make([]int64, len(newOriginFormation.Symbols)) // copy(newOriginFormation.DisplaySymbols, newOriginFormation.Symbols) // // newOriginFormation.Link() // if newOriginFormation.Pay > 0 { // return len(newOriginFormation.RewardInfo) // } //} } return 0 }