playerinfo.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. package gamelogic
  2. import (
  3. "fmt"
  4. "bet24.com/log"
  5. ladder "bet24.com/servers/micros/ladderservice/proto"
  6. )
  7. type PlayerInfo struct {
  8. IsValid bool // 是否有效玩家
  9. HandCards []int // 手牌
  10. EndScore int // 游戏结算所得
  11. TotalScore int // 游戏总得分
  12. AutoOut bool // 托管标志
  13. LastAction int // 上一个动作
  14. LastActionData int // 上个动作数据
  15. CurrentCard int // 当前轮次的出牌
  16. WinCardScore int // 每一小局赢牌得分
  17. WinCardChangeScore int // 每一小局每轮赢牌获得分数,用于赢牌飘分
  18. TotalChangeScore int // 每一小局获得的分数
  19. FinalCalcScore int // 每一小局最后计算得分
  20. Projects []SingleProject // 项目数据
  21. CallProject int // 玩家需要发声的最高项目名
  22. CanAction []int // 玩家叫牌的动作
  23. CanGawah bool // 玩家能否全部打出
  24. HaveBaloot bool // 是否有baloot项目
  25. IsCallBiggest bool // 在hokum模式下,非第一轮,玩家如果第一个出牌,此牌在该花色下是否为最大且非主牌不为A,主牌不为J
  26. WinCardNumber int // 赢牌数量
  27. LeftSendCards []int // 剩余三张发牌数据
  28. CanDoReshuffle bool // 是否有重新洗牌操作
  29. ReshuffleAction int // 洗牌动作
  30. IsReshuffleTime bool // 是否刷新倒计时
  31. BigCards []int // 在Hokum模式下,玩家必须压的大牌,如果为空则走原来的逻辑
  32. Doublings []DoublingDetail // 翻倍详情
  33. MatchScore int // 比赛分
  34. LevelValue int // 经验值
  35. IsSurrender bool // 是否投降
  36. ProjectTips []int // 项目提示
  37. LadderInfo ladder.UserLadderInfo // 玩家段位信息
  38. LadderChangeValue int // 段位变化值
  39. LastWinCount int // 结算前连胜次数,用于连胜中断时,展示玩家中断时的连胜次数
  40. userID int // 玩家ID
  41. bet int // 进房押注金额
  42. isRobot bool // 是否机器人
  43. enterGold int // 玩家携带金币
  44. consecutiveWinCardCount int // 连续赢牌次数
  45. isEndToStart bool // 金币场继续游戏情况为true,用于记录是否发送匹配界面的
  46. bakHandCards []int // 备用手牌数据,用于导入数据到Excel表中,后期不用可以删除
  47. winCardScore int // 玩家吃牌分数,用于统计玩家每小局吃牌分并导入数据到Excel表中,后期不用可以删除
  48. isControl bool // 是否走个个人奖池控牌
  49. controlType int // 控制类型
  50. roundScores []int // 玩家每小局得分
  51. controlDoubling int // 加倍场触发倍数,非加倍场为-1
  52. averageDoubling int // 平均执行倍数
  53. bakProjects []SingleProject
  54. robotType int
  55. robotActionType int
  56. robotActionProb int
  57. selfConsecutiveWinCardCount int
  58. outTimeCount int
  59. }
  60. func (p *PlayerInfo) initData(userId, enterGold, initScore int) {
  61. p.gameInit()
  62. p.IsValid = false
  63. p.TotalScore = initScore
  64. p.enterGold = enterGold
  65. p.userID = userId
  66. p.EndScore = 0
  67. p.Doublings = []DoublingDetail{}
  68. p.isControl = false
  69. p.controlType = 0
  70. p.roundScores = []int{}
  71. p.controlDoubling = -1
  72. p.averageDoubling = 0
  73. p.IsSurrender = false
  74. p.LadderChangeValue = 0
  75. }
  76. func (p *PlayerInfo) gameInit() {
  77. p.HandCards = []int{}
  78. p.AutoOut = false
  79. p.LastAction = Action_Invalid
  80. p.LastActionData = -1
  81. p.CurrentCard = CARD_COUNT
  82. p.WinCardScore = 0
  83. p.WinCardChangeScore = 0
  84. p.CanAction = []int{}
  85. p.Projects = []SingleProject{}
  86. p.bakProjects = []SingleProject{}
  87. p.CallProject = PROJECT_INVALID
  88. p.CanGawah = false
  89. p.HaveBaloot = false
  90. p.IsCallBiggest = false
  91. p.TotalChangeScore = 0
  92. p.FinalCalcScore = 0
  93. p.WinCardNumber = 0
  94. p.LeftSendCards = []int{}
  95. p.CanDoReshuffle = false
  96. p.ReshuffleAction = Reshuffle_None
  97. p.IsReshuffleTime = false
  98. p.BigCards = []int{}
  99. p.consecutiveWinCardCount = 0
  100. p.selfConsecutiveWinCardCount = 0
  101. p.bakHandCards = []int{}
  102. p.winCardScore = 0
  103. p.LevelValue = 0
  104. p.ProjectTips = []int{0, 0, 0, 0}
  105. p.robotActionType = RobotType_Cautious
  106. p.robotActionProb = 100
  107. p.outTimeCount = 0
  108. }
  109. func (p *PlayerInfo) canReshuffle() bool {
  110. return p.CanDoReshuffle && p.ReshuffleAction == Reshuffle_None
  111. }
  112. func (p *PlayerInfo) intLastAction() {
  113. p.LastAction = Action_Invalid
  114. p.LastActionData = -1
  115. }
  116. func (p *PlayerInfo) addDoublingData(gameIndex, times int) {
  117. p.Doublings = append(p.Doublings, DoublingDetail{
  118. RoundIndex: gameIndex,
  119. DoublingTotalTimes: times,
  120. })
  121. }
  122. func (p *PlayerInfo) initBigCards(bigCards []int) {
  123. p.BigCards = []int{}
  124. if len(bigCards) > 0 {
  125. p.BigCards = append(p.BigCards, bigCards...)
  126. }
  127. }
  128. func (p *PlayerInfo) getPlayerCurrentTotalDoublings() int {
  129. baseTimes := 0
  130. for n := 0; n < len(p.Doublings); n++ {
  131. baseTimes += p.Doublings[n].DoublingTotalTimes
  132. }
  133. return baseTimes
  134. }
  135. func (p *PlayerInfo) checkBaloot(trumpType int) {
  136. haveTrumpQ := false
  137. haveTrumpK := false
  138. for i := 0; i < len(p.HandCards); i++ {
  139. if p.HandCards[i] == trumpType*8+CardValueQ {
  140. haveTrumpQ = true
  141. }
  142. if p.HandCards[i] == trumpType*8+CardValueK {
  143. haveTrumpK = true
  144. }
  145. }
  146. if haveTrumpQ && haveTrumpK {
  147. p.HaveBaloot = true
  148. }
  149. }
  150. func (p *PlayerInfo) isAllZeroScoreCard() bool {
  151. for i := 0; i < len(p.HandCards); i++ {
  152. if value_regular[getCardValue(p.HandCards[i])] > 0 {
  153. return false
  154. }
  155. }
  156. p.CanDoReshuffle = true
  157. return true
  158. }
  159. func (p *PlayerInfo) needReshuffle() bool {
  160. for i := 0; i < len(p.HandCards); i++ {
  161. if value_regular[getCardValue(p.HandCards[i])] > 0 {
  162. return false
  163. }
  164. }
  165. return true
  166. }
  167. func (p *PlayerInfo) isIncludeBaloot() bool {
  168. if !p.HaveBaloot {
  169. return false
  170. }
  171. if len(p.Projects) == 0 {
  172. return false
  173. }
  174. for i := 0; i < len(p.Projects); i++ {
  175. if p.Projects[i].Type == PROJECT_BALOOT {
  176. return true
  177. }
  178. }
  179. return false
  180. }
  181. func (p *PlayerInfo) outAllBalootCard(trumpType int) bool {
  182. if !p.HaveBaloot || trumpType == CardType_Invalid {
  183. return false
  184. }
  185. haveTrumpQ := haveCard(p.HandCards, trumpType*8+CardValueQ)
  186. haveTrumpK := haveCard(p.HandCards, trumpType*8+CardValueK)
  187. return !haveTrumpQ && !haveTrumpK
  188. }
  189. func (p *PlayerInfo) ininTime() {
  190. p.IsReshuffleTime = false
  191. }
  192. func (p *PlayerInfo) setPlayerOperators(buyList []int) {
  193. if len(buyList) > 0 {
  194. p.IsReshuffleTime = true
  195. }
  196. p.CanAction = []int{}
  197. p.CanAction = buyList
  198. }
  199. func (p *PlayerInfo) isBuyPass() bool {
  200. if len(p.CanAction) == 0 {
  201. return true
  202. }
  203. return p.LastActionData == Action_Buy_Pass
  204. }
  205. func (p *PlayerInfo) canAction() bool {
  206. return len(p.CanAction) > 0
  207. }
  208. func (p *PlayerInfo) getAutoBuyAction() int {
  209. if len(p.CanAction) > 0 {
  210. return p.CanAction[0]
  211. }
  212. return Action_Buy_Invaild
  213. }
  214. func (p *PlayerInfo) canDoBuyAction(buyAction int) bool {
  215. if buyAction < 0 || buyAction >= Action_Buy_Invaild {
  216. return false
  217. }
  218. for i := 0; i < len(p.CanAction); i++ {
  219. if p.CanAction[i] == buyAction {
  220. return true
  221. }
  222. }
  223. return false
  224. }
  225. func (p *PlayerInfo) hideSecretData() {
  226. if len(p.HandCards) == 0 {
  227. return
  228. }
  229. for i := 0; i < len(p.HandCards); i++ {
  230. p.HandCards[i] = CARD_COUNT
  231. }
  232. if len(p.LeftSendCards) == 0 {
  233. return
  234. }
  235. for i := 0; i < len(p.LeftSendCards); i++ {
  236. p.LeftSendCards[i] = CARD_COUNT
  237. }
  238. }
  239. func (p *PlayerInfo) analysisProject(projects []int, suit int) {
  240. cardList := make([]int, len(p.HandCards))
  241. copy(cardList, p.HandCards)
  242. cardList = append(cardList, p.CurrentCard)
  243. projectList := []SingleProject{}
  244. bestType := -1
  245. for i := PROJECT_FOURHUNDRED; i >= PROJECT_SIRA; i-- {
  246. for n := 0; n < projects[i]; n++ {
  247. if suit == Suit_Hokum && i == PROJECT_FOURHUNDRED {
  248. return
  249. }
  250. cards, bInclude := isIncludeTheProject(cardList, i, suit)
  251. if !bInclude {
  252. return
  253. }
  254. cardList = removeCards(cardList, cards)
  255. projectList = append(projectList, SingleProject{
  256. Type: i,
  257. Score: value_project[i],
  258. Cards: cards,
  259. taskScore: value_project_task[i],
  260. })
  261. if bestType < i {
  262. bestType = i
  263. }
  264. }
  265. }
  266. p.CallProject = bestType
  267. p.Projects = projectList
  268. p.bakProjects = projectList
  269. }
  270. func (p *PlayerInfo) removeCard(card int) bool {
  271. for i := 0; i < len(p.HandCards); i++ {
  272. if p.HandCards[i] == card {
  273. p.HandCards = append(p.HandCards[:i], p.HandCards[i+1:]...)
  274. p.CurrentCard = card
  275. return true
  276. }
  277. }
  278. log.Release("PlayerInfo.removeCard %d not exist %v", card, p.HandCards)
  279. return false
  280. }
  281. func (p *PlayerInfo) clearHandCard() {
  282. p.HandCards = []int{}
  283. }
  284. func (p *PlayerInfo) addScore(mineScore int) {
  285. p.WinCardScore += mineScore
  286. p.WinCardChangeScore = mineScore
  287. }
  288. func (p *PlayerInfo) getProjectScore() int {
  289. score := 0
  290. for i := 0; i < len(p.Projects); i++ {
  291. score += p.Projects[i].Score
  292. }
  293. return score
  294. }
  295. func (p *PlayerInfo) IsAllTrumpCard(trumpType int) bool {
  296. for i := 0; i < len(p.HandCards); i++ {
  297. if getCardType(p.HandCards[i]) != trumpType {
  298. return false
  299. }
  300. }
  301. return true
  302. }
  303. func (p *PlayerInfo) addEndScore(weScore int, endScore int, isBO1Win bool, bo1WinScore int) {
  304. if isBO1Win {
  305. p.TotalScore = bo1WinScore
  306. p.roundScores = append(p.roundScores, bo1WinScore)
  307. } else {
  308. p.TotalScore += weScore
  309. p.roundScores = append(p.roundScores, weScore)
  310. }
  311. p.FinalCalcScore = weScore
  312. p.TotalChangeScore = endScore
  313. }
  314. func (p *PlayerInfo) getTotalScore() int {
  315. return p.TotalScore
  316. }
  317. func (p *PlayerInfo) pointsToEndScore() {
  318. p.EndScore = p.getTotalScore()
  319. }
  320. func (p *PlayerInfo) dump(chairId int) {
  321. robot := ""
  322. if p.isRobot {
  323. robot = "ROBOT"
  324. }
  325. log.Debug(" ----Player [%d] chair [%d] enterGold:%d bet:%d %s", p.userID, chairId, p.enterGold, p.bet, robot)
  326. log.Debug(" HandCards%s ", getCardsHex(p.HandCards))
  327. log.Debug(" LeftSendCards%s", getCardsHex(p.LeftSendCards))
  328. log.Debug(" AutoOut[%v] LastAction[%d] Data[%d] CurrentCard[%d]", p.AutoOut, p.LastAction, p.LastActionData, p.CurrentCard)
  329. log.Debug(" CanGawah[%v] HaveBaloot[%v] IsCallBiggest[%v]", p.CanGawah, p.HaveBaloot, p.IsCallBiggest)
  330. log.Debug(" EndScore[%d] TotalScore[%d] WinCardScore[%d], WinCardChangeScore[%d], TotalChangeScore[%d], FinalCalcScore[%d]",
  331. p.EndScore, p.TotalScore, p.WinCardScore, p.WinCardChangeScore, p.TotalChangeScore, p.FinalCalcScore)
  332. log.Debug(" CanDoReshuffle[%v] ReshuffleAction[%d] IsReshuffleTime[%v]", p.CanDoReshuffle,
  333. p.ReshuffleAction, p.IsReshuffleTime)
  334. log.Debug(" CallProject:%d", p.CallProject)
  335. for i := 0; i < len(p.Projects); i++ {
  336. log.Debug(" %s", p.Projects[i].getProjectHex())
  337. }
  338. ret := "PlayerAction:[ "
  339. for n := 0; n < len(p.CanAction); n++ {
  340. ret += fmt.Sprintf("%d", p.CanAction[n])
  341. ret += " "
  342. }
  343. ret += "]"
  344. log.Debug(" %s", ret)
  345. log.Debug(" BigCards%s", getCardsHex(p.BigCards))
  346. log.Debug(" winDoulingData:")
  347. for n := 0; n < len(p.Doublings); n++ {
  348. p.Doublings[n].dump()
  349. }
  350. if p.isControl {
  351. log.Debug(" ContorlType:%d", p.controlType)
  352. log.Debug(" controlDoubling:%d", p.controlDoubling)
  353. log.Debug(" averageDoubling:%d", p.averageDoubling)
  354. }
  355. log.Debug(" IsSurrender:%v", p.IsSurrender)
  356. log.Debug(" +++++++++++++++++")
  357. }