360 lines
8.2 KiB
Go
360 lines
8.2 KiB
Go
package redvsblack
|
||
|
||
import (
|
||
"mongo.games.com/game/common"
|
||
"sort"
|
||
)
|
||
|
||
var CardsKindFigureUpSington = &CardsKindFigureUp{}
|
||
|
||
type handCardsInfo struct {
|
||
cards []int //考虑花色,从小到大排序,注意A的位置
|
||
cards2 []int //不考虑花色,从小到大排序,注意A的位置
|
||
numColor int //花形数量
|
||
numValue int //牌型数量
|
||
maxValue int //最大单牌
|
||
maxColor int //最大单牌花色
|
||
}
|
||
|
||
type KindOfCard struct {
|
||
Kind int //牌型
|
||
maxValue int //最大单牌
|
||
maxColor int //最大单牌花色
|
||
orgCards []int //原始牌
|
||
nocCards []int //去掉花色的牌
|
||
OrderCards []int //排序后的牌
|
||
}
|
||
|
||
func (this *KindOfCard) TidyCards() {
|
||
// var order []int
|
||
// if this.Kind == CardsKind_RoyalStraight || this.Kind == CardsKind_RoyalFlushStraight {
|
||
// order = []int{this.nocCards[1], this.nocCards[2], this.nocCards[0]} //把A放后面
|
||
// } else {
|
||
// order = this.nocCards
|
||
// }
|
||
// orgCards := make([]int, Hand_CardNum, Hand_CardNum)
|
||
// copy(orgCards, this.orgCards)
|
||
// for _, c := range order {
|
||
// for i, oc := range orgCards {
|
||
// if c == oc%PER_CARD_COLOR_MAX {
|
||
// n := len(orgCards)
|
||
// this.OrderCards = append(this.OrderCards, oc)
|
||
// rest := orgCards[:i]
|
||
// if i < n-1 {
|
||
// rest = append(rest, orgCards[i+1:]...)
|
||
// }
|
||
// orgCards = rest
|
||
// break
|
||
// }
|
||
// }
|
||
// }
|
||
this.OrderCards = this.orgCards
|
||
}
|
||
|
||
func CreateCardKind() *KindOfCard {
|
||
return &KindOfCard{
|
||
Kind: CardsKind_Single,
|
||
maxValue: 0,
|
||
maxColor: 0,
|
||
}
|
||
}
|
||
|
||
type CardsKindFigureUp struct {
|
||
}
|
||
|
||
func createHandCardsInfo(cards []int) *handCardsInfo {
|
||
cardsInfo := &handCardsInfo{
|
||
cards: make([]int, len(cards)),
|
||
}
|
||
copy(cardsInfo.cards, cards)
|
||
//先整理下牌
|
||
sort.Ints(cardsInfo.cards)
|
||
colorMap := make(map[int]bool)
|
||
kindMap := make(map[int]bool)
|
||
maxValue := 1
|
||
for i := 0; i < Hand_CardNum; i++ {
|
||
c := cardsInfo.cards[i] / PER_CARD_COLOR_MAX
|
||
k := cardsInfo.cards[i] % PER_CARD_COLOR_MAX
|
||
colorMap[c] = true
|
||
kindMap[k] = true
|
||
cardsInfo.cards2 = append(cardsInfo.cards2, k)
|
||
if CardValueMap[k] > CardValueMap[maxValue] {
|
||
maxValue = k
|
||
cardsInfo.maxValue = k
|
||
cardsInfo.maxColor = c
|
||
} else if CardValueMap[k] == CardValueMap[maxValue] {
|
||
if c > cardsInfo.maxColor {
|
||
cardsInfo.maxColor = c
|
||
}
|
||
}
|
||
}
|
||
sort.Ints(cardsInfo.cards2)
|
||
cardsInfo.numColor = len(colorMap)
|
||
cardsInfo.numValue = len(kindMap)
|
||
return cardsInfo
|
||
}
|
||
|
||
func (this *CardsKindFigureUp) FigureUpByCard(cards []int) *KindOfCard {
|
||
cardsInfo := createHandCardsInfo(cards)
|
||
//处理检查的牌型
|
||
cardKind := this.checkCardKind(cardsInfo)
|
||
if cardKind != nil {
|
||
cardKind.nocCards = cardsInfo.cards2
|
||
} else {
|
||
cardKind = &KindOfCard{
|
||
Kind: CardsKind_Single,
|
||
maxValue: cardsInfo.maxValue,
|
||
maxColor: cardsInfo.maxColor,
|
||
nocCards: cardsInfo.cards2,
|
||
}
|
||
}
|
||
cardKind.orgCards = cards
|
||
|
||
return cardKind
|
||
}
|
||
|
||
func (this *CardsKindFigureUp) checkCardKind(cardsInfo *handCardsInfo) *KindOfCard {
|
||
for i := CardsKind_Max - 1; i > 0; i-- {
|
||
kindFunc := getCardCheckFunc(i)
|
||
if kindFunc == nil {
|
||
continue
|
||
}
|
||
koc := kindFunc(cardsInfo)
|
||
if koc != nil {
|
||
return koc
|
||
}
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func CompareCards(l, r *KindOfCard) int {
|
||
if l.Kind == r.Kind { //牌型相同
|
||
ret := compareCardsSameKindBySize(l, r)
|
||
if ret == 0 {
|
||
if l.maxColor > r.maxColor {
|
||
return 1
|
||
} else {
|
||
return -1
|
||
}
|
||
} else {
|
||
return ret
|
||
}
|
||
}
|
||
if l.Kind > r.Kind {
|
||
return 1
|
||
} else {
|
||
return -1
|
||
}
|
||
}
|
||
|
||
// 比大小:同牌型最大单牌大小相同的情况下,依次比较剩余牌的大小
|
||
func compareCardsSameKindBySize(l, r *KindOfCard) int {
|
||
if l.nocCards[0] == A_CARD && r.nocCards[0] != A_CARD {
|
||
return 1
|
||
}
|
||
if l.nocCards[0] != A_CARD && r.nocCards[0] == A_CARD {
|
||
return -1
|
||
}
|
||
//对子比较(优先比对)
|
||
if l.Kind == CardsKind_Double || l.Kind == CardsKind_BigDouble {
|
||
if CardValueMap[l.nocCards[0]] > CardValueMap[r.nocCards[0]] {
|
||
return 1
|
||
} else if CardValueMap[l.nocCards[0]] < CardValueMap[r.nocCards[0]] {
|
||
return -1
|
||
}
|
||
}
|
||
for i := 2; i >= 0; i-- {
|
||
if CardValueMap[l.nocCards[i]] > CardValueMap[r.nocCards[i]] {
|
||
return 1
|
||
} else if CardValueMap[l.nocCards[i]] < CardValueMap[r.nocCards[i]] {
|
||
return -1
|
||
}
|
||
}
|
||
//大小相等
|
||
return 0
|
||
}
|
||
|
||
// 比花色:同牌型最大单牌大小相同的情况下,最大单牌比较花色,黑桃>红桃>梅花>方片
|
||
func CompareCardsSameKindByColor(l, r *KindOfCard) int {
|
||
if l.maxColor > r.maxColor {
|
||
return 1
|
||
} else {
|
||
return -1
|
||
}
|
||
}
|
||
|
||
// 根据牌型创建相应的牌
|
||
func CreateCardByKind(cards [2][3]int, k int) []int {
|
||
//先将两幅手牌放入一个数组中
|
||
//在两幅手牌中找到花色相同的牌
|
||
temp := make([]int, 0)
|
||
for i := 0; i < 2; i++ {
|
||
for j := 0; j < 3; j++ {
|
||
temp = append(temp, cards[i][j])
|
||
}
|
||
}
|
||
|
||
//根据不同的类型调用对应的生成函数
|
||
if k == CardsKind_BigDouble {
|
||
return CreateBigDouble(temp)
|
||
} else if k == CardsKind_Straight {
|
||
return CreateStraight(temp)
|
||
} else if k == CardsKind_Flush {
|
||
return CreateFlush(temp)
|
||
} else if k == CardsKind_ThreeSame {
|
||
return CreateThreeSame(temp)
|
||
}
|
||
return temp
|
||
}
|
||
func CreateBigDouble(temp []int) []int {
|
||
//先找出牌面值大于8的任一一张牌
|
||
sameCard := -1
|
||
for idx, v := range temp {
|
||
c := v % PER_CARD_COLOR_MAX
|
||
if CardValueMap[c] > 8 {
|
||
sameCard = v
|
||
temp[0], temp[idx] = temp[idx], temp[0]
|
||
break
|
||
}
|
||
}
|
||
|
||
//现有手牌里查找是否有相同的
|
||
for i := 1; i < len(temp); i++ {
|
||
if temp[i]%PER_CARD_COLOR_MAX == sameCard%PER_CARD_COLOR_MAX {
|
||
temp[1], temp[i] = temp[i], temp[1]
|
||
return temp
|
||
}
|
||
}
|
||
//没有相同的,创造一张相同的牌
|
||
temp[1] = sameCard%PER_CARD_COLOR_MAX + common.RandInt(1, 4)*PER_CARD_COLOR_MAX
|
||
if temp[1] > POKER_CART_CNT {
|
||
temp[1] = temp[1] - POKER_CART_CNT
|
||
}
|
||
return temp
|
||
}
|
||
func CreateStraight(temp []int) []int {
|
||
firstCard := 0
|
||
//找出第一张不是K的牌
|
||
for k, v := range temp {
|
||
c := v % PER_CARD_COLOR_MAX
|
||
if CardValueMap[c] < 12 {
|
||
firstCard = c
|
||
temp[0], temp[k] = temp[k], temp[0]
|
||
break
|
||
}
|
||
}
|
||
|
||
//从第二张开始查找,现有的牌能否凑成顺子,不能则创造一张
|
||
n := 1
|
||
for i := 1; i < len(temp); i++ {
|
||
c := temp[i] % PER_CARD_COLOR_MAX
|
||
if CardValueMap[c] == firstCard+1 {
|
||
temp[n], temp[i] = temp[i], temp[n]
|
||
firstCard++
|
||
n++
|
||
}
|
||
}
|
||
|
||
if n < 3 {
|
||
for i := n; i < 3; i++ {
|
||
temp[i] = (firstCard + 1) + common.RandInt(4)*PER_CARD_COLOR_MAX
|
||
firstCard++
|
||
}
|
||
}
|
||
|
||
return temp
|
||
}
|
||
func CreateFlush(temp []int) []int {
|
||
colorMap := make(map[int]int)
|
||
maxColor := 0
|
||
for _, v := range temp {
|
||
c := v / PER_CARD_COLOR_MAX
|
||
colorMap[c] = colorMap[c] + 1
|
||
if colorMap[c] > colorMap[maxColor] {
|
||
maxColor = c
|
||
}
|
||
}
|
||
|
||
//将maxColor花色的牌放最前边
|
||
n := 0
|
||
for i, v := range temp {
|
||
c := v / PER_CARD_COLOR_MAX
|
||
if c == maxColor {
|
||
if i != n {
|
||
temp[n], temp[i] = temp[i], temp[n]
|
||
}
|
||
n++
|
||
if n == colorMap[maxColor] || n == 3 {
|
||
break
|
||
}
|
||
}
|
||
}
|
||
|
||
//6张牌中至少有2张牌的花色一样,所以最多更换一张牌的花色
|
||
if colorMap[maxColor] < 3 {
|
||
for i := colorMap[maxColor]; i < len(temp); i++ {
|
||
v := temp[i]
|
||
isNext := false
|
||
|
||
for j := 0; j < len(temp); j++ {
|
||
if j != i && v%PER_CARD_COLOR_MAX == temp[j]%PER_CARD_COLOR_MAX {
|
||
isNext = true
|
||
break
|
||
}
|
||
}
|
||
|
||
if !isNext {
|
||
temp[i] = temp[i]%PER_CARD_COLOR_MAX + maxColor*PER_CARD_COLOR_MAX
|
||
temp[colorMap[maxColor]], temp[i] = temp[i], temp[colorMap[maxColor]]
|
||
break
|
||
}
|
||
}
|
||
}
|
||
return temp
|
||
}
|
||
func CreateThreeSame(temp []int) []int {
|
||
valueMap := make(map[int]int)
|
||
valueArray := make([]int, 0)
|
||
sameCard := -1
|
||
for _, v := range temp {
|
||
c := v % PER_CARD_COLOR_MAX
|
||
valueMap[c] = valueMap[c] + 1
|
||
if valueMap[c] > valueMap[sameCard] {
|
||
sameCard = c
|
||
}
|
||
}
|
||
|
||
if valueMap[sameCard] > 1 {
|
||
//将相同的牌放最前边
|
||
n := 0
|
||
for i, v := range temp {
|
||
c := v % PER_CARD_COLOR_MAX
|
||
if c == sameCard {
|
||
valueArray = append(valueArray, v)
|
||
if i != n {
|
||
temp[n], temp[i] = temp[i], temp[n]
|
||
}
|
||
n++
|
||
if n == valueMap[sameCard] || n == 3 {
|
||
break
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if valueMap[sameCard] < 3 {
|
||
for i := valueMap[sameCard]; i < 3; i++ { //创造豹子
|
||
for j := 0; j < 4; j++ {
|
||
card := j*PER_CARD_COLOR_MAX + sameCard
|
||
if !common.InSliceInt(valueArray, card) {
|
||
temp[i] = card
|
||
valueArray = append(valueArray, card)
|
||
break
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return temp
|
||
}
|