package gamelogic import ( "fmt" "math/rand" "bet24.com/log" "bet24.com/servers/games/masharie_table/common" ) type cardlogic struct { cards []int //牌堆 curCardIndex int //当前取牌引用于发牌 trumpCard int //主牌 trumpType int //主花色 cardDeck []common.CardDeck //牌组 curDeckIndex int //当前牌堆索引用于取牌堆 } func newCardLogic() *cardlogic { ret := new(cardlogic) ret.initData() return ret } func (cl *cardlogic) initData() { cl.cards = make([]int, CARD_COUNT) for i := 0; i < CARD_COUNT; i++ { cl.cards[i] = CARD_COUNT //都设置成无效牌值 } cl.shuffle(false, 0) } // 洗牌 @reshuffleType 0:常规洗牌,发牌| 1: 不允许洗出翻倍牌型 | 2: 不允许洗出两组大于baloot项目牌型 | 3: 不允许洗出派奖牌型 func (cl *cardlogic) shuffle(test bool, reshuffleType int) { cl.trumpType = CardType_Invalid cl.curCardIndex = 0 cl.curDeckIndex = 0 cl.cards = make([]int, CARD_COUNT) for d := 0; d < CARD_COUNT; d++ { cl.cards[d] = d } for i := CARD_COUNT - 1; i > 1; i-- { place := rand.Intn(i) tmp := cl.cards[place] cl.cards[place] = cl.cards[i] cl.cards[i] = tmp } if test { //测试时不洗牌 index := 0 for d := 0; d < 8; d++ { for t := 0; t < 4; t++ { cl.cards[index] = d + 8*t index++ } } } //发牌,不是重洗 if reshuffleType == 0 { //设置主牌 cl.setTrumpCard() } //生成牌组 cl.getCardDeck(reshuffleType) if reshuffleType == 1 { if cl.checkMultipleCardDeck() { //判断是否还有翻倍 cl.shuffle(false, reshuffleType) } } else if reshuffleType == 3 { if cl.checkAwardCardDeck() { cl.shuffle(false, reshuffleType) } } else if cl.checkSameProjectCardDeck() { cl.shuffle(false, 2) } } // 设置主牌 func (cl *cardlogic) setTrumpCard() { trumpCard := cl.getOneCard() cl.trumpCard = trumpCard cl.trumpType = GetCardType(cl.trumpCard) } // 生成牌组 func (cl *cardlogic) getCardDeck(reshuffleType int) { count := CARD_DECK_COUNT cl.cardDeck = make([]common.CardDeck, count) for i := 0; i < count; i++ { handCards := cl.generateHandCards() cards, project, projectLength, maxCard := SortHandCards(handCards, cl.trumpType) cl.cardDeck[i] = common.CardDeck{ HandCards: common.HandCards{ Cards: cards, Project: project, ProjectLength: projectLength, MaxCard: maxCard, }, } } cl.calculateRankings() cl.dump(reshuffleType) } // 五组手牌汇总计算名次, 相同项目的前提下,比较单张牌牌值,第一大也相同,则比较第二大,以此类推,都相同算平分 func (cl *cardlogic) calculateRankings() { trumpType := cl.trumpType for i := 0; i < len(cl.cardDeck); i++ { cl.cardDeck[i].Ranking = 1 for j := 0; j < len(cl.cardDeck); j++ { if i == j { continue } if cl.cardDeck[j].HandCards.Project > cl.cardDeck[i].HandCards.Project { cl.cardDeck[i].Ranking++ } else if cl.cardDeck[j].HandCards.Project == cl.cardDeck[i].HandCards.Project { //如果是没有项目按照单张牌比较 if cl.cardDeck[j].HandCards.Project == common.Project_Base { ranking := calculateCardsScore(cl.cardDeck[i].HandCards.Cards, cl.cardDeck[j].HandCards.Cards, trumpType) if ranking == 2 { cl.cardDeck[i].Ranking++ } } else { //有项目则 只拿项目中的牌进行比较 不考虑主花色 //因为已经排好序了 所以只需要比较单张牌值 ranking := calculateProjectScore(cl.cardDeck[i].HandCards.Cards, cl.cardDeck[j].HandCards.Cards) if ranking == 2 { cl.cardDeck[i].Ranking++ } } } } } } // 按名次获取手牌 func (cl *cardlogic) getHandCardsByRanking(ranking int) common.CardDeck { var result []common.CardDeck var resultIndex []int //牌堆索引 for i, d := range cl.cardDeck { if d.Ranking == ranking { result = append(result, d) resultIndex = append(resultIndex, i) } } //随机取一组 i := rand.Intn(len(resultIndex)) index := resultIndex[i] //获取后移除 cl.cardDeck = append(cl.cardDeck[:index], cl.cardDeck[index+1:]...) return result[i] } // 得到所有的排名,不去重 func (cl *cardlogic) getAllRanking() []int { var result []int for _, d := range cl.cardDeck { result = append(result, d.Ranking) } return result } // 根据顺序获取手牌 func (cl *cardlogic) getHandCardsByIndex() common.CardDeck { ret := cl.cardDeck[cl.curDeckIndex] cl.curDeckIndex++ return ret } // 生成手牌 func (cl *cardlogic) generateHandCards() []int { count := HAND_CARD_COUNT ret := make([]int, count) for i := 0; i < count; i++ { ret[i] = cl.getOneCard() } return ret } // 获取单张牌 func (cl *cardlogic) getOneCard() int { ret := cl.cards[cl.curCardIndex] cl.curCardIndex++ //存在重新的情况,所以要避免再次拿到主牌 if cl.trumpCard == ret { ret = cl.getOneCard() return ret } return ret } // 检查牌组是否有多倍的牌组 func (cl *cardlogic) checkMultipleCardDeck() bool { for _, v := range cl.cardDeck { if v.Project > common.Project_Base { return true } } return false } // 检查是否有两组相同项目的牌组 并且项目大于Baloot func (cl *cardlogic) checkSameProjectCardDeck() bool { for i := 0; i < len(cl.cardDeck); i++ { for j := i + 1; j < len(cl.cardDeck); j++ { if cl.cardDeck[i].HandCards.Project == cl.cardDeck[j].HandCards.Project && cl.cardDeck[i].HandCards.Project > common.Project_Baloot { return true } } } return false } // 检查是否有派奖项目的牌组 func (cl *cardlogic) checkAwardCardDeck() bool { for _, v := range cl.cardDeck { if v.HandCards.Project > common.Project_Baloot { return true } } return false } func (cl *cardlogic) getCardDeckHex(isHtml bool) string { ret := " " for _, v := range cl.cardDeck { ret += "[" ret += getHandCardsHex(v.HandCards, isHtml) ret += "" ret += fmt.Sprintf("%s:%d", "Rank", v.Ranking) ret += "]" ret += " " } ret += "" return ret } func getHandCardsHex(hand common.HandCards, isHtml bool) string { ret := "" ret += fmt.Sprintf("[PJ:%s{%v}]", common.GetProjectDesc(hand.Project, isHtml), common.GetMultiple(hand.Project)) ret += "[" for _, v := range hand.Cards { ret += "" ret += getCardHex(v, isHtml) //最后一个逗号不要 if v != hand.Cards[len(hand.Cards)-1] { ret += "," } } ret += "]" if !isHtml { ret += fmt.Sprintf("[%s:%d]", "PJL", hand.ProjectLength) ret += fmt.Sprintf("[%s:%d] ", "Max", hand.MaxCard) } return ret } func (cl *cardlogic) dump(reshuffleType int) { if reshuffleType != 0 { log.Debug("!!!==== Reshuffle[%v] ====!!!", reshuffleType) } log.Debug("====Cardlogic TrumpCard[%v] CardIndex[%d] DeckIndex[%d]====", getCardHex(cl.trumpCard, false), cl.curCardIndex, cl.curDeckIndex) log.Debug("Cards%v", getCardsHex(cl.cards, false)) log.Debug("========================================") log.Debug("CardDeck%v", cl.getCardDeckHex(false)) log.Debug("========================================") log.Debug("---------------------------") }