tablesink.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. package gamelogic
  2. import (
  3. "encoding/json"
  4. "os"
  5. "sync"
  6. "time"
  7. "bet24.com/log"
  8. "bet24.com/servers/games/luckyfruit_table/common"
  9. "bet24.com/servers/games/luckyfruit_table/config"
  10. "bet24.com/servers/insecureframe/frame"
  11. )
  12. type tablesink struct {
  13. table frame.Table
  14. LastStateTick time.Time
  15. userBetList map[int][]common.Bet
  16. lock *sync.RWMutex
  17. spinResult common.Fruit
  18. userList *userlist
  19. betRank *betPool
  20. freeChips *freeChips
  21. score_users *common.ScoreUsers
  22. robotActions []robot_action
  23. robotStopEvent chan bool
  24. robotLock *sync.RWMutex
  25. scores []common.UserSetScore // 结算阶段,广播所有人的分数,给桌面玩家或者自己头像飘分用
  26. appleAmount int
  27. watermelonAmount int
  28. grapeAmount int
  29. bananaAmount int
  30. orangeAmount int
  31. drawAppleWinAmount int //记录苹果投注金额 用于避免重复开大奖
  32. privateData string
  33. roomInfo config.RoomInfo
  34. stat StatisticsList
  35. }
  36. func newTableSink(table frame.Table, data string) *tablesink {
  37. ts := new(tablesink)
  38. ts.table = table
  39. ts.privateData = data
  40. ts.lock = &sync.RWMutex{}
  41. err := json.Unmarshal([]byte(data), &ts.roomInfo)
  42. if err != nil {
  43. found := false
  44. for _, v := range config.Rooms.Rooms {
  45. if data == v.RoomName {
  46. ts.roomInfo = v
  47. found = true
  48. break
  49. }
  50. }
  51. if !found {
  52. ts.roomInfo = config.Rooms.Rooms[0]
  53. }
  54. }
  55. if ts.roomInfo.HistoryCount == 0 {
  56. ts.roomInfo.HistoryCount = 50
  57. }
  58. ts.userList = newUserList()
  59. ts.betRank = newBetPool(&ts.roomInfo)
  60. ts.freeChips = newFreeChips(&ts.roomInfo, ts.onFreeChipsChange)
  61. ts.score_users = new(common.ScoreUsers)
  62. ts.robotLock = &sync.RWMutex{}
  63. ts.startPeriod()
  64. ts.stat.initData(ts.table.GetTableID())
  65. if ts.test() {
  66. log.Debug("tablesink.setFrame test end")
  67. }
  68. table.SetTimer(common.TIMERID_CHECKROBOT, 5000)
  69. return ts
  70. }
  71. func (ts *tablesink) test() bool {
  72. if len(os.Args) < 2 {
  73. return false
  74. }
  75. common.ResetWinningOdds(ts.roomInfo.Odds)
  76. common.ResetFruitProbability(ts.roomInfo.Probability)
  77. bidTypeMax := int(common.BigOrange) //大水果无法下注
  78. testCount := 1000000
  79. total := float64(-testCount * int(common.BidTypeMax))
  80. returns := make([]int, bidTypeMax)
  81. for i := 0; i < testCount; i++ {
  82. spinResult := common.Spin()
  83. //winArea := common.GetWinArea(spinResult)
  84. //大水果无法下注
  85. for j := 0; j < bidTypeMax; j++ {
  86. odds := common.GetResultOdds(j, spinResult)
  87. if odds > 0 {
  88. returns[j]++
  89. total += odds
  90. }
  91. }
  92. }
  93. testResult := make([]float64, bidTypeMax)
  94. for j := 0; j < bidTypeMax; j++ {
  95. testResult[j] = float64(returns[j]) / float64(testCount) * common.GetResultOdds(j, -1)
  96. }
  97. log.Debug("testCount [%d] result %v total = %f", testCount, testResult, total)
  98. for j := 0; j < bidTypeMax; j++ {
  99. ts.testOne(j)
  100. }
  101. return true
  102. }
  103. func (ts *tablesink) testOne(betType int) {
  104. testCount := 10000
  105. returns := float64(0)
  106. for i := 0; i < testCount; i++ {
  107. spinResult := common.Spin()
  108. odds := common.GetResultOdds(betType, spinResult)
  109. if odds > 0 {
  110. returns += odds
  111. }
  112. }
  113. log.Debug("[%s] testCount [%d] returns %v rate = %f", common.GetBetDesc(betType), testCount, returns, float64(returns)/float64(testCount))
  114. }
  115. func (ts *tablesink) Destroy() {
  116. ts.table.LogWithTableId("------tablesink:Destroy-------")
  117. //close(ts.stopChan)
  118. }
  119. func (ts *tablesink) OnUserEnterTable(userIndex int32, chairId int) {
  120. u, _ := ts.table.GetUser(userIndex)
  121. if u == nil {
  122. log.Debug("tablesink.OnUserEnterTable %d not exist", userIndex)
  123. return
  124. }
  125. // 发送场景
  126. ts.sendGameScene(userIndex)
  127. ts.userList.addUser(u.GetUserId(), u.GetUserNickName(), u.GetUserFaceId(), u.GetUserFaceUrl(), u.GetUserVipLevel(), u.GetUserVipExpire(), u.GetDecorations())
  128. ts.betRank.addUser(u.GetUserId())
  129. if !u.IsRobot() {
  130. go ts.onCheckFreeChip(userIndex, u.GetUserId(), FreeChip, "")
  131. }
  132. }
  133. func (ts *tablesink) OnUserExitTable(userIndex int32, chairId int) {
  134. //判断一下用户是否有下注
  135. usr, _ := ts.table.GetUser(userIndex)
  136. if usr == nil {
  137. log.Debug("tablesink.OnUserExit %d not exist", userIndex)
  138. return
  139. }
  140. userId := usr.GetUserId()
  141. ts.lock.RLock()
  142. _, isBet := ts.userBetList[userId]
  143. ts.lock.RUnlock()
  144. if !isBet {
  145. ts.userList.removeUser(userId)
  146. if usr.IsRobot() {
  147. if !ts.betRank.isRank(userId) {
  148. ts.betRank.removeUser(userId)
  149. }
  150. }
  151. return
  152. }
  153. //如果机器人有下注,但没有上榜,则直接清除机器人
  154. if isBet && usr.IsRobot() && !ts.betRank.isRank(userId) {
  155. ts.betRank.removeUser(userId)
  156. }
  157. ts.userList.removeUser(userId)
  158. }
  159. func (ts *tablesink) OnUserOffline(chairId int) {
  160. }
  161. func (ts *tablesink) OnUserReplay(chairId int) {
  162. }
  163. func (ts *tablesink) OnUserReady(userIndex int32, chairId int) {
  164. }
  165. func (ts *tablesink) OnUserCancelReady(userIndex int32, chairId int) {
  166. }
  167. func (ts *tablesink) OnGetChairScene(chairId int, isPlayer bool) string {
  168. return ts.getStateData()
  169. }
  170. func (ts *tablesink) OnGetPrivateRoomScene(chairId int) string {
  171. return ts.getStateData()
  172. }
  173. func (ts *tablesink) OnGetChairCount() int {
  174. return 1
  175. }
  176. func (ts *tablesink) OnTimer(timerId int) {
  177. switch timerId {
  178. case common.TIMERID_CHECKROBOT:
  179. ts.checkRobot()
  180. ts.table.SetTimer(timerId, 5000)
  181. default:
  182. ts.table.LogWithTableId("tablesink.OnTimer unhandled timer[%d]", timerId)
  183. }
  184. }
  185. func (ts *tablesink) DumpScene() {
  186. }
  187. func (ts *tablesink) GetGoldLimit() (min, max int) {
  188. return ts.roomInfo.MinBet, ts.roomInfo.MaxBet
  189. }
  190. func (ts *tablesink) IsDual() bool {
  191. return false
  192. }
  193. func (ts *tablesink) OnBaseScoreChanged(baseScore int) {
  194. }
  195. func (ts *tablesink) SetPrivateRoomParam(param int, value string) {
  196. ts.table.LogWithTableId("tablesink.SetPrivateRoomParam %d:%s", param, value)
  197. }
  198. func (ts *tablesink) OnPrivateRoomStatusChanged(oldStatus, newStatus int) {
  199. ts.table.LogWithTableId("OnPrivateRoomStatusChanged %d->%d", oldStatus, newStatus)
  200. }
  201. func (ts *tablesink) OnPrivateRoomDismissed() {
  202. ts.table.LogWithTableId("OnPrivateRoomDismissed ")
  203. }
  204. func (ts *tablesink) IsAllRobot() bool {
  205. return false
  206. }