playerinfo.go 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  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. OpenChannel bool //打开最后的通道
  22. round int //回合
  23. hope int //期待点数
  24. hopeRound int //期待回合
  25. isShakeOutHope bool //最近几轮内是否摇出期待点数
  26. writtenScore bool // 是否已写分
  27. bet int //投注金额
  28. isRobot bool //是否机器人
  29. }
  30. func (p *PlayerInfo) initData(chairId, userId, enterGold int) {
  31. p.gameInit()
  32. p.IsValid = false
  33. p.Dropped = false
  34. p.chairId = chairId
  35. p.enterGold = enterGold
  36. p.userId = userId
  37. }
  38. func (p *PlayerInfo) gameInit() {
  39. p.AutoOut = false
  40. p.Kills = 0
  41. p.Death = 0
  42. p.SixPointTotal = 0
  43. p.ContinueSixPoint = 0
  44. p.Place = -1
  45. p.Score = 0
  46. p.LastAction = Action_Move // 初始化成move,用于判断第一个动作
  47. p.OpenChannel = false //默认封禁
  48. p.Planes = make([]Plane, PLANE_COUNT)
  49. for i := 0; i < PLANE_COUNT; i++ {
  50. p.Planes[i].Id = i
  51. //前面2个棋子位置设置成1并且可以移动
  52. if i < 2 {
  53. p.Planes[i].Position = 1
  54. p.Planes[i].CanMove = true
  55. } else {
  56. p.Planes[i].CanMove = false
  57. p.Planes[i].Position = 0
  58. }
  59. }
  60. p.round = 0
  61. p.hope = 6 //默认期待起飞点数6
  62. p.hopeRound = 0
  63. p.isShakeOutHope = false
  64. p.writtenScore = false
  65. p.bet = 0
  66. }
  67. func (p *PlayerInfo) dump(chairId int) {
  68. robot := ""
  69. if p.isRobot {
  70. robot = "ROBOT"
  71. }
  72. if p.IsValid {
  73. log.Debug(" ----Player [%d] chair [%d] enterGold:%d %s", p.userId, chairId, p.enterGold, robot)
  74. log.Debug(" OpenChannel[%v] Planes[%v],Place[%d],Score[%d]", p.OpenChannel, p.Planes, p.Place, p.Score)
  75. log.Debug(" LastAction[%d],Number[%d]", p.LastAction, p.Number)
  76. log.Debug(" +++++++++++++++++")
  77. }
  78. }
  79. // 可移动棋子不同坐标数量
  80. func (p *PlayerInfo) canMovePlaneCountByPosition() int {
  81. samePosition := make(map[int]int)
  82. for _, v := range p.Planes {
  83. if v.CanMove {
  84. samePosition[v.Position] = 1
  85. }
  86. }
  87. return len(samePosition)
  88. }
  89. // 找可以移动的飞机
  90. func (p *PlayerInfo) canMovePlane(planeId int) (ok bool, Id int, isReach bool, stepCount int, oldPosition int) {
  91. ok = false
  92. Id = planeId
  93. isReach = false
  94. stepCount = -1
  95. if !isValidPlane(planeId) {
  96. log.Release("PlayerInfo.movePlane invalid PlaneId %d", planeId)
  97. return
  98. }
  99. oldPosition = p.Planes[planeId].Position
  100. number := p.Number
  101. if p.Planes[planeId].Position == 0 {
  102. if number != 6 {
  103. log.Release("PlayerInfo.movePlane plane is not take off %d,%d", planeId, number)
  104. return
  105. } else {
  106. p.Planes[planeId].Position = 1 // 起飞
  107. stepCount = 1
  108. ok = true
  109. return
  110. }
  111. }
  112. // 如果不封锁的情况 判断是否超出
  113. if p.OpenChannel && p.Planes[planeId].Position+number > MAX_STEP {
  114. log.Release("PlayerInfo.movePlane Position[%d] + number[%d] > MAX_STEP[%d]", p.Planes[planeId].Position, number, MAX_STEP)
  115. ok = false
  116. return
  117. }
  118. stepCount = number
  119. //限制通过 or 已经超过入口
  120. if !p.OpenChannel || p.Planes[planeId].Position == LOOP_START {
  121. if p.Planes[planeId].Position+number > LOOP_START {
  122. //计算差值剩余的步数由1开始计算
  123. number = number - (LOOP_START - p.Planes[planeId].Position) - 1
  124. p.Planes[planeId].Position = 1
  125. }
  126. p.Planes[planeId].Position += number
  127. } else {
  128. //如果通道打开则不走52
  129. if p.Planes[planeId].Position < LOOP_START && p.Planes[planeId].Position+number >= LOOP_START {
  130. number = number - (LOOP_START - p.Planes[planeId].Position)
  131. p.Planes[planeId].Position = SAFE_START
  132. }
  133. p.Planes[planeId].Position += number
  134. }
  135. ok = true
  136. if p.Planes[planeId].Position == MAX_STEP {
  137. log.Release("PlayerInfo.movePlane Arrive End Position[%d] == MAX_STEP[%d]", p.Planes[planeId].Position, MAX_STEP)
  138. isReach = true
  139. }
  140. return
  141. }
  142. func (p *PlayerInfo) setRollNumber(number int) bool {
  143. p.Number = number
  144. //当骰子连续三次掷出6点时,会自动跳过操作,轮到下一名玩家操作
  145. if number == 6 && p.ContinueSixPoint >= 2 {
  146. p.ContinueSixPoint = 0
  147. p.SixPointTotal++
  148. for i := 0; i < PLANE_COUNT; i++ {
  149. p.Planes[i].CanMove = false
  150. }
  151. return false
  152. }
  153. if number == 6 {
  154. p.ContinueSixPoint++
  155. p.SixPointTotal++
  156. }
  157. for i := 0; i < PLANE_COUNT; i++ {
  158. p.Planes[i].resetCanMove(number)
  159. }
  160. return true
  161. }
  162. func (p *PlayerInfo) isWin() bool {
  163. for _, v := range p.Planes {
  164. //这个版本的逻辑是有一个到达就算赢
  165. if v.isLanded() {
  166. return true
  167. }
  168. }
  169. return false
  170. }
  171. func (p *PlayerInfo) isCanMove() bool {
  172. for _, v := range p.Planes {
  173. if v.CanMove {
  174. return true
  175. }
  176. }
  177. return false
  178. }
  179. // 判断期望点是否可以抵达
  180. func (p *PlayerInfo) isHopeCanArrive() bool {
  181. if p.hope == 6 {
  182. return false
  183. }
  184. for _, v := range p.Planes {
  185. if v.Position+p.hope == MAX_STEP {
  186. return true
  187. }
  188. }
  189. return false
  190. }
  191. // 判断是否即将获胜
  192. func (p *PlayerInfo) isWillWin() {
  193. count := 0
  194. for _, v := range p.Planes {
  195. if p.OpenChannel && v.isWillArrive() {
  196. count++
  197. }
  198. }
  199. if count < 1 {
  200. return
  201. }
  202. //判断当前的期待点数是否可以到达
  203. if p.OpenChannel && p.isHopeCanArrive() {
  204. return
  205. }
  206. hopePoint := p.getArriveHopePoint()
  207. if p.OpenChannel && hopePoint > 0 && hopePoint < 6 && p.hope != hopePoint {
  208. p.hope = hopePoint
  209. p.isShakeOutHope = false
  210. }
  211. }
  212. // 获得即将抵达终点总点数
  213. func (p *PlayerInfo) getArriveHopePoint() int {
  214. if !p.OpenChannel {
  215. return 0
  216. }
  217. validPoints := make(map[int]int)
  218. for _, v := range p.Planes {
  219. distance := v.calculateArriveDistance()
  220. if distance > 0 && distance < 6 {
  221. validPoints[v.Id] = distance
  222. }
  223. }
  224. //Map随机获取
  225. for _, v := range validPoints {
  226. return v
  227. }
  228. return 0
  229. }
  230. // 检查是否撞机
  231. func (p *PlayerInfo) checkCrashed(chairId int, pos int) []*Plane {
  232. var crashed []*Plane
  233. for i := 0; i < PLANE_COUNT; i++ {
  234. if isCrash(chairId, pos, p.chairId, p.Planes[i].Position) {
  235. crashed = append(crashed, &p.Planes[i])
  236. }
  237. }
  238. return crashed
  239. }
  240. // 检查该对手的所有棋子 与自己棋子坐标的关系 0相对安全 1追赶 2超过
  241. func (p *PlayerInfo) checkChairPosition(chairId int, pos int) int {
  242. temp := 0
  243. if pos == 0 || pos >= SAFE_START {
  244. return temp
  245. }
  246. chair1pos := (chairId*13 + pos) % LOOP_START //自己的棋子操作后的位置
  247. for i := 0; i < PLANE_COUNT; i++ {
  248. //这里不能考虑对手位置是否安全 只需要考虑对手是否起飞和进入最后阶段
  249. if p.Planes[i].Position == 0 || p.Planes[i].Position >= SAFE_START {
  250. continue
  251. }
  252. chair2pos := (p.chairId*13 + p.Planes[i].Position) % LOOP_START //棋盘上对手的位置
  253. if chair1pos == chair2pos {
  254. continue
  255. }
  256. //超过对手
  257. if chair1pos > chair2pos && chair1pos-chair2pos <= 6 {
  258. return 2
  259. } else if chair2pos > chair1pos && chair2pos-chair1pos <= 6 {
  260. temp = 1
  261. }
  262. }
  263. return temp
  264. }
  265. // 检查是否在相同位置数量
  266. func (p *PlayerInfo) checkSamePositionCount(position, planeId int) int {
  267. myPlaneCount := 0
  268. for i := 0; i < PLANE_COUNT; i++ {
  269. if p.Planes[i].Id == planeId {
  270. continue
  271. }
  272. if p.Planes[i].Position == 0 {
  273. continue
  274. }
  275. if p.Planes[i].Position == position {
  276. myPlaneCount++
  277. }
  278. }
  279. return myPlaneCount
  280. }
  281. // 计算总位置点数
  282. func (p *PlayerInfo) calculatePosition() int {
  283. //只考虑最远端
  284. farthest := 0
  285. for i := 0; i < PLANE_COUNT; i++ {
  286. if p.Planes[i].Position == 0 {
  287. continue
  288. }
  289. if p.Planes[i].Position > farthest {
  290. farthest = p.Planes[i].Position
  291. }
  292. }
  293. return farthest
  294. }
  295. func (p *PlayerInfo) checkTookOffCount() (int, int) {
  296. tookOff := 0
  297. //离开起飞区
  298. leave := 0
  299. for i := 0; i < PLANE_COUNT; i++ {
  300. if p.Planes[i].isTookOff() {
  301. tookOff++
  302. if p.Planes[i].Position >= 10 {
  303. leave++
  304. }
  305. }
  306. }
  307. return tookOff, leave
  308. }
  309. // 转换棋子坐标
  310. func (p *PlayerInfo) convertPlanePosition(pos int) int {
  311. return (p.chairId*13 + pos) % LOOP_START
  312. }