room.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. package room
  2. import (
  3. "server/msg"
  4. "sort"
  5. "github.com/name5566/leaf/gate"
  6. "github.com/name5566/leaf/log"
  7. )
  8. // 定一个类为每局游戏
  9. type GameRound struct {
  10. // 押注总数
  11. TotalBet int32
  12. //回合列表
  13. Rounds []msg.ReqRound
  14. }
  15. // RoomStatus 房间状态
  16. const (
  17. RoomStatusWaiting = 0 // 等待开局
  18. RoomStatusDealing = 1 // 发牌中
  19. RoomStatusPlaying = 2 // 游戏进行中
  20. RoomStatusEnd = 3 // 游戏结束
  21. )
  22. type Room struct {
  23. Id string
  24. Players []*Player
  25. Status int
  26. // 当前轮次
  27. Round int
  28. // 当前回合的座位
  29. RoundSitPos int
  30. // 每局游戏
  31. GameRound *GameRound
  32. // 牌堆
  33. CardDeck *[]msg.ReqCard
  34. }
  35. type Player struct {
  36. Id string
  37. Agent gate.Agent
  38. IsRobot bool
  39. UserData interface{}
  40. //手牌
  41. HandCards *[]msg.ReqCard
  42. // 座位
  43. SitPos int32
  44. // 等待发牌
  45. WaitCard bool
  46. // 是否已看牌
  47. IsSeen bool
  48. // 是否已弃牌
  49. IsPacked bool
  50. // 是否已开牌
  51. IsShow bool
  52. // 是否已结算
  53. IsSettle bool
  54. // 是否已准备
  55. IsReady bool
  56. // 是否是庄家
  57. IsDealer bool
  58. // 是否获胜
  59. IsWin bool
  60. // 上一次操作
  61. LastOpt *msg.PlayerOpt
  62. // 是否可以亮牌
  63. CanShow bool
  64. }
  65. // 获取玩家ID
  66. func (p *Player) GetUserId() string {
  67. return p.Id
  68. }
  69. // 获取玩家的昵称
  70. func (p *Player) GetNickname() string {
  71. if userData, ok := p.UserData.(struct{ Nickname string }); ok {
  72. return userData.Nickname
  73. }
  74. return ""
  75. }
  76. // 获取玩家的头像
  77. func (p *Player) GetAvatar() string {
  78. if userData, ok := p.UserData.(struct{ Head_Image string }); ok {
  79. return userData.Head_Image
  80. }
  81. return ""
  82. }
  83. func (r *Room) AddPlayer(p *Player) {
  84. r.Players = append(r.Players, p)
  85. }
  86. func (r *Room) RemovePlayer(p *Player) {
  87. for i, player := range r.Players {
  88. if player.Id == p.Id {
  89. r.Players = append(r.Players[:i], r.Players[i+1:]...)
  90. break
  91. }
  92. }
  93. }
  94. func (r *Room) RemoveAllRobot() {
  95. newPlayers := make([]*Player, 0)
  96. for _, player := range r.Players {
  97. if !player.IsRobot {
  98. newPlayers = append(newPlayers, player)
  99. }
  100. }
  101. r.Players = newPlayers
  102. }
  103. func (r *Room) GetPlayer(id string) *Player {
  104. for _, player := range r.Players {
  105. if player.Id == id {
  106. return player
  107. }
  108. }
  109. return nil
  110. }
  111. // 获取庄家的玩家
  112. func (r *Room) GetDealerPlayer() *Player {
  113. for _, player := range r.Players {
  114. if player.IsDealer {
  115. return player
  116. }
  117. }
  118. return nil
  119. }
  120. // 设置指定玩家为庄家,并设置其他玩家为非庄家
  121. func (r *Room) SetDealerPlayer(p *Player) {
  122. for _, player := range r.Players {
  123. player.IsDealer = false
  124. }
  125. p.IsDealer = true
  126. }
  127. // 获取WaitCard是false的所有玩家
  128. func (r *Room) GetWaitCardPlayers() []*Player {
  129. players := make([]*Player, 0)
  130. for _, player := range r.Players {
  131. if !player.WaitCard {
  132. players = append(players, player)
  133. }
  134. }
  135. return players
  136. }
  137. // sitPos 是当前玩家的座位号,GetWaitCardPlayers 从sitPos开始 顺时针方向把所有玩家返回
  138. // 从指定座位号开始顺时针获取所有玩家
  139. func (room *Room) GetPlayersBySitPos(startSitPos int32) []*Player {
  140. players := make([]*Player, 0)
  141. maxSitPos := int32(5) //
  142. log.Debug("startSitPos:%v", room.Players)
  143. // 先添加大于等于 startSitPos 的座位
  144. for sitPos := startSitPos; sitPos <= maxSitPos; sitPos++ {
  145. for _, player := range room.Players {
  146. if player.SitPos == sitPos {
  147. players = append(players, player)
  148. break
  149. }
  150. }
  151. }
  152. // 再添加小于 startSitPos 的座位
  153. for sitPos := int32(0); sitPos < startSitPos; sitPos++ {
  154. for _, player := range room.Players {
  155. if player.SitPos == sitPos {
  156. players = append(players, player)
  157. break
  158. }
  159. }
  160. }
  161. return players
  162. }
  163. // 根据座位号获取玩家
  164. func (r *Room) GetPlayerBySitPos(sitPos int32) *Player {
  165. for _, player := range r.Players {
  166. if player.SitPos == sitPos {
  167. return player
  168. }
  169. }
  170. return nil
  171. }
  172. // 增加玩家操作到当前回合
  173. func (r *Room) AddPlayerOpt(round *msg.ReqRound) {
  174. r.Round++
  175. r.GameRound.Rounds = append(r.GameRound.Rounds, *round)
  176. }
  177. // 设置当前回合为下个没有弃牌的玩家(逆时针)
  178. func (r *Room) SetNextRound() {
  179. curSitPos := int32(r.RoundSitPos)
  180. player := r.GetPlayerBySitPos(curSitPos)
  181. player.CanShow = true
  182. // 按照座位号从小到大排序
  183. sort.Slice(r.Players, func(i, j int) bool {
  184. return r.Players[i].SitPos < r.Players[j].SitPos
  185. })
  186. // 获取当前座位号的索引
  187. curSitPosIndex := -1
  188. for i, player := range r.Players {
  189. if player.SitPos == curSitPos {
  190. curSitPosIndex = i
  191. break
  192. }
  193. }
  194. // 逆时针:当前索引减1
  195. // 如果减1后小于0,则回到最后一个位置
  196. nextIndex := curSitPosIndex
  197. for i := 0; i < len(r.Players); i++ {
  198. nextIndex = (curSitPosIndex - 1 - i + len(r.Players)) % len(r.Players)
  199. if !r.Players[nextIndex].IsPacked {
  200. break
  201. }
  202. }
  203. r.RoundSitPos = int(r.Players[nextIndex].SitPos)
  204. log.Debug("SetNextRound:下一个操作的玩家座位:%d", r.RoundSitPos)
  205. }
  206. // 获取没有弃牌的玩家是否只有一个,并返回没有弃牌的座位号
  207. func (r *Room) IsOnlyOneNotPacked() (bool, int32) {
  208. count := 0
  209. sitPos := int32(0)
  210. for _, player := range r.Players {
  211. if !player.IsPacked {
  212. count++
  213. sitPos = player.SitPos
  214. }
  215. }
  216. return count == 1, sitPos
  217. }
  218. // 当前座位号玩家获胜
  219. func (r *Room) PlayerWin(sitPos int32) {
  220. player := r.GetPlayerBySitPos(sitPos)
  221. player.IsWin = true
  222. r.Status = RoomStatusEnd
  223. }
  224. // 增加押注
  225. func (r *Room) AddBet(bet int32) {
  226. r.GameRound.TotalBet += bet
  227. }