player.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. package gamelogic
  2. import (
  3. "bet24.com/log"
  4. )
  5. type PlayerInfo struct {
  6. IsValid bool //是否有效玩家
  7. Dropped bool //是否已弃牌
  8. AutoOut bool //托管标志
  9. userId int
  10. chairId int
  11. enterGold int
  12. Planes []Plane
  13. LastAction int
  14. Number int //骰子点数
  15. ContinueSixPoint int //连续6点次数
  16. Kills int //击杀次数
  17. Death int //死亡次数
  18. SixPointTotal int //出现6点次数
  19. Place int //名次
  20. Score int //奖金
  21. round int //回合
  22. hope int //期待点数
  23. hopeRound int //期待回合
  24. isShakeOutHope bool //最近几轮内是否摇出期待点数
  25. writtenScore bool // 是否已写分
  26. }
  27. func (p *PlayerInfo) initData(chairId, userId, enterGold int) {
  28. p.IsValid = true
  29. p.chairId = chairId
  30. p.Dropped = false
  31. p.AutoOut = false
  32. p.Kills = 0
  33. p.Death = 0
  34. p.SixPointTotal = 0
  35. p.Place = -1
  36. p.Score = 0
  37. p.userId = userId
  38. p.LastAction = Action_Move // 初始化成move,用于判断第一个动作
  39. p.Planes = make([]Plane, PLANE_COUNT)
  40. for i := 0; i < PLANE_COUNT; i++ {
  41. p.Planes[i].Id = i
  42. p.Planes[i].CanMove = false
  43. p.Planes[i].Position = 0
  44. }
  45. p.enterGold = enterGold
  46. p.round = 0
  47. p.hope = 6 //默认期待起飞点数6
  48. p.hopeRound = 0
  49. p.isShakeOutHope = false
  50. p.writtenScore = false
  51. }
  52. func (p *PlayerInfo) dump(chairId int) {
  53. log.Debug(" ----Player [%d] chair [%d] enterGold:%d", p.userId, chairId, p.enterGold)
  54. log.Debug(" Planes[%v],Place[%d],Score[%d]", p.Planes, p.Place, p.Score)
  55. log.Debug(" LastAction[%d],Number[%d]", p.LastAction, p.Number)
  56. log.Debug(" +++++++++++++++++")
  57. }
  58. //可移动棋子不同坐标数量
  59. func (p *PlayerInfo) canMovePlaneCountByPosition() int {
  60. samePosition := make(map[int]int)
  61. for _, v := range p.Planes {
  62. if v.CanMove {
  63. samePosition[v.Position] = 1
  64. }
  65. }
  66. return len(samePosition)
  67. }
  68. //找可以移动的飞机
  69. func (p *PlayerInfo) canMovePlane(planeId int) (ok bool, Id int, isReach bool, stepCount int) {
  70. ok = false
  71. Id = planeId
  72. isReach = false
  73. stepCount = -1
  74. if !isValidPlane(planeId) {
  75. log.Release("PlayerInfo.movePlane invalid PlaneId %d", planeId)
  76. return
  77. }
  78. number := p.Number
  79. if p.Planes[planeId].Position == 0 {
  80. if number != 6 {
  81. log.Release("PlayerInfo.movePlane plane is not take off %d,%d", planeId, number)
  82. return
  83. } else {
  84. p.Planes[planeId].Position = 1 // 起飞
  85. stepCount = 1
  86. ok = true
  87. return
  88. }
  89. }
  90. // 是否超出
  91. if p.Planes[planeId].Position+number > MAX_STEP {
  92. log.Release("PlayerInfo.movePlane Position[%d] + number[%d] > MAX_STEP[%d]", p.Planes[planeId].Position, number, MAX_STEP)
  93. ok = false
  94. return
  95. }
  96. p.Planes[planeId].Position += number
  97. stepCount = number
  98. ok = true
  99. //是否到达终点
  100. if p.Planes[planeId].Position == MAX_STEP {
  101. log.Release("PlayerInfo.movePlane Arrive End Position[%d] == MAX_STEP[%d]", p.Planes[planeId].Position, MAX_STEP)
  102. isReach = true
  103. }
  104. return
  105. }
  106. func (p *PlayerInfo) setRollNumber(number int) bool {
  107. p.Number = number
  108. //当骰子连续三次掷出6点时,会自动跳过操作,轮到下一名玩家操作
  109. if number == 6 && p.ContinueSixPoint >= 2 {
  110. p.ContinueSixPoint = 0
  111. p.SixPointTotal++
  112. for i := 0; i < PLANE_COUNT; i++ {
  113. p.Planes[i].CanMove = false
  114. }
  115. return false
  116. }
  117. if number == 6 {
  118. p.ContinueSixPoint++
  119. p.SixPointTotal++
  120. }
  121. for i := 0; i < PLANE_COUNT; i++ {
  122. p.Planes[i].resetCanMove(number)
  123. }
  124. return true
  125. }
  126. func (p *PlayerInfo) isWin() bool {
  127. for _, v := range p.Planes {
  128. if !v.isLanded() {
  129. return false
  130. }
  131. }
  132. return true
  133. }
  134. func (p *PlayerInfo) isCanMove() bool {
  135. for _, v := range p.Planes {
  136. if v.CanMove {
  137. return true
  138. }
  139. }
  140. return false
  141. }
  142. //判断期望点是否可以抵达
  143. func (p *PlayerInfo) isHopeCanArrive() bool {
  144. if p.hope == 6 {
  145. return false
  146. }
  147. for _, v := range p.Planes {
  148. if v.Position+p.hope == MAX_STEP {
  149. return true
  150. }
  151. }
  152. return false
  153. }
  154. //判断是否即将获胜
  155. func (p *PlayerInfo) isWillWin() {
  156. //是否全部棋子进入最后阶段
  157. count := 0
  158. for _, v := range p.Planes {
  159. if v.Position == MAX_STEP || v.isWillArrive() {
  160. count++
  161. }
  162. }
  163. if count != 4 {
  164. return
  165. }
  166. if p.isHopeCanArrive() {
  167. return
  168. }
  169. hopePoint := p.getArriveHopePoint()
  170. if hopePoint > 0 && hopePoint < 6 && p.hope != hopePoint {
  171. p.hope = hopePoint
  172. p.isShakeOutHope = false
  173. }
  174. }
  175. //获得即将抵达终点总点数
  176. func (p *PlayerInfo) getArriveHopePoint() int {
  177. validPoints := make(map[int]int)
  178. for _, v := range p.Planes {
  179. distance := v.calculateArriveDistance()
  180. if distance > 0 && distance < 6 {
  181. validPoints[v.Id] = distance
  182. }
  183. }
  184. //Map随机获取
  185. for _, v := range validPoints {
  186. return v
  187. }
  188. return 0
  189. }
  190. //检查是否撞机
  191. func (p *PlayerInfo) checkCrashed(chairId int, pos int) []*Plane {
  192. var crashed []*Plane
  193. for i := 0; i < PLANE_COUNT; i++ {
  194. if isCrash(chairId, pos, p.chairId, p.Planes[i].Position) {
  195. crashed = append(crashed, &p.Planes[i])
  196. }
  197. }
  198. return crashed
  199. }
  200. //检查该对手的所有棋子 与自己棋子坐标的关系 0相对安全 1追赶 2超过
  201. func (p *PlayerInfo) checkChairPosition(chairId int, pos int) int {
  202. //临时标记
  203. temp := 0
  204. if pos == 0 || pos >= 52 {
  205. return temp
  206. }
  207. chair1pos := (chairId*13 + pos) % 52 //自己的棋子操作后的位置
  208. for i := 0; i < PLANE_COUNT; i++ {
  209. //这里不能考虑对手位置是否安全 只需要考虑对手是否起飞和进入最后阶段
  210. if p.Planes[i].Position == 0 || p.Planes[i].Position >= 52 {
  211. continue
  212. }
  213. chair2pos := (p.chairId*13 + p.Planes[i].Position) % 52 //棋盘上对手的位置
  214. if chair1pos == chair2pos {
  215. continue
  216. }
  217. //超过对手
  218. if chair1pos > chair2pos && chair1pos-chair2pos <= 6 {
  219. return 2
  220. } else if chair2pos > chair1pos && chair2pos-chair1pos <= 6 {
  221. temp = 1
  222. }
  223. }
  224. return temp
  225. }
  226. //检查是否在相同位置数量
  227. func (p *PlayerInfo) checkSamePositionCount(position, planeId int) int {
  228. myPlaneCount := 0
  229. for i := 0; i < PLANE_COUNT; i++ {
  230. if p.Planes[i].Id == planeId {
  231. continue
  232. }
  233. if p.Planes[i].Position == 0 {
  234. continue
  235. }
  236. if p.Planes[i].Position == position {
  237. myPlaneCount++
  238. }
  239. }
  240. return myPlaneCount
  241. }
  242. //计算总位置点数
  243. func (p *PlayerInfo) calculatePosition() int {
  244. position := 0
  245. for i := 0; i < PLANE_COUNT; i++ {
  246. if p.Planes[i].Position == 0 {
  247. position -= 6
  248. } else {
  249. position += p.Planes[i].Position
  250. }
  251. }
  252. return position
  253. }