Browse Source

cards combine optimize

master
tangmingyou 4 years ago
parent
commit
e17bbd3dc7
  1. 30
      cmd/main.go
  2. 5
      internal/game/actions.go
  3. 41
      internal/game/hand.go
  4. 22
      tool/collect/collect.go

30
cmd/main.go

@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"math/rand" "math/rand"
"texas-poker-bk/internal/conf" "texas-poker-bk/internal/conf"
"texas-poker-bk/internal/game"
"texas-poker-bk/internal/server" "texas-poker-bk/internal/server"
"time" "time"
) )
@ -21,32 +20,5 @@ func startServer() {
} }
func main() { func main() {
//startServer() startServer()
public := [5]*game.Card{
{Dot: game.Poker10, Suit: game.Club},
{Dot: game.Poker6, Suit: game.Spade},
{Dot: game.Poker7, Suit: game.Diamond},
{Dot: game.Poker5, Suit: game.Heart},
{Dot: game.PokerK, Suit: game.Diamond},
}
h1 := [2]*game.Card{
{Dot: game.PokerA, Suit: game.Spade},
{Dot: game.Poker5, Suit: game.Spade},
}
h2 := [2]*game.Card{
{Dot: game.Poker6, Suit: game.Club},
{Dot: game.Poker3, Suit: game.Diamond},
}
h3 := [2]*game.Card{
{Dot: game.Poker9, Suit: game.Club},
{Dot: game.Poker10, Suit: game.Heart},
}
hand1, err := game.AnalyzeMaxHand(h1, public)
hand2, err := game.AnalyzeMaxHand(h2, public)
hand3, err := game.AnalyzeMaxHand(h3, public)
fmt.Println(err, hand1)
fmt.Println(err, hand2)
fmt.Println(err, hand3)
} }

5
internal/game/actions.go

@ -38,7 +38,7 @@ func init() {
LimitedActions[1] = Call4Limited LimitedActions[1] = Call4Limited
LimitedActions[2] = Raise4Limited LimitedActions[2] = Raise4Limited
LimitedActions[3] = AllIn4Limited LimitedActions[3] = AllIn4Limited
LimitedActions[4] = Discard4Limited LimitedActions[4] = Fold4Limited
LimitedActions[5] = Check4Limited LimitedActions[5] = Check4Limited
LimitedBetting = &PlayerBetting{ LimitedBetting = &PlayerBetting{
betHandlers: LimitedActions, betHandlers: LimitedActions,
@ -113,7 +113,8 @@ func AllIn4Limited(player *Player, betChip int32) proto.Message {
return &api.ResFail{Msg: "限注牌桌不可AllIn"} return &api.ResFail{Msg: "限注牌桌不可AllIn"}
} }
func Discard4Limited(player *Player, betChip int32) proto.Message { // Fold4Limited 弃牌限注局
func Fold4Limited(player *Player, betChip int32) proto.Message {
table := player.GameTable table := player.GameTable
table.LastPosBetOp = 4 table.LastPosBetOp = 4
table.LastPosBetChip = 0 table.LastPosBetChip = 0

41
internal/game/hand.go

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"math" "math"
"strconv" "strconv"
"texas-poker-bk/tool/collect"
) )
// Hand 5张牌的牌型 // Hand 5张牌的牌型
@ -15,9 +16,10 @@ type Hand struct {
} }
func (h *Hand) Init(cards [5]*Card) *Hand { func (h *Hand) Init(cards [5]*Card) *Hand {
SortCards(&cards) // 5张牌点数大小排序
// 牌型排序降序 sortCards(&cards)
face := GetCardFace(&cards) // TODO 牌权重排序 // 计算点数相同牌组数,牌型权重降序
face := getCardFaceAndTidyCards(&cards)
// 计算牌型 // 计算牌型
switch true { switch true {
case isRoyalFlush(cards): case isRoyalFlush(cards):
@ -118,34 +120,21 @@ func AnalyzeMaxHand(handCards [2]*Card, publicCards [5]*Card) (*Hand, error) {
return new(Hand).Init(cards), nil return new(Hand).Init(cards), nil
} }
// 查找最大分数组合 // 查找最大分数组合
cardsLen := len(allCards)
tempCards := [5]*Card{} tempCards := [5]*Card{}
var maxHand *Hand var maxHand *Hand
// 遍历和公共牌的所有组合 // 遍历和公共牌的所有组合
for i := 0; i < cardsLen; i++ { collect.Combination(allCards, 5, func(temp []*Card) {
tempCards[0] = allCards[i] copy(tempCards[:], temp)
for j := i + 1; j < cardsLen; j++ { tempHand := new(Hand).Init(tempCards)
tempCards[1] = allCards[j] if maxHand == nil || tempHand.point > maxHand.point {
for k := j + 1; k < cardsLen; k++ { maxHand = tempHand
tempCards[2] = allCards[k]
for m := k + 1; m < cardsLen; m++ {
tempCards[3] = allCards[m]
for n := m + 1; n < cardsLen; n++ {
tempCards[4] = allCards[n]
tempHand := new(Hand).Init(tempCards)
if maxHand == nil || tempHand.point > maxHand.point {
maxHand = tempHand
}
}
}
}
} }
} })
return maxHand, nil return maxHand, nil
} }
// SortCards 5张牌降序排序 // sortCards 5张牌降序排序
func SortCards(cards *[5]*Card) { func sortCards(cards *[5]*Card) {
for i := 0; i < len(cards); i++ { for i := 0; i < len(cards); i++ {
for j := i + 1; j < len(cards); j++ { for j := i + 1; j < len(cards); j++ {
if cards[i].Compare(cards[j]) < 0 { if cards[i].Compare(cards[j]) < 0 {
@ -155,9 +144,9 @@ func SortCards(cards *[5]*Card) {
} }
} }
// GetCardFace 分析相同点数的牌个数 // getCardFaceAndTidyCards 分析相同点数的牌个数
// return 0:单牌个数 1:对子个数 2:三条个数 3四条个数 // return 0:单牌个数 1:对子个数 2:三条个数 3四条个数
func GetCardFace(cards *[5]*Card) [4]int { func getCardFaceAndTidyCards(cards *[5]*Card) [4]int {
var faceMap = make(map[PokerDot]int, 5) var faceMap = make(map[PokerDot]int, 5)
for _, c := range cards { for _, c := range cards {
faceMap[c.Dot]++ faceMap[c.Dot]++

22
tool/collect/collect.go

@ -75,3 +75,25 @@ func Max[T int32 | int64 | int](nums []T, dv T) T {
} }
return max return max
} }
// Combination 列出切片的所有count个元素组合情况
func Combination[T any](origin []T, count int, consumer func(once []T)) {
if count > len(origin) {
return
}
temp := make([]T, count)
combination0(origin, 0, count, temp, consumer)
}
// combination0
func combination0[T any](arr []T, start int, count int, temp []T, consumer func(once []T)) {
if count == 0 {
consumer(temp)
return
}
for i := start; i < len(arr); i++ {
temp[len(temp)-count] = arr[i] // 对于每个组合,按照索引大小,先取第一个,此时要取的个数减 1,
combination0(arr, i+1, count-1, temp, consumer)
}
}

Loading…
Cancel
Save