cardlogic.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. package gamelogic
  2. import (
  3. "fmt"
  4. "math/rand"
  5. "bet24.com/log"
  6. "bet24.com/servers/games/masharie_table/common"
  7. )
  8. type cardlogic struct {
  9. cards []int //牌堆
  10. curCardIndex int //当前取牌引用于发牌
  11. trumpCard int //主牌
  12. trumpType int //主花色
  13. cardDeck []common.CardDeck //牌组
  14. curDeckIndex int //当前牌堆索引用于取牌堆
  15. }
  16. func newCardLogic() *cardlogic {
  17. ret := new(cardlogic)
  18. ret.initData()
  19. return ret
  20. }
  21. func (cl *cardlogic) initData() {
  22. cl.cards = make([]int, CARD_COUNT)
  23. for i := 0; i < CARD_COUNT; i++ {
  24. cl.cards[i] = CARD_COUNT //都设置成无效牌值
  25. }
  26. cl.shuffle(false, 0)
  27. }
  28. // 洗牌 @reshuffleType 0:常规洗牌,发牌| 1: 不允许洗出翻倍牌型 | 2: 不允许洗出两组大于baloot项目牌型 | 3: 不允许洗出派奖牌型
  29. func (cl *cardlogic) shuffle(test bool, reshuffleType int) {
  30. cl.trumpType = CardType_Invalid
  31. cl.curCardIndex = 0
  32. cl.curDeckIndex = 0
  33. cl.cards = make([]int, CARD_COUNT)
  34. for d := 0; d < CARD_COUNT; d++ {
  35. cl.cards[d] = d
  36. }
  37. for i := CARD_COUNT - 1; i > 1; i-- {
  38. place := rand.Intn(i)
  39. tmp := cl.cards[place]
  40. cl.cards[place] = cl.cards[i]
  41. cl.cards[i] = tmp
  42. }
  43. if test {
  44. //测试时不洗牌
  45. index := 0
  46. for d := 0; d < 8; d++ {
  47. for t := 0; t < 4; t++ {
  48. cl.cards[index] = d + 8*t
  49. index++
  50. }
  51. }
  52. }
  53. //发牌,不是重洗
  54. if reshuffleType == 0 {
  55. //设置主牌
  56. cl.setTrumpCard()
  57. }
  58. //生成牌组
  59. cl.getCardDeck(reshuffleType)
  60. if reshuffleType == 1 {
  61. if cl.checkMultipleCardDeck() {
  62. //判断是否还有翻倍
  63. cl.shuffle(false, reshuffleType)
  64. }
  65. } else if reshuffleType == 3 {
  66. if cl.checkAwardCardDeck() {
  67. cl.shuffle(false, reshuffleType)
  68. }
  69. } else if cl.checkSameProjectCardDeck() {
  70. cl.shuffle(false, 2)
  71. }
  72. }
  73. // 设置主牌
  74. func (cl *cardlogic) setTrumpCard() {
  75. trumpCard := cl.getOneCard()
  76. cl.trumpCard = trumpCard
  77. cl.trumpType = GetCardType(cl.trumpCard)
  78. }
  79. // 生成牌组
  80. func (cl *cardlogic) getCardDeck(reshuffleType int) {
  81. count := CARD_DECK_COUNT
  82. cl.cardDeck = make([]common.CardDeck, count)
  83. for i := 0; i < count; i++ {
  84. handCards := cl.generateHandCards()
  85. cards, project, projectLength, maxCard := SortHandCards(handCards, cl.trumpType)
  86. cl.cardDeck[i] = common.CardDeck{
  87. HandCards: common.HandCards{
  88. Cards: cards,
  89. Project: project,
  90. ProjectLength: projectLength,
  91. MaxCard: maxCard,
  92. },
  93. }
  94. }
  95. cl.calculateRankings()
  96. cl.dump(reshuffleType)
  97. }
  98. // 五组手牌汇总计算名次, 相同项目的前提下,比较单张牌牌值,第一大也相同,则比较第二大,以此类推,都相同算平分
  99. func (cl *cardlogic) calculateRankings() {
  100. trumpType := cl.trumpType
  101. for i := 0; i < len(cl.cardDeck); i++ {
  102. cl.cardDeck[i].Ranking = 1
  103. for j := 0; j < len(cl.cardDeck); j++ {
  104. if i == j {
  105. continue
  106. }
  107. if cl.cardDeck[j].HandCards.Project > cl.cardDeck[i].HandCards.Project {
  108. cl.cardDeck[i].Ranking++
  109. } else if cl.cardDeck[j].HandCards.Project == cl.cardDeck[i].HandCards.Project {
  110. //如果是没有项目按照单张牌比较
  111. if cl.cardDeck[j].HandCards.Project == common.Project_Base {
  112. ranking := calculateCardsScore(cl.cardDeck[i].HandCards.Cards, cl.cardDeck[j].HandCards.Cards, trumpType)
  113. if ranking == 2 {
  114. cl.cardDeck[i].Ranking++
  115. }
  116. } else {
  117. //有项目则 只拿项目中的牌进行比较 不考虑主花色
  118. //因为已经排好序了 所以只需要比较单张牌值
  119. ranking := calculateProjectScore(cl.cardDeck[i].HandCards.Cards, cl.cardDeck[j].HandCards.Cards)
  120. if ranking == 2 {
  121. cl.cardDeck[i].Ranking++
  122. }
  123. }
  124. }
  125. }
  126. }
  127. }
  128. // 按名次获取手牌
  129. func (cl *cardlogic) getHandCardsByRanking(ranking int) common.CardDeck {
  130. var result []common.CardDeck
  131. var resultIndex []int //牌堆索引
  132. for i, d := range cl.cardDeck {
  133. if d.Ranking == ranking {
  134. result = append(result, d)
  135. resultIndex = append(resultIndex, i)
  136. }
  137. }
  138. //随机取一组
  139. i := rand.Intn(len(resultIndex))
  140. index := resultIndex[i]
  141. //获取后移除
  142. cl.cardDeck = append(cl.cardDeck[:index], cl.cardDeck[index+1:]...)
  143. return result[i]
  144. }
  145. // 得到所有的排名,不去重
  146. func (cl *cardlogic) getAllRanking() []int {
  147. var result []int
  148. for _, d := range cl.cardDeck {
  149. result = append(result, d.Ranking)
  150. }
  151. return result
  152. }
  153. // 根据顺序获取手牌
  154. func (cl *cardlogic) getHandCardsByIndex() common.CardDeck {
  155. ret := cl.cardDeck[cl.curDeckIndex]
  156. cl.curDeckIndex++
  157. return ret
  158. }
  159. // 生成手牌
  160. func (cl *cardlogic) generateHandCards() []int {
  161. count := HAND_CARD_COUNT
  162. ret := make([]int, count)
  163. for i := 0; i < count; i++ {
  164. ret[i] = cl.getOneCard()
  165. }
  166. return ret
  167. }
  168. // 获取单张牌
  169. func (cl *cardlogic) getOneCard() int {
  170. ret := cl.cards[cl.curCardIndex]
  171. cl.curCardIndex++
  172. //存在重新的情况,所以要避免再次拿到主牌
  173. if cl.trumpCard == ret {
  174. ret = cl.getOneCard()
  175. return ret
  176. }
  177. return ret
  178. }
  179. // 检查牌组是否有多倍的牌组
  180. func (cl *cardlogic) checkMultipleCardDeck() bool {
  181. for _, v := range cl.cardDeck {
  182. if v.Project > common.Project_Base {
  183. return true
  184. }
  185. }
  186. return false
  187. }
  188. // 检查是否有两组相同项目的牌组 并且项目大于Baloot
  189. func (cl *cardlogic) checkSameProjectCardDeck() bool {
  190. for i := 0; i < len(cl.cardDeck); i++ {
  191. for j := i + 1; j < len(cl.cardDeck); j++ {
  192. if cl.cardDeck[i].HandCards.Project == cl.cardDeck[j].HandCards.Project && cl.cardDeck[i].HandCards.Project > common.Project_Baloot {
  193. return true
  194. }
  195. }
  196. }
  197. return false
  198. }
  199. // 检查是否有派奖项目的牌组
  200. func (cl *cardlogic) checkAwardCardDeck() bool {
  201. for _, v := range cl.cardDeck {
  202. if v.HandCards.Project > common.Project_Baloot {
  203. return true
  204. }
  205. }
  206. return false
  207. }
  208. func (cl *cardlogic) getCardDeckHex(isHtml bool) string {
  209. ret := " "
  210. for _, v := range cl.cardDeck {
  211. ret += "["
  212. ret += getHandCardsHex(v.HandCards, isHtml)
  213. ret += ""
  214. ret += fmt.Sprintf("%s:%d", "Rank", v.Ranking)
  215. ret += "]"
  216. ret += " "
  217. }
  218. ret += ""
  219. return ret
  220. }
  221. func getHandCardsHex(hand common.HandCards, isHtml bool) string {
  222. ret := ""
  223. ret += fmt.Sprintf("[PJ:%s{%v}]", common.GetProjectDesc(hand.Project, isHtml), common.GetMultiple(hand.Project))
  224. ret += "["
  225. for _, v := range hand.Cards {
  226. ret += ""
  227. ret += getCardHex(v, isHtml)
  228. //最后一个逗号不要
  229. if v != hand.Cards[len(hand.Cards)-1] {
  230. ret += ","
  231. }
  232. }
  233. ret += "]"
  234. if !isHtml {
  235. ret += fmt.Sprintf("[%s:%d]", "PJL", hand.ProjectLength)
  236. ret += fmt.Sprintf("[%s:%d] ", "Max", hand.MaxCard)
  237. }
  238. return ret
  239. }
  240. func (cl *cardlogic) dump(reshuffleType int) {
  241. if reshuffleType != 0 {
  242. log.Debug("!!!==== Reshuffle[%v] ====!!!", reshuffleType)
  243. }
  244. log.Debug("====Cardlogic TrumpCard[%v] CardIndex[%d] DeckIndex[%d]====",
  245. getCardHex(cl.trumpCard, false), cl.curCardIndex, cl.curDeckIndex)
  246. log.Debug("Cards%v", getCardsHex(cl.cards, false))
  247. log.Debug("========================================")
  248. log.Debug("CardDeck%v", cl.getCardDeckHex(false))
  249. log.Debug("========================================")
  250. log.Debug("---------------------------")
  251. }