package slotpanda import ( "bet24.com/log" "bet24.com/servers/micros/slotsservice/handler/slotcommon/slotcount" "encoding/json" "math/rand" ) type FreeSlotChange struct { SlotId int Chance int } // 每组的15个slot信息 type FreeSlots struct { Slots []int // 实际Slot ChangedRows []int // 被变换的列 Lines []Result // 中奖连线 WinAmount int } type FreeSpinResult struct { BetAmount int Slots []FreeSlots TotalFreeCount int // 总free次数 LeftFreeCount int // 当前free次数 MaxScatter int // 最大数量 CurScatter int // 当前数量 ReFreeInner int // 当scatter满了后,产生新的轮盘 ReFreeOuter int } func (fr *FreeSpinResult) getWinAmount() int { ret := 0 for _, v := range fr.Slots { ret += v.WinAmount } return ret } func (fr *FreeSpinResult) getDesc() string { d, _ := json.Marshal(fr.Slots) return string(d) } type FreeSpinInfo struct { userId int freeSlotCount *slotcount.MultipleSlotCountManager slotmgr *slotmanager winShapes []WinShape wins []Win Changes []FreeSlotChange BetAmount int TotalCount int LeftCount int MaxScatter int // 最大数量 CurScatter int // 当前数量 scatterId int bonusId int wildId int level int isChipRoom bool } func newFreeSpinInfo(userId int, freeSlotCount *slotcount.MultipleSlotCountManager, winShapes []WinShape, wins []Win, slotmgr *slotmanager, changes []FreeSlotChange) *FreeSpinInfo { ret := new(FreeSpinInfo) ret.userId = userId ret.freeSlotCount = freeSlotCount ret.winShapes = winShapes ret.wins = wins ret.slotmgr = slotmgr ret.MaxScatter = 100 ret.scatterId = slotmgr.getScatterSlotId() ret.bonusId = slotmgr.getBonusSlotId() ret.wildId = slotmgr.getWildSlotId() ret.Changes = changes return ret } func (f *FreeSpinInfo) useFreeSpin() (bool, FreeSpinResult, bool) { var ret FreeSpinResult if f.LeftCount <= 0 { return false, ret, false } level := 0 sc := f.freeSlotCount.GetMgr(level) f.LeftCount-- ret.MaxScatter = f.MaxScatter ret.CurScatter = f.CurScatter ret.TotalFreeCount = f.TotalCount ret.LeftFreeCount = f.LeftCount ret.BetAmount = f.BetAmount // 产生4组 // 变化为同一个素材 changedSlotId := f.getChangeSlot() for i := 0; i < 4; i++ { var fs FreeSlots slots := sc.Get15Slots(f.level) // 随机一列发 faLineCount := 1 r := rand.Intn(100) if r < 50 { faLineCount = 1 } else if r < 85 { faLineCount = 2 } else { faLineCount = 3 } firstFaLine := -1 for i := 0; i < faLineCount; i++ { line := rand.Intn(5) for { if line == firstFaLine { line = rand.Intn(5) } else { break } } /* if changedSlotId == -1 { changedSlotId = slots[line] } // 如果素材为scatter,bonus,wild,则不能变成一列,需要重新找一个新的元素 if changedSlotId == f.scatterId || changedSlotId == f.bonusId || changedSlotId == f.wildId { changedSlotId = -1 continue } */ firstFaLine = line slots[line] = changedSlotId slots[line+5] = slots[line] slots[line+10] = slots[line] fs.ChangedRows = append(fs.ChangedRows, line) } fs.Slots = slots // 添加scatter for _, v := range slots { if v == f.scatterId { inner, outer := f.addScatter() if inner > 0 { ret.ReFreeInner = inner ret.ReFreeOuter = outer } } } // 计算结果 shapeCount := len(f.winShapes) for k, v := range f.winShapes { // 查看每条连线的数量 s := make([]Slot, RESULT_COUNT) for i := 0; i < 15; i++ { s[i] = f.slotmgr.getSlot(slots[i]) } slotID, slotCount, _ := v.getCount(s) // 查看结果 result := f.getOneResult(slotID, slotCount, k) if result != nil { // 中奖了 fs.WinAmount += f.BetAmount * result.WinRate / shapeCount fs.Lines = append(fs.Lines, *result) } } ret.Slots = append(ret.Slots, fs) } return true, ret, f.isChipRoom } func (f *FreeSpinInfo) getFreeCount() int { return f.LeftCount } func (f *FreeSpinInfo) addScatter() (int, int) { f.CurScatter++ if f.CurScatter >= f.MaxScatter { f.CurScatter = 0 inner, outer := f.getMultiple() f.TotalCount += inner * outer f.LeftCount += inner * outer log.Release("slotpanda.FreeSpinInfo.addScatter %d", f.TotalCount) return inner, outer } return 0, 0 } // 获得免费奖励 func (f *FreeSpinInfo) initFree(betAmount int, slots []int, isChipRoom bool) (int, int) { scatterCount := 0 for _, v := range slots { if v == f.scatterId { scatterCount++ } } if scatterCount < 3 { return 0, 0 } f.BetAmount = betAmount inner, outer := f.getMultiple() f.TotalCount = inner * outer f.LeftCount = f.TotalCount f.CurScatter = 0 f.isChipRoom = isChipRoom log.Release("slotpanda.FreeSpinInfo.initFree %d", f.TotalCount) return inner, outer } func (f *FreeSpinInfo) removeFreeTimes(times int) { f.TotalCount -= times f.LeftCount -= times if f.TotalCount < 0 { f.TotalCount = 0 } if f.LeftCount < 0 { f.LeftCount = 0 } } func (f *FreeSpinInfo) getMultiple() (inner, outer int) { inner = rand.Intn(3) + 1 r := rand.Intn(100) if r < 35 { outer = 4 return } r -= 35 if r < 35 { outer = 8 return } r -= 35 if r < 20 { outer = 12 return } outer = 16 return } func (f *FreeSpinInfo) getOneResult(slotID, slotCount, shapeID int) *Result { for _, v := range f.wins { if v.SlotID != slotID { continue } for _, rate := range v.Rates { if rate.Count == slotCount { return &Result{SlotID: slotID, SlotCount: slotCount, WinShapeID: shapeID, WinRate: rate.Win} } } } return nil } func (f *FreeSpinInfo) getChangeSlot() int { if len(f.Changes) == 0 { return 3 } total := 0 for _, v := range f.Changes { total += v.Chance } r := rand.Intn(total) for _, v := range f.Changes { if r < v.Chance { return v.SlotId } r -= v.Chance } log.Release("FreeSpinInfo.getChangeSlot should not come here") return 3 }