Initial commit
This commit is contained in:
@@ -0,0 +1 @@
|
||||
bazel*
|
||||
@@ -0,0 +1,150 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
pkg "mjhelper/pkg"
|
||||
|
||||
"github.com/mowshon/iterium"
|
||||
)
|
||||
|
||||
func allFans() []pkg.Fan {
|
||||
testFans := []pkg.Fan{
|
||||
{Id: 1, Name: "大四喜", Pattern: pkg.PatternDivision{Ke: 4, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{38, 49, 62, 63}, Value: 88},
|
||||
{Id: 2, Name: "大三元", Pattern: pkg.PatternDivision{Ke: 3, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 88},
|
||||
{Id: 3, Name: "绿一色", Pattern: pkg.PatternDivision{Ke: 4, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 88},
|
||||
{Id: 4, Name: "九莲宝灯", Pattern: pkg.PatternDivision{Ke: 2, Shun: 0, Dui: 0, Gang: 0}, ExcludeIds: []int{}, Value: 88},
|
||||
{Id: 5, Name: "四杠", Pattern: pkg.PatternDivision{Ke: 4, Shun: 0, Dui: 1, Gang: 4}, ExcludeIds: []int{}, Value: 88},
|
||||
{Id: 6, Name: "连七对", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 7, Gang: 0}, ExcludeIds: []int{}, Value: 88},
|
||||
{Id: 7, Name: "十三幺", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 88},
|
||||
{Id: 8, Name: "清幺九", Pattern: pkg.PatternDivision{Ke: 4, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 64},
|
||||
{Id: 9, Name: "小四喜", Pattern: pkg.PatternDivision{Ke: 3, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 64},
|
||||
{Id: 10, Name: "小三元", Pattern: pkg.PatternDivision{Ke: 2, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 64},
|
||||
{Id: 11, Name: "字一色", Pattern: pkg.PatternDivision{Ke: 4, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 64},
|
||||
{Id: 12, Name: "四暗刻", Pattern: pkg.PatternDivision{Ke: 4, Shun: 0, Dui: 2, Gang: 0}, ExcludeIds: []int{}, Value: 64},
|
||||
{Id: 13, Name: "一色双龙会", Pattern: pkg.PatternDivision{Ke: 0, Shun: 4, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 64},
|
||||
{Id: 14, Name: "一色四同顺", Pattern: pkg.PatternDivision{Ke: 0, Shun: 4, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 48},
|
||||
{Id: 15, Name: "一色四节高", Pattern: pkg.PatternDivision{Ke: 4, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 48},
|
||||
{Id: 16, Name: "一色四步高", Pattern: pkg.PatternDivision{Ke: 0, Shun: 4, Dui: 2, Gang: 0}, ExcludeIds: []int{}, Value: 32},
|
||||
{Id: 17, Name: "三杠", Pattern: pkg.PatternDivision{Ke: 3, Shun: 0, Dui: 1, Gang: 3}, ExcludeIds: []int{}, Value: 32},
|
||||
{Id: 18, Name: "混幺九", Pattern: pkg.PatternDivision{Ke: 4, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 32},
|
||||
{Id: 19, Name: "七对", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 7, Gang: 0}, ExcludeIds: []int{}, Value: 24},
|
||||
{Id: 20, Name: "七星不靠", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 0, Gang: 0}, ExcludeIds: []int{}, Value: 24},
|
||||
{Id: 21, Name: "全双刻", Pattern: pkg.PatternDivision{Ke: 4, Shun: 0, Dui: 2, Gang: 0}, ExcludeIds: []int{}, Value: 24},
|
||||
{Id: 22, Name: "清一色", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 24},
|
||||
{Id: 23, Name: "一色三同顺", Pattern: pkg.PatternDivision{Ke: 0, Shun: 3, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 24},
|
||||
{Id: 24, Name: "一色三节高", Pattern: pkg.PatternDivision{Ke: 3, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 24},
|
||||
{Id: 25, Name: "全大", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 24},
|
||||
{Id: 26, Name: "全中", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 24},
|
||||
{Id: 27, Name: "全小", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 24},
|
||||
{Id: 28, Name: "清龙", Pattern: pkg.PatternDivision{Ke: 3, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 16},
|
||||
{Id: 29, Name: "三色双龙会", Pattern: pkg.PatternDivision{Ke: 4, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 16},
|
||||
{Id: 30, Name: "一色三步高", Pattern: pkg.PatternDivision{Ke: 3, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 16},
|
||||
{Id: 31, Name: "全带五", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 16},
|
||||
{Id: 32, Name: "三同刻", Pattern: pkg.PatternDivision{Ke: 3, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 16},
|
||||
{Id: 33, Name: "三暗刻", Pattern: pkg.PatternDivision{Ke: 3, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 16},
|
||||
{Id: 34, Name: "全不靠", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 0, Gang: 0}, ExcludeIds: []int{}, Value: 12},
|
||||
{Id: 35, Name: "组合龙", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 12},
|
||||
{Id: 36, Name: "大于五", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 12},
|
||||
{Id: 37, Name: "小于五", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 12},
|
||||
{Id: 38, Name: "三风刻", Pattern: pkg.PatternDivision{Ke: 3, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 12},
|
||||
{Id: 39, Name: "花龙", Pattern: pkg.PatternDivision{Ke: 3, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 8},
|
||||
{Id: 40, Name: "推不倒", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 8},
|
||||
{Id: 41, Name: "三色三同顺", Pattern: pkg.PatternDivision{Ke: 0, Shun: 3, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 8},
|
||||
{Id: 42, Name: "三色三节高", Pattern: pkg.PatternDivision{Ke: 3, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 8},
|
||||
{Id: 43, Name: "无番和", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 8},
|
||||
{Id: 44, Name: "妙手回春", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 0, Gang: 0}, ExcludeIds: []int{}, Value: 8},
|
||||
{Id: 45, Name: "海底捞月", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 0, Gang: 0}, ExcludeIds: []int{}, Value: 8},
|
||||
{Id: 46, Name: "杠上开花", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 0, Gang: 1}, ExcludeIds: []int{}, Value: 8},
|
||||
{Id: 47, Name: "抢杠和", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 0, Gang: 0}, ExcludeIds: []int{}, Value: 8},
|
||||
// 双暗杠 98版计6番,06版计8番
|
||||
{Id: 48, Name: "双暗杠", Pattern: pkg.PatternDivision{Ke: 3, Shun: 0, Dui: 1, Gang: 2}, ExcludeIds: []int{}, Value: 6},
|
||||
{Id: 49, Name: "碰碰和", Pattern: pkg.PatternDivision{Ke: 4, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 6},
|
||||
{Id: 50, Name: "混一色", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 6},
|
||||
{Id: 51, Name: "三色三步高", Pattern: pkg.PatternDivision{Ke: 0, Shun: 3, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 6},
|
||||
{Id: 52, Name: "三色三节高", Pattern: pkg.PatternDivision{Ke: 3, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 6},
|
||||
{Id: 53, Name: "五门齐", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 6},
|
||||
{Id: 54, Name: "全求人", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 0, Gang: 0}, ExcludeIds: []int{}, Value: 6},
|
||||
// 明暗杠 06版计6番,存疑
|
||||
{Id: 55, Name: "明暗杠", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 0, Gang: 0}, ExcludeIds: []int{}, Value: 6},
|
||||
{Id: 56, Name: "双箭刻", Pattern: pkg.PatternDivision{Ke: 2, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 6},
|
||||
{Id: 57, Name: "全带幺", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 4},
|
||||
{Id: 58, Name: "不求人", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 0, Gang: 0}, ExcludeIds: []int{}, Value: 4},
|
||||
{Id: 59, Name: "双明杠", Pattern: pkg.PatternDivision{Ke: 2, Shun: 0, Dui: 1, Gang: 2}, ExcludeIds: []int{}, Value: 4},
|
||||
{Id: 60, Name: "和绝张", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 0, Gang: 0}, ExcludeIds: []int{}, Value: 4},
|
||||
{Id: 61, Name: "箭刻", Pattern: pkg.PatternDivision{Ke: 1, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 2},
|
||||
{Id: 62, Name: "圈风刻", Pattern: pkg.PatternDivision{Ke: 1, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 2},
|
||||
{Id: 63, Name: "门风刻", Pattern: pkg.PatternDivision{Ke: 1, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 2},
|
||||
{Id: 64, Name: "门前清", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 0, Gang: 0}, ExcludeIds: []int{}, Value: 2},
|
||||
{Id: 65, Name: "平和", Pattern: pkg.PatternDivision{Ke: 0, Shun: 4, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 2},
|
||||
{Id: 66, Name: "四归一", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 0, Gang: 0}, ExcludeIds: []int{}, Value: 2},
|
||||
{Id: 67, Name: "双同刻", Pattern: pkg.PatternDivision{Ke: 2, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 2},
|
||||
{Id: 68, Name: "双暗刻", Pattern: pkg.PatternDivision{Ke: 2, Shun: 0, Dui: 0, Gang: 0}, ExcludeIds: []int{}, Value: 2},
|
||||
{Id: 69, Name: "暗杠", Pattern: pkg.PatternDivision{Ke: 1, Shun: 0, Dui: 1, Gang: 1}, ExcludeIds: []int{}, Value: 2},
|
||||
{Id: 70, Name: "断幺", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 0, Gang: 0}, ExcludeIds: []int{}, Value: 2},
|
||||
{Id: 71, Name: "一般高", Pattern: pkg.PatternDivision{Ke: 0, Shun: 2, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 1},
|
||||
{Id: 72, Name: "喜相逢", Pattern: pkg.PatternDivision{Ke: 0, Shun: 2, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 1},
|
||||
{Id: 73, Name: "连六", Pattern: pkg.PatternDivision{Ke: 0, Shun: 2, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 1},
|
||||
{Id: 74, Name: "老少副", Pattern: pkg.PatternDivision{Ke: 0, Shun: 2, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 1},
|
||||
{Id: 75, Name: "幺九刻", Pattern: pkg.PatternDivision{Ke: 1, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 1},
|
||||
{Id: 76, Name: "明杠", Pattern: pkg.PatternDivision{Ke: 1, Shun: 0, Dui: 0, Gang: 1}, ExcludeIds: []int{}, Value: 1},
|
||||
{Id: 77, Name: "缺一门", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 0, Gang: 0}, ExcludeIds: []int{}, Value: 1},
|
||||
{Id: 78, Name: "无字", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 0, Gang: 0}, ExcludeIds: []int{}, Value: 1},
|
||||
{Id: 79, Name: "边张", Pattern: pkg.PatternDivision{Ke: 0, Shun: 1, Dui: 0, Gang: 0}, ExcludeIds: []int{}, Value: 1},
|
||||
{Id: 80, Name: "坎张", Pattern: pkg.PatternDivision{Ke: 0, Shun: 1, Dui: 0, Gang: 0}, ExcludeIds: []int{}, Value: 1},
|
||||
{Id: 81, Name: "单钓将", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{}, Value: 1},
|
||||
{Id: 82, Name: "自摸", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 0, Gang: 0}, ExcludeIds: []int{}, Value: 1},
|
||||
{Id: 82, Name: "花牌", Pattern: pkg.PatternDivision{Ke: 0, Shun: 0, Dui: 0, Gang: 0}, ExcludeIds: []int{}, Value: 1},
|
||||
}
|
||||
return testFans
|
||||
}
|
||||
|
||||
func AllFansToFile() {
|
||||
allFans := allFans()
|
||||
pkg.FansToFile(allFans, "test.json")
|
||||
}
|
||||
|
||||
func GenerateFan(fan pkg.Fan) {
|
||||
|
||||
}
|
||||
|
||||
func GenerateKe() {
|
||||
|
||||
}
|
||||
|
||||
func main() {
|
||||
result := iterium.Combinations([]string{
|
||||
"1W", "2W", "3W", "4W", "5W", "6W", "7W", "8W", "9W",
|
||||
"1T", "2T", "3T", "4T", "5T", "6T", "7T", "8T", "9T",
|
||||
"1B", "2B", "3B", "4B", "5B", "6B", "7B", "8B", "9B",
|
||||
"DO", "XI", "NA", "BE", "ZH", "FA", "BA",
|
||||
"1W", "2W", "3W", "4W", "5W", "6W", "7W", "8W", "9W",
|
||||
"1T", "2T", "3T", "4T", "5T", "6T", "7T", "8T", "9T",
|
||||
"1B", "2B", "3B", "4B", "5B", "6B", "7B", "8B", "9B",
|
||||
"DO", "XI", "NA", "BE", "ZH", "FA", "BA",
|
||||
"1W", "2W", "3W", "4W", "5W", "6W", "7W", "8W", "9W",
|
||||
"1T", "2T", "3T", "4T", "5T", "6T", "7T", "8T", "9T",
|
||||
"1B", "2B", "3B", "4B", "5B", "6B", "7B", "8B", "9B",
|
||||
"DO", "XI", "NA", "BE", "ZH", "FA", "BA",
|
||||
"1W", "2W", "3W", "4W", "5W", "6W", "7W", "8W", "9W",
|
||||
"1T", "2T", "3T", "4T", "5T", "6T", "7T", "8T", "9T",
|
||||
"1B", "2B", "3B", "4B", "5B", "6B", "7B", "8B", "9B",
|
||||
"DO", "XI", "NA", "BE", "ZH", "FA", "BA"}, 14)
|
||||
fmt.Println(result.Count())
|
||||
result2_1 := iterium.CombinationsWithReplacement([]string{
|
||||
"1TS", "2TS", "3TS", "4TS", "5TS", "6TS", "7TS",
|
||||
"1TK", "2TK", "3TK", "4TK", "5TK", "6TK", "7TK", "8TK", "9TK",
|
||||
"1TS", "2TS", "3TS", "4TS", "5TS", "6TS", "7TS",
|
||||
"1TK", "2TK", "3TK", "4TK", "5TK", "6TK", "7TK", "8TK", "9TK",
|
||||
"1TS", "2TS", "3TS", "4TS", "5TS", "6TS", "7TS",
|
||||
"1TK", "2TK", "3TK", "4TK", "5TK", "6TK", "7TK", "8TK", "9TK",
|
||||
"DOK", "XIK", "NAK", "BEK", "ZHK", "FAK", "BAK"}, 4)
|
||||
result2_2 := iterium.Combinations([]string{
|
||||
"1W", "2W", "3W", "4W", "5W", "6W", "7W", "8W", "9W",
|
||||
"1T", "2T", "3T", "4T", "5T", "6T", "7T", "8T", "9T",
|
||||
"1B", "2B", "3B", "4B", "5B", "6B", "7B", "8B", "9B",
|
||||
"DO", "XI", "NA", "BE", "ZH", "FA", "BA"}, 1)
|
||||
fmt.Println(result2_1.Count() * result2_2.Count())
|
||||
for i := range result2_1.Chan() {
|
||||
fmt.Println(i)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
module mjhelper
|
||||
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/mowshon/iterium v1.0.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230307190834-24139beb5833 // indirect
|
||||
)
|
||||
@@ -0,0 +1,4 @@
|
||||
github.com/mowshon/iterium v1.0.0 h1:04pku9dTNnfVvshf+DQIV3E92T/EwmnXKtXMkmZ3+5Q=
|
||||
github.com/mowshon/iterium v1.0.0/go.mod h1:Bnchn9HAYNQ/7MLUwKDyvjduSuVJQQwrNxmXJDqpXg4=
|
||||
golang.org/x/exp v0.0.0-20230307190834-24139beb5833 h1:SChBja7BCQewoTAU7IgvucQKMIXrEpFxNMs0spT3/5s=
|
||||
golang.org/x/exp v0.0.0-20230307190834-24139beb5833/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package pkg
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
type PatternDivision struct {
|
||||
Ke int
|
||||
Shun int
|
||||
Dui int
|
||||
Gang int
|
||||
}
|
||||
type Fan struct {
|
||||
Id int
|
||||
Name string
|
||||
Pattern PatternDivision
|
||||
ExcludeIds []int
|
||||
Value int
|
||||
}
|
||||
|
||||
func FansEncoder(fans []Fan) ([]byte, error) {
|
||||
return json.MarshalIndent(fans, "", " ")
|
||||
}
|
||||
|
||||
func FansDecoder(bytedata []byte) ([]Fan, error) {
|
||||
var fans []Fan
|
||||
err := json.Unmarshal(bytedata, &fans)
|
||||
return fans, err
|
||||
}
|
||||
|
||||
func FansToFile(fans []Fan, filepath string) error {
|
||||
jsonBytes, err := FansEncoder(fans)
|
||||
if err != nil {
|
||||
log.Fatalf("Can't encode fan xing: %v", err)
|
||||
return err
|
||||
}
|
||||
err = os.WriteFile(filepath, jsonBytes, 0644)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to write fan xing into a file(%s): %v", filepath, err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func DivisionHelperOnNumbers(tiles [9]int) {
|
||||
|
||||
}
|
||||
func HandPatternDivide() {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package pkg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFanEncoder(t *testing.T) {
|
||||
testFans := []Fan{
|
||||
{Id: 1, Name: "大四喜", Pattern: PatternDivision{Ke: 4, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{12}, Value: 88},
|
||||
{Id: 2, Name: "七对", Pattern: PatternDivision{Ke: 0, Shun: 0, Dui: 7, Gang: 0}, ExcludeIds: []int{12}, Value: 24},
|
||||
}
|
||||
data, err := FansEncoder(testFans)
|
||||
if err != nil {
|
||||
log.Fatalf("Can't encode fan xing: %v", err)
|
||||
return
|
||||
}
|
||||
fmt.Println(data)
|
||||
}
|
||||
|
||||
func TestFanDecoder(t *testing.T) {
|
||||
testFans := []Fan{
|
||||
{Id: 1, Name: "大四喜", Pattern: PatternDivision{Ke: 4, Shun: 0, Dui: 1, Gang: 0}, ExcludeIds: []int{12}, Value: 88},
|
||||
{Id: 2, Name: "七对", Pattern: PatternDivision{Ke: 0, Shun: 0, Dui: 7, Gang: 0}, ExcludeIds: []int{12}, Value: 24},
|
||||
}
|
||||
jsonBytes, err := FansEncoder(testFans)
|
||||
if err != nil {
|
||||
log.Fatalf("Can't encode fan xing, cancel decoding test: %v", err)
|
||||
return
|
||||
}
|
||||
fans, err := FansDecoder(jsonBytes)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed decoding byte stream of fan xing: %v", err)
|
||||
return
|
||||
}
|
||||
fmt.Println(fans)
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package pkg
|
||||
|
||||
import "errors"
|
||||
|
||||
var NumberToHanZiTable = []string{"一", "二", "三", "四", "五", "六", "七", "八", "九"}
|
||||
var StyleToHanZiTable = []string{"序数牌", "风牌", "箭牌", "花牌"}
|
||||
var XuStyleToHanZiTable = []string{"万", "条", "饼"}
|
||||
|
||||
func NumberToHanzi(num uint) (string, error) {
|
||||
if num >= uint(len(NumberToHanZiTable)) {
|
||||
return "", errors.New("not a valid number")
|
||||
}
|
||||
return NumberToHanZiTable[num-1], nil
|
||||
}
|
||||
|
||||
func StyleToHanZi(num uint) (string, error) {
|
||||
if num >= uint(len(StyleToHanZiTable)) {
|
||||
return "", errors.New("not a valid number")
|
||||
}
|
||||
return StyleToHanZiTable[num], nil
|
||||
}
|
||||
|
||||
func XuStyleToHanZi(num uint) (string, error) {
|
||||
if num >= uint(len(XuStyleToHanZiTable)) {
|
||||
return "", errors.New("not a valid number")
|
||||
}
|
||||
return XuStyleToHanZiTable[num], nil
|
||||
}
|
||||
+261
@@ -0,0 +1,261 @@
|
||||
package pkg
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"reflect"
|
||||
"sort"
|
||||
)
|
||||
|
||||
const (
|
||||
// 未出场
|
||||
tl_notshow = 0
|
||||
// 本家状态
|
||||
tl_mhand = 1
|
||||
tl_mshow = 2
|
||||
tl_mdisc = 3
|
||||
// 下家状态
|
||||
tl_nhand = 4
|
||||
tl_nshow = 5
|
||||
tl_ndisc = 6
|
||||
// 对家状态
|
||||
tl_ohand = 7
|
||||
tl_oshow = 8
|
||||
tl_odisc = 9
|
||||
// 上家状态
|
||||
tl_phand = 10
|
||||
tl_pshow = 11
|
||||
tl_pdisc = 12
|
||||
)
|
||||
|
||||
var tileTypes = [34]string{
|
||||
"1W", "2W", "3W", "4W", "5W", "6W", "7W", "8W", "9W",
|
||||
"1T", "2T", "3T", "4T", "5T", "6T", "7T", "8T", "9T",
|
||||
"1B", "2B", "3B", "4B", "5B", "6B", "7B", "8B", "9B",
|
||||
"DO", "XI", "NA", "BE", "ZH", "FA", "BA"}
|
||||
var tileHuaTypes = [8]string{"ME", "LA", "ZU", "JU", "CH", "XA", "QI", "DN"}
|
||||
|
||||
type environment struct {
|
||||
board [4][34]int
|
||||
}
|
||||
|
||||
func (e environment) Print() {
|
||||
for i := 0; i < len(e.board)+1; i++ {
|
||||
for j := 0; j < len(e.board[0]); j++ {
|
||||
if i == 0 {
|
||||
fmt.Printf("|% 3s", tileTypes[j])
|
||||
} else {
|
||||
fmt.Printf("|% 3d", e.board[i-1][j])
|
||||
}
|
||||
}
|
||||
fmt.Printf("|\n")
|
||||
}
|
||||
}
|
||||
|
||||
func (e environment) PatternNormalization() [3][34]int {
|
||||
var ret [3][34]int
|
||||
for i := 0; i < len(e.board[0]); i++ {
|
||||
hand := 0
|
||||
disc := 0
|
||||
noshow := 0
|
||||
for j := 0; j < len(e.board); j++ {
|
||||
switch e.board[j][i] {
|
||||
case tl_mhand, tl_mshow:
|
||||
hand += 1
|
||||
case tl_mdisc, tl_ndisc, tl_nshow, tl_odisc, tl_oshow, tl_pdisc, tl_pshow:
|
||||
disc += 1
|
||||
case tl_notshow:
|
||||
noshow += 1
|
||||
}
|
||||
}
|
||||
ret[0][i] = hand
|
||||
ret[1][i] = disc
|
||||
ret[2][i] = noshow
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func TileComparator(i, j string) (bool, error) {
|
||||
if i == j {
|
||||
return false, nil
|
||||
}
|
||||
ii, ij := -1, -1
|
||||
for k, v := range tileTypes {
|
||||
if i == v {
|
||||
ii = k
|
||||
}
|
||||
if j == v {
|
||||
ij = k
|
||||
}
|
||||
}
|
||||
if ii == -1 || ij == -1 {
|
||||
return false, errors.New("can't find tile by name")
|
||||
}
|
||||
return ii < ij, nil
|
||||
}
|
||||
|
||||
func Sort(tiles []string) error {
|
||||
sort.Slice(tiles, func(i, j int) bool {
|
||||
res, err := TileComparator(tiles[i], tiles[j])
|
||||
if err != nil {
|
||||
log.Fatalf("Sort tiles has error: %v", err)
|
||||
}
|
||||
return res
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check
|
||||
func CheckXushuHelper(tiles [9]int, index int, allCombs [][]int, combTable *[][][]int) {
|
||||
if index >= 9 {
|
||||
// Check invalid shun/ke/gang with more than 1 pair
|
||||
gangAmount := 0
|
||||
shunKeAmount := 0
|
||||
pairAmount := 0
|
||||
for _, combs := range allCombs {
|
||||
if len(combs) == 2 {
|
||||
pairAmount++
|
||||
}
|
||||
if len(combs) == 3 {
|
||||
shunKeAmount++
|
||||
}
|
||||
if len(combs) == 4 {
|
||||
gangAmount++
|
||||
}
|
||||
}
|
||||
if pairAmount > 1 && (gangAmount > 0 || shunKeAmount > 0) {
|
||||
return
|
||||
}
|
||||
*combTable = append(*combTable, allCombs)
|
||||
return
|
||||
}
|
||||
if tiles[index] == 0 {
|
||||
CheckXushuHelper(tiles, index+1, allCombs, combTable)
|
||||
return
|
||||
}
|
||||
if tiles[index] == 4 {
|
||||
tiles[index] = 0
|
||||
CheckXushuHelper(tiles, index+1, append(allCombs, []int{index, index, index, index}), combTable)
|
||||
if index < 7 {
|
||||
if tiles[index+1] > 0 && tiles[index+2] > 0 {
|
||||
tiles[index] = 3
|
||||
tiles[index+1] -= 1
|
||||
tiles[index+2] -= 1
|
||||
CheckXushuHelper(tiles, index, append(allCombs, []int{index, index + 1, index + 2}), combTable)
|
||||
tiles[index+1] += 1
|
||||
tiles[index+2] += 1
|
||||
}
|
||||
}
|
||||
tiles[index] = 2
|
||||
CheckXushuHelper(tiles, index, append(allCombs, []int{index, index}), combTable)
|
||||
} else if tiles[index] == 3 {
|
||||
tiles[index] = 0
|
||||
CheckXushuHelper(tiles, index+1, append(allCombs, []int{index, index, index}), combTable)
|
||||
if index < 7 {
|
||||
if tiles[index+1] > 0 && tiles[index+2] > 0 {
|
||||
tiles[index] = 2
|
||||
tiles[index+1] -= 1
|
||||
tiles[index+2] -= 1
|
||||
CheckXushuHelper(tiles, index, append(allCombs, []int{index, index + 1, index + 2}), combTable)
|
||||
tiles[index+1] += 1
|
||||
tiles[index+2] += 1
|
||||
}
|
||||
}
|
||||
} else if tiles[index] == 2 {
|
||||
tiles[index] = 0
|
||||
CheckXushuHelper(tiles, index+1, append(allCombs, []int{index, index}), combTable)
|
||||
if index < 7 {
|
||||
if tiles[index+1] > 0 && tiles[index+2] > 0 {
|
||||
tiles[index] = 1
|
||||
tiles[index+1] -= 1
|
||||
tiles[index+2] -= 1
|
||||
CheckXushuHelper(tiles, index, append(allCombs, []int{index, index + 1, index + 2}), combTable)
|
||||
tiles[index+1] += 1
|
||||
tiles[index+2] += 1
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if index < 7 {
|
||||
if tiles[index+1] > 0 && tiles[index+2] > 0 {
|
||||
tiles[index] = 0
|
||||
tiles[index+1] -= 1
|
||||
tiles[index+2] -= 1
|
||||
CheckXushuHelper(tiles, index+1, append(allCombs, []int{index, index + 1, index + 2}), combTable)
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func CheckXushuTile(tiles []string) ([][][]string, error) {
|
||||
limit := len(tiles)
|
||||
if limit <= 0 {
|
||||
return [][][]string{}, nil
|
||||
}
|
||||
var combTable [][][]int
|
||||
if limit <= 3 {
|
||||
var tileNumbers []int
|
||||
for _, tile := range tiles {
|
||||
tileNumbers = append(tileNumbers, int(tile[0])-48)
|
||||
}
|
||||
// bukao
|
||||
isBukao := true
|
||||
for _, num := range tileNumbers[1:] {
|
||||
if ((num - tileNumbers[0]) != 3) && ((num - tileNumbers[0]) != 6) {
|
||||
isBukao = false
|
||||
}
|
||||
}
|
||||
// isbukao + shisanyao
|
||||
if isBukao || reflect.DeepEqual(tileNumbers, []int{1, 9}) || reflect.DeepEqual(tileNumbers, []int{1, 1, 9}) || reflect.DeepEqual(tileNumbers, []int{1, 9, 9}) {
|
||||
var tmpAllCombs [][]int
|
||||
for _, tile := range tiles {
|
||||
tmpAllCombs = append(tmpAllCombs, []int{int(tile[0]) - 49})
|
||||
}
|
||||
combTable = append(combTable, tmpAllCombs)
|
||||
}
|
||||
}
|
||||
var flatTileVector [9]int
|
||||
for _, tile := range tiles {
|
||||
flatTileVector[int(tile[0])-49] += 1
|
||||
}
|
||||
CheckXushuHelper(flatTileVector, 0, [][]int{}, &combTable)
|
||||
|
||||
if len(combTable) <= 0 {
|
||||
return [][][]string{}, fmt.Errorf("tiles are not empty, but can't generate a valid pattern(%v)", tiles)
|
||||
}
|
||||
|
||||
strColor := tiles[0][1]
|
||||
var readableResult [][][]string
|
||||
for _, combs := range combTable {
|
||||
readableCombs := [][]string{}
|
||||
for _, comb := range combs {
|
||||
readableComb := []string{}
|
||||
for _, tile := range comb {
|
||||
readableComb = append(readableComb, fmt.Sprintf("%d%c", tile+1, strColor))
|
||||
}
|
||||
readableCombs = append(readableCombs, readableComb)
|
||||
}
|
||||
readableResult = append(readableResult, readableCombs)
|
||||
}
|
||||
return readableResult, nil
|
||||
}
|
||||
|
||||
func TilesDividedToPatterns(tiles []string) error {
|
||||
Sort(tiles)
|
||||
var wan, tiao, bing, zi []string
|
||||
for _, tile := range tiles {
|
||||
switch tile[1] {
|
||||
case 'W':
|
||||
wan = append(wan, tile)
|
||||
case 'T':
|
||||
tiao = append(tiao, tile)
|
||||
case 'B':
|
||||
bing = append(bing, tile)
|
||||
default:
|
||||
zi = append(zi, tile)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package pkg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPrint(t *testing.T) {
|
||||
var env environment
|
||||
env.Print()
|
||||
}
|
||||
|
||||
func TestPatternNormalization(t *testing.T) {
|
||||
var env environment
|
||||
handTiles := env.PatternNormalization()
|
||||
fmt.Println(handTiles)
|
||||
}
|
||||
|
||||
func TestTileComparator(t *testing.T) {
|
||||
type testcase struct {
|
||||
Args [2]string
|
||||
Expected bool
|
||||
}
|
||||
testcases := []testcase{
|
||||
{Args: [2]string{"1W", "6W"}, Expected: true},
|
||||
{Args: [2]string{"9W", "1B"}, Expected: true},
|
||||
{Args: [2]string{"4W", "BA"}, Expected: true},
|
||||
{Args: [2]string{"BE", "NA"}, Expected: false},
|
||||
}
|
||||
for _, v := range testcases {
|
||||
result, err := TileComparator(v.Args[0], v.Args[1])
|
||||
if err != nil {
|
||||
log.Fatalf("Failed in comparing tiles: %v", err)
|
||||
}
|
||||
if result != v.Expected {
|
||||
log.Fatalf("Failed in comparing tiles %s vs %s, expectd: %t, got %t", v.Args[0], v.Args[1], v.Expected, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSort(t *testing.T) {
|
||||
type testcase struct {
|
||||
Args []string
|
||||
Expected []string
|
||||
}
|
||||
testcases := []testcase{
|
||||
{Args: []string{"7B", "4T", "2T", "3W", "5W", "4W", "BA", "DO"}, Expected: []string{"3W", "4W", "5W", "2T", "4T", "7B", "DO", "BA"}},
|
||||
{Args: []string{"8B", "8B", "7B", "6B", "5W", "4W", "4W", "4W"}, Expected: []string{"4W", "4W", "4W", "5W", "6B", "7B", "8B", "8B"}},
|
||||
{Args: []string{"BA", "BA", "BA", "BA", "XI", "XI", "XI", "NA"}, Expected: []string{"XI", "XI", "XI", "NA", "BA", "BA", "BA", "BA"}},
|
||||
}
|
||||
for _, v := range testcases {
|
||||
err := Sort(v.Args)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed in sorting tiles: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(v.Args, v.Expected) {
|
||||
log.Fatalf("Failed in sorting tiles expectd: %v, got %v", v.Expected, v.Args)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckXushuTile(t *testing.T) {
|
||||
type testcase struct {
|
||||
Args []string
|
||||
Expected [][][]string
|
||||
}
|
||||
testcases := []testcase{
|
||||
{Args: []string{}, Expected: [][][]string{}},
|
||||
{Args: []string{"4W", "4W"}, Expected: [][][]string{{{"4W", "4W"}}}},
|
||||
{Args: []string{"4W", "4W", "4W", "4W"}, Expected: [][][]string{{{"4W", "4W", "4W", "4W"}}, {{"4W", "4W"}, {"4W", "4W"}}}},
|
||||
{Args: []string{"2W", "3W", "3W", "4W", "4W", "4W", "5W", "5W", "6W"}, Expected: [][][]string{{{"2W", "3W", "4W"}, {"3W", "4W", "5W"}, {"4W", "5W", "6W"}}}},
|
||||
{Args: []string{"2W", "3W", "3W", "4W", "4W", "4W", "5W", "5W", "5W", "5W", "6W"}, Expected: [][][]string{{{"2W", "3W", "4W"}, {"3W", "4W", "5W"}, {"4W", "5W", "6W"}, {"5W", "5W"}}}},
|
||||
{Args: []string{"3W", "3W", "3W", "4W", "4W", "4W", "5W", "5W", "5W"}, Expected: [][][]string{{{"3W", "3W", "3W"}, {"4W", "4W", "4W"}, {"5W", "5W", "5W"}}, {{"3W", "4W", "5W"}, {"3W", "4W", "5W"}, {"3W", "4W", "5W"}}}},
|
||||
{Args: []string{"3W", "3W", "3W", "3W", "4W", "4W", "4W", "4W", "5W", "5W", "5W", "5W"}, Expected: [][][]string{{{"3W", "3W", "3W", "3W"}, {"4W", "4W", "4W", "4W"}, {"5W", "5W", "5W", "5W"}}, {{"3W", "4W", "5W"}, {"3W", "3W", "3W"}, {"4W", "4W", "4W"}, {"5W", "5W", "5W"}}, {{"3W", "4W", "5W"}, {"3W", "4W", "5W"}, {"3W", "4W", "5W"}, {"3W", "4W", "5W"}}, {{"3W", "3W"}, {"3W", "3W"}, {"4W", "4W"}, {"4W", "4W"}, {"5W", "5W"}, {"5W", "5W"}}}},
|
||||
{Args: []string{"1W", "4W", "7W"}, Expected: [][][]string{{{"1W"}, {"4W"}, {"7W"}}}},
|
||||
{Args: []string{"4W", "7W"}, Expected: [][][]string{{{"4W"}, {"7W"}}}},
|
||||
{Args: []string{"1W", "4W"}, Expected: [][][]string{{{"1W"}, {"4W"}}}},
|
||||
{Args: []string{"1W", "7W"}, Expected: [][][]string{{{"1W"}, {"7W"}}}},
|
||||
{Args: []string{"1W", "1W", "9W"}, Expected: [][][]string{{{"1W"}, {"1W"}, {"9W"}}}},
|
||||
{Args: []string{"1W", "9W", "9W"}, Expected: [][][]string{{{"1W"}, {"9W"}, {"9W"}}}},
|
||||
{Args: []string{"1W", "9W"}, Expected: [][][]string{{{"1W"}, {"9W"}}}},
|
||||
{Args: []string{"1W", "3W", "5W"}, Expected: [][][]string{}},
|
||||
}
|
||||
for _, v := range testcases {
|
||||
result, err := CheckXushuTile(v.Args)
|
||||
if err != nil {
|
||||
log.Printf("Failed in dividing tiles: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(result, v.Expected) {
|
||||
log.Fatalf("Failed in dividing tiles expectd: %v, got %v", v.Expected, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
# A Majiang helper
|
||||
|
||||
## Dev diary
|
||||
|
||||
S1: A helper to analysis the best way to achieve hu
|
||||
S1.1: Without
|
||||
@@ -0,0 +1,182 @@
|
||||
[
|
||||
{
|
||||
"Id": 1,
|
||||
"Name": "大四喜",
|
||||
"Pattern": {
|
||||
"Ke": 4,
|
||||
"Shun": 0,
|
||||
"Dui": 1,
|
||||
"Gang": 0
|
||||
},
|
||||
"ExcludeIds": [],
|
||||
"Value": 88
|
||||
},
|
||||
{
|
||||
"Id": 2,
|
||||
"Name": "大三元",
|
||||
"Pattern": {
|
||||
"Ke": 3,
|
||||
"Shun": 0,
|
||||
"Dui": 1,
|
||||
"Gang": 0
|
||||
},
|
||||
"ExcludeIds": [],
|
||||
"Value": 88
|
||||
},
|
||||
{
|
||||
"Id": 3,
|
||||
"Name": "绿一色",
|
||||
"Pattern": {
|
||||
"Ke": 4,
|
||||
"Shun": 0,
|
||||
"Dui": 1,
|
||||
"Gang": 0
|
||||
},
|
||||
"ExcludeIds": [],
|
||||
"Value": 88
|
||||
},
|
||||
{
|
||||
"Id": 4,
|
||||
"Name": "九莲宝灯",
|
||||
"Pattern": {
|
||||
"Ke": 2,
|
||||
"Shun": 0,
|
||||
"Dui": 0,
|
||||
"Gang": 0
|
||||
},
|
||||
"ExcludeIds": [],
|
||||
"Value": 88
|
||||
},
|
||||
{
|
||||
"Id": 5,
|
||||
"Name": "四杠",
|
||||
"Pattern": {
|
||||
"Ke": 4,
|
||||
"Shun": 0,
|
||||
"Dui": 1,
|
||||
"Gang": 4
|
||||
},
|
||||
"ExcludeIds": [],
|
||||
"Value": 88
|
||||
},
|
||||
{
|
||||
"Id": 6,
|
||||
"Name": "连七对",
|
||||
"Pattern": {
|
||||
"Ke": 0,
|
||||
"Shun": 0,
|
||||
"Dui": 7,
|
||||
"Gang": 0
|
||||
},
|
||||
"ExcludeIds": [],
|
||||
"Value": 88
|
||||
},
|
||||
{
|
||||
"Id": 7,
|
||||
"Name": "十三幺",
|
||||
"Pattern": {
|
||||
"Ke": 0,
|
||||
"Shun": 0,
|
||||
"Dui": 1,
|
||||
"Gang": 0
|
||||
},
|
||||
"ExcludeIds": [],
|
||||
"Value": 88
|
||||
},
|
||||
{
|
||||
"Id": 8,
|
||||
"Name": "清幺九",
|
||||
"Pattern": {
|
||||
"Ke": 4,
|
||||
"Shun": 0,
|
||||
"Dui": 1,
|
||||
"Gang": 0
|
||||
},
|
||||
"ExcludeIds": [],
|
||||
"Value": 88
|
||||
},
|
||||
{
|
||||
"Id": 9,
|
||||
"Name": "小四喜",
|
||||
"Pattern": {
|
||||
"Ke": 3,
|
||||
"Shun": 0,
|
||||
"Dui": 1,
|
||||
"Gang": 0
|
||||
},
|
||||
"ExcludeIds": [],
|
||||
"Value": 64
|
||||
},
|
||||
{
|
||||
"Id": 10,
|
||||
"Name": "小三元",
|
||||
"Pattern": {
|
||||
"Ke": 2,
|
||||
"Shun": 0,
|
||||
"Dui": 1,
|
||||
"Gang": 0
|
||||
},
|
||||
"ExcludeIds": [],
|
||||
"Value": 64
|
||||
},
|
||||
{
|
||||
"Id": 11,
|
||||
"Name": "字一色",
|
||||
"Pattern": {
|
||||
"Ke": 4,
|
||||
"Shun": 0,
|
||||
"Dui": 1,
|
||||
"Gang": 0
|
||||
},
|
||||
"ExcludeIds": [],
|
||||
"Value": 64
|
||||
},
|
||||
{
|
||||
"Id": 12,
|
||||
"Name": "四暗刻",
|
||||
"Pattern": {
|
||||
"Ke": 4,
|
||||
"Shun": 0,
|
||||
"Dui": 2,
|
||||
"Gang": 0
|
||||
},
|
||||
"ExcludeIds": [],
|
||||
"Value": 64
|
||||
},
|
||||
{
|
||||
"Id": 13,
|
||||
"Name": "一色双龙会",
|
||||
"Pattern": {
|
||||
"Ke": 0,
|
||||
"Shun": 4,
|
||||
"Dui": 1,
|
||||
"Gang": 0
|
||||
},
|
||||
"ExcludeIds": [],
|
||||
"Value": 64
|
||||
},
|
||||
{
|
||||
"Id": 14,
|
||||
"Name": "一色四同顺",
|
||||
"Pattern": {
|
||||
"Ke": 0,
|
||||
"Shun": 4,
|
||||
"Dui": 1,
|
||||
"Gang": 0
|
||||
},
|
||||
"ExcludeIds": [],
|
||||
"Value": 48
|
||||
},
|
||||
{
|
||||
"Id": 15,
|
||||
"Name": "一色四节高",
|
||||
"Pattern": {
|
||||
"Ke": 4,
|
||||
"Shun": 0,
|
||||
"Dui": 1,
|
||||
"Gang": 0
|
||||
},
|
||||
"ExcludeIds": [],
|
||||
"Value": 48
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user