package slotcount import ( "encoding/json" "fmt" "math/rand" "os" "bet24.com/log" ) type SlotCount struct { SlotID int Count int } type SlotColumn struct { SlotCounts []SlotCount pool []int } func (scm *SlotColumn) makePool() { scm.pool = []int{} for _, v := range scm.SlotCounts { for i := 0; i < v.Count; i++ { scm.pool = append(scm.pool, v.SlotID) } } } func (scm *SlotColumn) getSlot() int { return scm.pool[rand.Intn(len(scm.pool))] } type SlotLevel struct { Columns []SlotColumn } type SlotCountManager struct { levels []SlotLevel Level int // fafafa特殊 goldFaId int freeSlotId int } func NewSlotCountManager(confFile string) *SlotCountManager { ret := new(SlotCountManager) ret.loadData(confFile) return ret } func NewSlotCountManagerByConfig(level int, counts [][][]int) *SlotCountManager { ret := new(SlotCountManager) ret.Level = level ret.loadDataByConfig(counts) return ret } func (scm *SlotCountManager) loadDataByConfig(counts [][][]int) { for _, level := range counts { // level var sl SlotLevel for _, column := range level { var scm SlotColumn for i := 0; i < len(column); i++ { if column[i] == 0 { continue } scm.SlotCounts = append(scm.SlotCounts, SlotCount{SlotID: i, Count: column[i]}) } scm.makePool() sl.Columns = append(sl.Columns, scm) } scm.levels = append(scm.levels, sl) } } func (scm *SlotCountManager) loadData(confFile string) { var counts [][][]int data, err := os.ReadFile(fmt.Sprintf("slotconf/%s.json", confFile)) if err != nil { log.Error("SlotCountManager.loadData read %s.json failed", confFile) return } err = json.Unmarshal(data, &counts) if err != nil { log.Error("SlotCountManager.loadData Unmarshal %s.json failed err:%v", confFile, err) return } scm.loadDataByConfig(counts) } const ( ROW_COUNT = 3 COLUMN_COUNT = 5 ) func (scm *SlotCountManager) Get15Slots(betLevel int) []int { if len(scm.levels) == 0 { return []int{} } ret := make([]int, ROW_COUNT*COLUMN_COUNT) // dfdc根据下注额确定配置项,其他slot没有 if betLevel >= len(scm.levels) { betLevel = len(scm.levels) - 1 } level := scm.levels[betLevel] for r := 0; r < ROW_COUNT; r++ { for c := 0; c < COLUMN_COUNT; c++ { // dfdc只有5列的配置,其他slot是15列配置 idx := (r*COLUMN_COUNT + c) % len(level.Columns) ret[r*COLUMN_COUNT+c] = level.Columns[idx].getSlot() } } return ret } func (scm *SlotCountManager) GetOneSlot(betLevel int, idx int) int { if len(scm.levels) == 0 { return -1 } if betLevel >= len(scm.levels) { betLevel = len(scm.levels) - 1 } level := scm.levels[betLevel] idx = idx % len(level.Columns) return level.Columns[idx].getSlot() } func (scm *SlotCountManager) setFafafaInfo(goldFaId int, freeSlotId int) { scm.goldFaId = goldFaId scm.freeSlotId = freeSlotId } func (scm *SlotCountManager) GetFafafaSlots(isFree bool) []int { ret := make([]int, 15) goldFaCount := 0 for i := 0; i < 15; i++ { for { ret[i] = scm.GetOneSlot(0, i) if !isFree || (ret[i] != scm.freeSlotId && ret[i] != scm.goldFaId) { break } } if ret[i] == scm.goldFaId { goldFaCount++ } } // 如果有两个以上 if goldFaCount >= 2 { for i := 0; i < 5; i++ { if ret[i] == scm.goldFaId { // 每列都改成发 ret[i+5] = scm.goldFaId ret[i+10] = scm.goldFaId } } } else if isFree { // 随机一列发 faLineCount := 1 if rand.Intn(100) >= 99 { faLineCount = 4 } else if rand.Intn(100) >= 92 { faLineCount = 3 } else if rand.Intn(100) >= 72 { faLineCount = 2 } changeLines := make([]int, faLineCount) lines5 := []int{0, 1, 2, 3, 4} for i := 4; i > 1; i-- { place := rand.Intn(i) tmp := lines5[place] lines5[place] = lines5[i] lines5[i] = tmp } for i := 0; i < faLineCount; i++ { changeLines[i] = lines5[i] } for _, line := range changeLines { ret[line] = scm.goldFaId ret[line+5] = scm.goldFaId ret[line+10] = scm.goldFaId } } return ret } func (scm *SlotCountManager) Get16Slots(betLevel int, isFree bool, freeSlotId int) []int { const RESULT_COUNT = 16 ret := make([]int, RESULT_COUNT) isHaveFree := make([]bool, COLUMN_COUNT) if betLevel >= len(scm.levels) { betLevel = len(scm.levels) - 1 } level := scm.levels[betLevel] for r := 0; r < ROW_COUNT; r++ { for c := 0; c < COLUMN_COUNT; c++ { row := (r*COLUMN_COUNT + c) % 5 id := scm.getSlotIdByLevel(&level.Columns[c], isFree, isHaveFree[row], freeSlotId) if !isHaveFree[row] && id == freeSlotId { isHaveFree[row] = true } ret[r*COLUMN_COUNT+c] = id } } //特殊区域 ret[RESULT_COUNT-1] = scm.getSlotIdByLevel(&level.Columns[5], isFree, isHaveFree[2], freeSlotId) return ret } /* 获取扇子ID */ func (scm *SlotCountManager) GetFanID(magicSlotId, topSlotId, betLevel int, isFree bool) int { //判断顶格是否为扇子 因为只有扇子为通用素材所以判断是否为Magic即可 if magicSlotId != topSlotId && !isFree { return -1 } if betLevel >= len(scm.levels) { betLevel = len(scm.levels) - 1 } level := scm.levels[betLevel] ret := level.Columns[6].getSlot() return ret } /* 根据等级配置获取单个素材ID */ func (scm *SlotCountManager) getSlotIdByLevel(sc *SlotColumn, isFree, isHaveFreeRow bool, freeSlotId int) int { slotId := -1 for { slotId = sc.getSlot() //每列最多出现一个免费素材 if !isFree && isHaveFreeRow && slotId == freeSlotId { continue } else { break } } return slotId }