package gamelogic import ( "encoding/json" "os" "sync" "time" "bet24.com/log" "bet24.com/servers/games/luckyfruit_table/common" "bet24.com/servers/games/luckyfruit_table/config" "bet24.com/servers/insecureframe/frame" ) type tablesink struct { table frame.Table LastStateTick time.Time userBetList map[int][]common.Bet lock *sync.RWMutex spinResult common.Fruit userList *userlist betRank *betPool freeChips *freeChips score_users *common.ScoreUsers robotActions []robot_action robotStopEvent chan bool robotLock *sync.RWMutex scores []common.UserSetScore // 结算阶段,广播所有人的分数,给桌面玩家或者自己头像飘分用 appleAmount int watermelonAmount int grapeAmount int bananaAmount int orangeAmount int drawAppleWinAmount int //记录苹果投注金额 用于避免重复开大奖 privateData string roomInfo config.RoomInfo stat StatisticsList } func newTableSink(table frame.Table, data string) *tablesink { ts := new(tablesink) ts.table = table ts.privateData = data ts.lock = &sync.RWMutex{} err := json.Unmarshal([]byte(data), &ts.roomInfo) if err != nil { found := false for _, v := range config.Rooms.Rooms { if data == v.RoomName { ts.roomInfo = v found = true break } } if !found { ts.roomInfo = config.Rooms.Rooms[0] } } if ts.roomInfo.HistoryCount == 0 { ts.roomInfo.HistoryCount = 50 } ts.userList = newUserList() ts.betRank = newBetPool(&ts.roomInfo) ts.freeChips = newFreeChips(&ts.roomInfo, ts.onFreeChipsChange) ts.score_users = new(common.ScoreUsers) ts.robotLock = &sync.RWMutex{} ts.startPeriod() ts.stat.initData(ts.table.GetTableID()) if ts.test() { log.Debug("tablesink.setFrame test end") } table.SetTimer(common.TIMERID_CHECKROBOT, 5000) return ts } func (ts *tablesink) test() bool { if len(os.Args) < 2 { return false } common.ResetWinningOdds(ts.roomInfo.Odds) common.ResetFruitProbability(ts.roomInfo.Probability) bidTypeMax := int(common.BigOrange) //大水果无法下注 testCount := 1000000 total := float64(-testCount * int(common.BidTypeMax)) returns := make([]int, bidTypeMax) for i := 0; i < testCount; i++ { spinResult := common.Spin() //winArea := common.GetWinArea(spinResult) //大水果无法下注 for j := 0; j < bidTypeMax; j++ { odds := common.GetResultOdds(j, spinResult) if odds > 0 { returns[j]++ total += odds } } } testResult := make([]float64, bidTypeMax) for j := 0; j < bidTypeMax; j++ { testResult[j] = float64(returns[j]) / float64(testCount) * common.GetResultOdds(j, -1) } log.Debug("testCount [%d] result %v total = %f", testCount, testResult, total) for j := 0; j < bidTypeMax; j++ { ts.testOne(j) } return true } func (ts *tablesink) testOne(betType int) { testCount := 10000 returns := float64(0) for i := 0; i < testCount; i++ { spinResult := common.Spin() odds := common.GetResultOdds(betType, spinResult) if odds > 0 { returns += odds } } log.Debug("[%s] testCount [%d] returns %v rate = %f", common.GetBetDesc(betType), testCount, returns, float64(returns)/float64(testCount)) } func (ts *tablesink) Destroy() { ts.table.LogWithTableId("------tablesink:Destroy-------") //close(ts.stopChan) } func (ts *tablesink) OnUserEnterTable(userIndex int32, chairId int) { u, _ := ts.table.GetUser(userIndex) if u == nil { log.Debug("tablesink.OnUserEnterTable %d not exist", userIndex) return } // 发送场景 ts.sendGameScene(userIndex) ts.userList.addUser(u.GetUserId(), u.GetUserNickName(), u.GetUserFaceId(), u.GetUserFaceUrl(), u.GetUserVipLevel(), u.GetUserVipExpire(), u.GetDecorations()) ts.betRank.addUser(u.GetUserId()) if !u.IsRobot() { go ts.onCheckFreeChip(userIndex, u.GetUserId(), FreeChip, "") } } func (ts *tablesink) OnUserExitTable(userIndex int32, chairId int) { //判断一下用户是否有下注 usr, _ := ts.table.GetUser(userIndex) if usr == nil { log.Debug("tablesink.OnUserExit %d not exist", userIndex) return } userId := usr.GetUserId() ts.lock.RLock() _, isBet := ts.userBetList[userId] ts.lock.RUnlock() if !isBet { ts.userList.removeUser(userId) if usr.IsRobot() { if !ts.betRank.isRank(userId) { ts.betRank.removeUser(userId) } } return } //如果机器人有下注,但没有上榜,则直接清除机器人 if isBet && usr.IsRobot() && !ts.betRank.isRank(userId) { ts.betRank.removeUser(userId) } ts.userList.removeUser(userId) } func (ts *tablesink) OnUserOffline(chairId int) { } func (ts *tablesink) OnUserReplay(chairId int) { } func (ts *tablesink) OnUserReady(userIndex int32, chairId int) { } func (ts *tablesink) OnUserCancelReady(userIndex int32, chairId int) { } func (ts *tablesink) OnGetChairScene(chairId int, isPlayer bool) string { return ts.getStateData() } func (ts *tablesink) OnGetPrivateRoomScene(chairId int) string { return ts.getStateData() } func (ts *tablesink) OnGetChairCount() int { return 1 } func (ts *tablesink) OnTimer(timerId int) { switch timerId { case common.TIMERID_CHECKROBOT: ts.checkRobot() ts.table.SetTimer(timerId, 5000) default: ts.table.LogWithTableId("tablesink.OnTimer unhandled timer[%d]", timerId) } } func (ts *tablesink) DumpScene() { } func (ts *tablesink) GetGoldLimit() (min, max int) { return ts.roomInfo.MinBet, ts.roomInfo.MaxBet } func (ts *tablesink) IsDual() bool { return false } func (ts *tablesink) OnBaseScoreChanged(baseScore int) { } func (ts *tablesink) SetPrivateRoomParam(param int, value string) { ts.table.LogWithTableId("tablesink.SetPrivateRoomParam %d:%s", param, value) } func (ts *tablesink) OnPrivateRoomStatusChanged(oldStatus, newStatus int) { ts.table.LogWithTableId("OnPrivateRoomStatusChanged %d->%d", oldStatus, newStatus) } func (ts *tablesink) OnPrivateRoomDismissed() { ts.table.LogWithTableId("OnPrivateRoomDismissed ") } func (ts *tablesink) IsAllRobot() bool { return false }