Documentation
¶
Index ¶
- Constants
- Variables
- func BrightYarrowPrint(text string)
- func BrightYarrowPrintf(format string, texts ...interface{})
- func ByteAtStr(b byte, s string) int
- func CalcPointRon(han int, fu int, yakumanTimes int, isParent bool) (point int)
- func CalcPointTsumo(han int, fu int, yakumanTimes int, isParent bool) (childPoint int, parentPoint int)
- func CalcPointTsumoSum(han int, fu int, yakumanTimes int, isParent bool) int
- func CalcTenpaiRate(melds []*model.Meld, discardTiles []int, meldDiscardsAt []int) float64
- func CalcYakuHan(yakuTypes []int, isNaki bool) (cntHan int)
- func CalcYakumanTimes(yakuTypes []int, isNaki bool) (times int)
- func CalculateAgariRateOfEachTile(waits Waits, playerInfo *model.PlayerInfo) map[int]float64
- func CalculateAvgAgariRate(waits Waits, playerInfo *model.PlayerInfo) float64
- func CalculateLeftNoSujiTiles(safeTiles34 []bool, leftTiles34 []int) (leftNoSujiTiles []int)
- func CalculateMeld(playerInfo *model.PlayerInfo, calledTile int, isRedFive bool, allowChi bool) (minShanten int, results Hand14AnalysisResultList, ...)
- func CalculateShanten(tiles34 []int) int
- func CalculateShantenOfChiitoi(tiles34 []int) int
- func CalculateShantenOfNormal(tiles34 []int, countOfTiles int) int
- func CalculateShantenWithImproves14(playerInfo *model.PlayerInfo) (shanten int, results Hand14AnalysisResultList, ...)
- func CatPrint()
- func ChiCongPrint(text string)
- func ChiCongPrintf(format string, texts ...interface{})
- func CityLightPrint(text string)
- func CityLightPrintf(format string, texts ...interface{})
- func CountOfTiles34(tiles34 []int) (count int)
- func CountPairsOfTiles34(tiles34 []int) (count int)
- func EggBluePrint(text string)
- func EggBluePrintf(format string, texts ...interface{})
- func Equal(a, b float64) bool
- func GetTenpaiRate3(rate4 float64) (rate3 float64)
- func GradualChangePrint(text string)
- func InDelta(a, b, delta float64) bool
- func InInts(e int, arr []int) bool
- func InStrings(e string, arr []string) bool
- func InitLeftTiles34() []int
- func InitLeftTiles34WithTiles34(tiles34 []int) []int
- func IsAgari(tiles34 []int) bool
- func LightGreenishBluePrint(text string)
- func LightGreenishBluePrintf(format string, texts ...interface{})
- func Lower(c byte) byte
- func MaxInt(a, b int) int
- func MinInt(a, b int) int
- func MintLeafPrint(text string)
- func MintLeafPrintf(format string, texts ...interface{})
- func MustParseHumanTilesWithMelds(humanTilesWithMelds string) *model.PlayerInfo
- func MustStrToTile34(humanTile string) int
- func MustStrToTiles(humanTiles string) []int
- func MustStrToTiles34(humanTiles string) []int
- func NumberToChineseShanten(num int) string
- func OrangevillePrint(text string)
- func OrangevillePrintf(format string, texts ...interface{})
- func OutsideTiles(tile int) (outsideTiles []int)
- func ParseHumanTilesWithMelds(humanTilesWithMelds string) (playerInfo *model.PlayerInfo, err error)
- func RandomAddTile(tiles34 []int)
- func RonPointOtherNakiWithDora(doraCount int) (point float64)
- func SetConsiderOldYaku(b bool)
- func ShantenTrueColorChinese(num int)
- func SourLemonPrint(text string)
- func SourLemonPrintf(format string, texts ...interface{})
- func StrToTile34(humanTile string) (tile34 int, isRedFive bool, err error)
- func StrToTiles(humanTiles string) (tiles []int, numRedFives []int, err error)
- func StrToTiles34(humanTiles string) (tiles34 []int, numRedFives []int, err error)
- func Tile34ToStr(tile34 int) string
- func Tiles34ToStr(tiles34 []int) (humanTiles string)
- func Tiles34ToStrWithBracket(tiles34 []int) string
- func Tiles34ToTiles(tiles34 []int) (tiles []int)
- func TilesToMahjongZH(tiles []int) (words []string)
- func TilesToMahjongZHInterface(tiles []int) (words []interface{})
- func TilesToStr(tiles []int) (humanTiles string)
- func TilesToStrWithBracket(tiles []int) string
- func TilesToTiles34(tiles []int) (tiles34 []int)
- func Upper(c byte) byte
- func YakuTypesToStr(yakuTypes []int) string
- func YakuTypesWithDoraToStr(yakuTypes map[int]struct{}, numDora int) string
- type DivideResult
- type Hand13AnalysisResult
- type Hand14AnalysisResult
- type Hand14AnalysisResultList
- type Improves
- type PointResult
- type RiskTiles34
- type Waits
- type WallSafeTile
- type WallSafeTileList
- func CalcDNCSafeTiles(leftTiles34 []int) (dncSafeTiles WallSafeTileList)
- func CalcDNCSafeTilesWithDiscards(leftTiles34 []int, safeTiles34 []bool) (dncSafeTiles WallSafeTileList)
- func CalcNCSafeTiles(leftTiles34 []int) (ncSafeTiles WallSafeTileList)
- func CalcOCSafeTiles(leftTiles34 []int) (ocSafeTiles WallSafeTileList)
- func CalcWallTiles(leftTiles34 []int) (safeTiles WallSafeTileList)
Constants ¶
const ( RonPointRiichiHiIppatsu = 5172.0 // 基准 RonPointRiichiIppatsu = 7445.0 //RonPointHonitsu = 6603.0 //RonPointToitoi = 7300.0 RonPointOtherNaki = 3000.0 // *fixed // TODO: 考虑双东的影响 RonPointDama = 4536.0 )
子家荣和点数均值 参考:「統計学」のマージャン戦術 亲家按 x1.5 算 TODO: 剩余 dora 数对失点的影响
const ( WallSafeTypeDoubleNoChance = iota // 只输单骑对碰 WallSafeTypeNoChance // 单骑对碰边张坎张 WallSafeTypeDoubleOneChance WallSafeTypeMixedOneChance // 对于456来说,一半 double,一半不是 double WallSafeTypeOneChance )
const ( // https://en.wikipedia.org/wiki/Japanese_Mahjong_yaku // Special criteria YakuRiichi int = iota YakuChiitoi // Yaku based on luck YakuTsumo //YakuIppatsu //YakuHaitei //YakuHoutei //YakuRinshan //YakuChankan YakuDaburii // Yaku based on sequences YakuPinfu YakuRyanpeikou YakuIipeikou YakuSanshokuDoujun // * YakuIttsuu // * // Yaku based on triplets and/or quads YakuToitoi YakuSanAnkou YakuSanshokuDoukou YakuSanKantsu // Yaku based on terminal or honor tiles YakuTanyao YakuYakuhai YakuChanta // * 必须有顺子 YakuJunchan // * 必须有顺子 YakuHonroutou // 七对也算 YakuShousangen // Yaku based on suits YakuHonitsu // * YakuChinitsu // * // Yakuman //YakuKokushi //YakuKokushi13 YakuSuuAnkou YakuSuuAnkouTanki YakuDaisangen YakuShousuushii YakuDaisuushii YakuTsuuiisou YakuChinroutou YakuRyuuiisou YakuChuuren YakuChuuren9 YakuSuuKantsu // 古役 YakuShiiaruraotai YakuUumensai YakuSanrenkou YakuIsshokusanjun // 古役役满 YakuDaisuurin YakuDaisharin YakuDaichikurin YakuDaichisei )
Variables ¶
var ( // TileTypeTable [需要判断危险度的牌号(0-8)][是否有对应的现物(0-1或0-3)] // 123789: 无现物,有现物 // 4: 无17现物,无1有7,有1无7,有17 // 56: 同上 TileTypeTable = [][]tileType{ {tileTypeNoSuji19, tileTypeSuji19}, {tileTypeNoSuji28, tileTypeSuji28}, {tileTypeNoSuji37, tileTypeSuji37}, {tileTypeNoSuji46, tileTypeHalfSuji46B, tileTypeHalfSuji46A, tileTypeDoubleSuji46}, {tileTypeNoSuji5, tileTypeHalfSuji5, tileTypeHalfSuji5, tileTypeDoubleSuji5}, {tileTypeNoSuji46, tileTypeHalfSuji46A, tileTypeHalfSuji46B, tileTypeDoubleSuji46}, {tileTypeNoSuji37, tileTypeSuji37}, {tileTypeNoSuji28, tileTypeSuji28}, {tileTypeNoSuji19, tileTypeSuji19}, } // [是否为役牌(0-1)][剩余数-1] HonorTileType = [][]tileType{ {tileTypeOtakazeLeft1, tileTypeOtakazeLeft2, tileTypeOtakazeLeft3, tileTypeOtakazeLeft3}, {tileTypeYakuHaiLeft1, tileTypeYakuHaiLeft2, tileTypeYakuHaiLeft3, tileTypeYakuHaiLeft3}, } )
var FixedDoraRiskRateMulti = []float64{
14.9 / 12.8 * 78 / 58,
15.0 / 13.1 * 78 / 58,
12.1 / 9.5 * 75 / 56,
10.3 / 8.6 * 75 / 54,
8.9 / 7.4 * 77 / 53,
9.7 / 7.4 * 81 / 60,
8.9 / 7.2 * 81 / 60,
10.4 / 7.9 * 81 / 60,
8.0 / 5.5 * 75 / 56,
5.5 / 3.9 * 81 / 56,
3.5 / 1.8 * 92 / 58,
4.1 / 2.2 * 88 / 62,
4.1 / 2.3 * 88 / 62,
5.2 / 4.6 * 96 / 67,
2.9 / 1.9 * 96 / 67,
1.1 / 0.3 * 96 / 67,
5.1 / 4.0 * 92 / 56,
3.0 / 1.8 * 92 / 56,
0.8 / 0.2 * 92 / 56,
}
考虑失点的综合值(参考第9巡的数据)
var Mahjong = [...]string{
"1m", "2m", "3m", "4m", "5m", "6m", "7m", "8m", "9m",
"1p", "2p", "3p", "4p", "5p", "6p", "7p", "8p", "9p",
"1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s",
"1z", "2z", "3z", "4z", "5z", "6z", "7z",
}
var MahjongU = [...]string{
"1M", "2M", "3M", "4M", "5M", "6M", "7M", "8M", "9M",
"1p", "2p", "3p", "4p", "5p", "6p", "7p", "8p", "9p",
"1S", "2S", "3S", "4S", "5S", "6S", "7S", "8S", "9S",
"1Z", "2Z", "3Z", "4Z", "5Z", "6Z", "7Z",
}
var MahjongZH = [...]string{
"1万", "2万", "3万", "4万", "5万", "6万", "7万", "8万", "9万",
"1饼", "2饼", "3饼", "4饼", "5饼", "6饼", "7饼", "8饼", "9饼",
"1索", "2索", "3索", "4索", "5索", "6索", "7索", "8索", "9索",
"东", "南", "西", "北", "白", "发", "中",
}
var MaxTurns = len(RiskRate) - 1
var NakiYakuHanMap = _yakuHanMap{ YakuSanshokuDoujun: 1, YakuIttsuu: 1, YakuToitoi: 2, YakuSanAnkou: 2, YakuSanshokuDoukou: 2, YakuSanKantsu: 2, YakuTanyao: 1, YakuYakuhai: 1, YakuChanta: 1, YakuJunchan: 2, YakuHonroutou: 2, YakuShousangen: 2, YakuHonitsu: 2, YakuChinitsu: 5, }
var NakiYakumanTimesMap = map[int]int{ YakuDaisangen: 1, YakuShousuushii: 1, YakuDaisuushii: 2, YakuTsuuiisou: 1, YakuChinroutou: 1, YakuRyuuiisou: 1, YakuSuuKantsu: 1, }
var OldNakiYakuHanMap = _yakuHanMap{ YakuShiiaruraotai: 1, YakuUumensai: 2, YakuSanrenkou: 2, YakuIsshokusanjun: 2, }
var OldYakuHanMap = _yakuHanMap{ YakuUumensai: 2, YakuSanrenkou: 2, YakuIsshokusanjun: 3, }
var OldYakuNameMap = map[int]string{ YakuShiiaruraotai: "十二落抬", YakuUumensai: "五门齐", YakuSanrenkou: "三连刻", YakuIsshokusanjun: "一色三顺", YakuDaisuurin: "大数邻", YakuDaisharin: "大车轮", YakuDaichikurin: "大竹林", YakuDaichisei: "大七星", }
var OldYakumanTimesMap = map[int]int{ YakuDaisuurin: 1, YakuDaisharin: 1, YakuDaichikurin: 1, YakuDaichisei: 1, }
var RiskRate = [][]float64{
{},
{5.7, 5.7, 5.8, 4.7, 3.4, 2.5, 2.5, 3.1, 5.6, 3.8, 1.8, 0.8, 2.6, 2.1, 1.2, 0.5, 2.4, 1.4, 1.2},
{6.6, 6.9, 6.3, 5.2, 4.0, 3.5, 3.5, 4.1, 5.3, 3.5, 1.9, 0.8, 2.6, 2.3, 1.2, 0.5, 2.7, 1.3, 0.4},
{7.7, 8.0, 6.7, 5.8, 4.6, 4.3, 4.1, 4.9, 5.2, 3.6, 1.8, 1.6, 2.0, 2.4, 1.2, 0.3, 2.6, 1.2, 0.3},
{8.5, 8.9, 7.1, 6.2, 5.1, 4.8, 4.7, 5.6, 5.2, 3.8, 1.7, 1.6, 2.0, 2.6, 1.1, 0.2, 2.6, 1.2, 0.2},
{9.4, 9.7, 7.5, 6.7, 5.5, 5.3, 5.1, 6.0, 5.3, 3.7, 1.7, 1.7, 2.0, 2.9, 1.2, 0.2, 2.8, 1.2, 0.2},
{10.2, 10.5, 7.9, 7.1, 5.9, 5.8, 5.6, 6.4, 5.2, 3.7, 1.7, 1.8, 2.0, 3.2, 1.3, 0.2, 2.9, 1.3, 0.2},
{11.0, 11.3, 8.4, 7.5, 6.3, 6.3, 6.1, 6.8, 5.3, 3.7, 1.7, 2.0, 2.1, 3.6, 1.4, 0.2, 3.2, 1.4, 0.2},
{11.9, 12.2, 8.9, 8.0, 6.8, 6.9, 6.6, 7.4, 5.3, 3.8, 1.7, 2.1, 2.2, 4.0, 1.6, 0.2, 3.5, 1.6, 0.2},
{12.8, 13.1, 9.5, 8.6, 7.4, 7.4, 7.2, 7.9, 5.5, 3.9, 1.8, 2.2, 2.3, 4.6, 1.9, 0.3, 4.0, 1.8, 0.2},
{13.8, 14.1, 10.1, 9.2, 8.0, 8.0, 7.8, 8.5, 5.6, 4.0, 1.9, 2.4, 2.4, 5.3, 2.2, 0.3, 4.6, 2.1, 0.3},
{14.9, 15.1, 10.8, 9.9, 8.7, 8.7, 8.5, 9.2, 5.7, 4.2, 2.0, 2.5, 2.6, 6.0, 2.6, 0.4, 5.1, 2.5, 0.3},
{16.0, 16.3, 11.6, 10.6, 9.4, 9.4, 9.2, 9.9, 6.0, 4.4, 2.2, 2.7, 2.7, 6.8, 3.1, 0.4, 5.1, 2.5, 0.3},
{17.2, 17.5, 12.4, 11.4, 10.2, 10.2, 10.0, 10.6, 6.2, 4.6, 2.4, 3.0, 3.0, 7.8, 3.7, 0.5, 6.6, 3.7, 0.5},
{18.5, 18.8, 13.3, 12.3, 11.1, 11.0, 10.9, 11.4, 6.6, 4.9, 2.7, 3.2, 3.1, 8.8, 4.4, 0.7, 7.4, 4.4, 0.6},
{19.9, 20.1, 14.3, 13.3, 12.0, 11.9, 11.8, 12.3, 7.0, 5.3, 3.0, 3.4, 3.4, 9.9, 5.2, 0.8, 8.4, 5.3, 0.8},
{21.3, 21.7, 15.4, 14.3, 13.1, 12.9, 12.8, 13.3, 7.4, 5.7, 3.3, 3.7, 3.6, 11.2, 6.2, 1.0, 9.4, 6.5, 0.9},
{22.9, 23.2, 16.6, 15.4, 14.2, 14.0, 13.8, 14.4, 8.0, 6.1, 3.6, 3.9, 3.9, 12.4, 7.3, 1.3, 10.5, 7.7, 1.2},
{24.7, 24.9, 17.9, 16.7, 15.4, 15.2, 15.0, 15.6, 8.5, 6.6, 4.0, 4.3, 4.2, 13.9, 8.5, 1.7, 11.8, 9.4, 1.6},
{27.5, 27.8, 20.4, 19.1, 17.8, 17.5, 17.5, 17.5, 9.8, 7.4, 5.0, 5.1, 5.1, 18.1, 12.1, 2.8, 14.7, 12.6, 2.1},
}
[巡目][类型]
var YakuHanMap = _yakuHanMap{ YakuRiichi: 1, YakuChiitoi: 2, YakuTsumo: 1, YakuDaburii: 2, YakuPinfu: 1, YakuRyanpeikou: 3, YakuIipeikou: 1, YakuSanshokuDoujun: 2, YakuIttsuu: 2, YakuToitoi: 2, YakuSanAnkou: 2, YakuSanshokuDoukou: 2, YakuSanKantsu: 2, YakuTanyao: 1, YakuYakuhai: 1, YakuChanta: 2, YakuJunchan: 3, YakuHonroutou: 2, YakuShousangen: 2, YakuHonitsu: 3, YakuChinitsu: 6, }
var YakuNameMap = map[int]string{ YakuRiichi: "立直", YakuChiitoi: "七对", YakuTsumo: "自摸", YakuDaburii: "w立", YakuPinfu: "平和", YakuRyanpeikou: "两杯口", YakuIipeikou: "一杯口", YakuSanshokuDoujun: "三色", YakuIttsuu: "一通", YakuToitoi: "对对", YakuSanAnkou: "三暗刻", YakuSanshokuDoukou: "三色同刻", YakuSanKantsu: "三杠子", YakuTanyao: "断幺", YakuYakuhai: "役牌", YakuChanta: "混全", YakuJunchan: "纯全", YakuHonroutou: "混老头", YakuShousangen: "小三元", YakuHonitsu: "混一色", YakuChinitsu: "清一色", YakuSuuAnkou: "四暗刻", YakuSuuAnkouTanki: "四暗刻单骑", YakuDaisangen: "大三元", YakuShousuushii: "小四喜", YakuDaisuushii: "大四喜", YakuTsuuiisou: "字一色", YakuChinroutou: "清老头", YakuRyuuiisou: "绿一色", YakuChuuren: "九莲", YakuChuuren9: "纯正九莲", YakuSuuKantsu: "四杠子", }
var YakumanTimesMap = map[int]int{ YakuSuuAnkou: 1, YakuSuuAnkouTanki: 2, YakuDaisangen: 1, YakuShousuushii: 1, YakuDaisuushii: 2, YakuTsuuiisou: 1, YakuChinroutou: 1, YakuRyuuiisou: 1, YakuChuuren: 1, YakuChuuren9: 2, YakuSuuKantsu: 1, }
var YaochuTiles = [...]int{0, 8, 9, 17, 18, 26, 27, 28, 29, 30, 31, 32, 33}
Functions ¶
func BrightYarrowPrint ¶
func BrightYarrowPrint(text string)
func BrightYarrowPrintf ¶
func BrightYarrowPrintf(format string, texts ...interface{})
func CalcPointRon ¶
番数 符数 役满倍数 是否为亲家 返回荣和点数
func CalcPointTsumo ¶
func CalcPointTsumo(han int, fu int, yakumanTimes int, isParent bool) (childPoint int, parentPoint int)
番数 符数 役满倍数 是否为亲家 返回自摸时的子家支付点数和亲家支付点数
func CalcPointTsumoSum ¶
番数 符数 役满倍数 是否为亲家 返回自摸时的点数
func CalcTenpaiRate ¶
没有立直时,根据玩家的副露、手切来判断其听牌率 (0-100) TODO: 传入 *model.PlayerInfo
func CalcYakuHan ¶
计算 yakuTypes(非役满) 累积的番数
func CalculateAgariRateOfEachTile ¶
func CalculateAgariRateOfEachTile(waits Waits, playerInfo *model.PlayerInfo) map[int]float64
计算各张待牌的和率 剩余为 0 则和率为 0
func CalculateAvgAgariRate ¶
func CalculateAvgAgariRate(waits Waits, playerInfo *model.PlayerInfo) float64
计算平均和率
func CalculateLeftNoSujiTiles ¶
计算剩余的无筋 123789 牌 总计 18 种。剩余无筋牌数量越少,该无筋牌越危险
func CalculateMeld ¶
func CalculateMeld(playerInfo *model.PlayerInfo, calledTile int, isRedFive bool, allowChi bool) (minShanten int, results Hand14AnalysisResultList, incShantenResults Hand14AnalysisResultList)
计算鸣牌下的何切分析 calledTile 他家出的牌,尝试鸣这张牌 isRedFive 这张牌是否为赤5 allowChi 是否允许吃这张牌
func CalculateShantenOfChiitoi ¶
参考 http://ara.moo.jp/mjhmr/shanten.htm 七对子向听数 = 6-对子数+max(0,7-种类数)
func CalculateShantenOfNormal ¶
根据手牌计算一般型(不考虑七对国士)的向听数 3k+1 和 3k+2 张牌都行
func CalculateShantenWithImproves14 ¶
func CalculateShantenWithImproves14(playerInfo *model.PlayerInfo) (shanten int, results Hand14AnalysisResultList, incShantenResults Hand14AnalysisResultList)
CalculateShantenWithImproves14 3k+2 张牌,计算向听数、进张、改良、向听倒退等
func ChiCongPrint ¶
func ChiCongPrint(text string)
func ChiCongPrintf ¶
func ChiCongPrintf(format string, texts ...interface{})
func CityLightPrint ¶
func CityLightPrint(text string)
func CityLightPrintf ¶
func CityLightPrintf(format string, texts ...interface{})
func EggBluePrint ¶
func EggBluePrint(text string)
func EggBluePrintf ¶
func EggBluePrintf(format string, texts ...interface{})
func GetTenpaiRate3 ¶
用四麻的数据近似得到三麻的数据 更加精确的数据见 https://shikkaku.com/data_sanma_20
func GradualChangePrint ¶
func GradualChangePrint(text string)
func InitLeftTiles34 ¶
func InitLeftTiles34() []int
func InitLeftTiles34WithTiles34 ¶
根据传入的牌,返回移除这些牌后剩余的牌
func LightGreenishBluePrint ¶
func LightGreenishBluePrint(text string)
func LightGreenishBluePrintf ¶
func LightGreenishBluePrintf(format string, texts ...interface{})
func MintLeafPrint ¶
func MintLeafPrint(text string)
func MintLeafPrintf ¶
func MintLeafPrintf(format string, texts ...interface{})
func MustParseHumanTilesWithMelds ¶
func MustParseHumanTilesWithMelds(humanTilesWithMelds string) *model.PlayerInfo
func OrangevillePrint ¶
func OrangevillePrint(text string)
func OrangevillePrintf ¶
func OrangevillePrintf(format string, texts ...interface{})
func ParseHumanTilesWithMelds ¶
func ParseHumanTilesWithMelds(humanTilesWithMelds string) (playerInfo *model.PlayerInfo, err error)
func RonPointOtherNakiWithDora ¶
简单地判断子家副露者的打点 dora point han 0 3000 1-3 1 4200 2-4 2 5880 3-5 3 8232 4-6 4 10000 5-7 5 13000 6-8 亲家按 x1.5 算 TODO: 暗杠对打点的提升?
func SetConsiderOldYaku ¶
func SetConsiderOldYaku(b bool)
func ShantenTrueColorChinese ¶
func ShantenTrueColorChinese(num int)
func SourLemonPrint ¶
func SourLemonPrint(text string)
func SourLemonPrintf ¶
func SourLemonPrintf(format string, texts ...interface{})
func StrToTile34 ¶
e.g. "3m" => 2 可以接收赤5,如 0p
func StrToTiles ¶
e.g. "11122z" => [27, 27, 27, 28, 28]
func StrToTiles34 ¶
e.g. "224m 24p" => [0, 2, 0, 1, 0, ..., 1, 0, 1, ...] 也可以传入不含空格的手牌,如 "224m24p" 可以接收赤5,如 0p
func Tile34ToStr ¶
func Tiles34ToStr ¶
func Tiles34ToStrWithBracket ¶
func Tiles34ToTiles ¶
func TilesToMahjongZH ¶
func TilesToMahjongZHInterface ¶
func TilesToMahjongZHInterface(tiles []int) (words []interface{})
func TilesToStrWithBracket ¶
e.g. [9, 11, 27] => "[13p 1z]"
func TilesToTiles34 ¶
func YakuTypesToStr ¶
func YakuTypesWithDoraToStr ¶
Types ¶
type DivideResult ¶
type DivideResult struct { PairTile int // 雀头牌 KotsuTiles []int // 刻子牌(注意 len(KotsuTiles) 为自摸时的暗刻数,荣和时的暗刻数需要另加逻辑判断) ShuntsuFirstTiles []int // 顺子牌的第一张(如 678s 的 6s) // 由于生成 winTable 的代码是不考虑具体是什么牌的, // 所以只能判断如七对子、九莲宝灯、一气通贯、两杯口、一杯口等和「形状」有关的役, // 像国士无双、断幺、全带、三色、绿一色等,和具体的牌/位置有关的役是判断不出的,需要另加逻辑判断 IsChiitoi bool // 七对子 IsChuurenPoutou bool // 九莲宝灯 IsIttsuu bool // 一气通贯(注意:未考虑副露!) IsRyanpeikou bool // 两杯口(IsRyanpeikou == true 时 IsIipeikou == false) IsIipeikou bool // 一杯口 }
3k+2 张牌的某种拆解结果
func DivideTiles34 ¶
func DivideTiles34(tiles34 []int) (divideResults []*DivideResult)
3k+2 张牌,返回所有可能的拆解,没有拆解表示未和牌(不检测国士无双) http://hp.vector.co.jp/authors/VA046927/mjscore/mjalgorism.html http://hp.vector.co.jp/authors/VA046927/mjscore/AgariIndex.java
type Hand13AnalysisResult ¶
type Hand13AnalysisResult struct { // 原手牌 Tiles34 []int // 剩余牌 LeftTiles34 []int // 是否已鸣牌(非门清状态) // 用于判断是否无役等 IsNaki bool // 向听数 Shanten int // 进张 // 考虑了剩余枚数 // 若某个进张牌 4 枚都可见,则该进张的 value 值为 0 Waits Waits // 默听时的进张 DamaWaits Waits // map[进张牌]向听前进后的(最大)进张数 NextShantenWaitsCountMap map[int]int // 向听前进后的(最大)进张数的加权均值 AvgNextShantenWaitsCount float64 // 综合了进张与向听前进后进张的评分 MixedWaitsScore float64 // 改良:摸到这张牌虽不能让向听数前进,但可以让进张变多 // len(Improves) 即为改良的牌的种数 Improves Improves // 改良情况数,这里计算的是有多少种使进张增加的摸牌-切牌方式 ImproveWayCount int // 摸到非进张牌时的进张数的加权均值(非改良+改良。对于非改良牌,其进张数为 Waits.AllCount()) // 这里只考虑一巡的改良均值 // TODO: 在考虑改良的情况下,如何计算向听前进所需要的摸牌次数的期望值?蒙特卡罗方法? AvgImproveWaitsCount float64 // 听牌时的手牌和率 // TODO: 未听牌时的和率? AvgAgariRate float64 // 振听可能率(一向听和听牌时) FuritenRate float64 // 役种 YakuTypes map[int]struct{} // (鸣牌时)是否片听 IsPartWait bool // 宝牌个数(手牌+副露) DoraCount int // 非立直状态下的打点期望(副露或默听) DamaPoint float64 // 立直状态下的打点期望 RiichiPoint float64 // 局收支 MixedRoundPoint float64 }
3k+1 张手牌的分析结果
func CalculateShantenWithImproves13 ¶
func CalculateShantenWithImproves13(playerInfo *model.PlayerInfo) (r *Hand13AnalysisResult)
CalculateShantenWithImproves13 3k+1 张牌,计算向听数、进张、改良等(考虑了剩余枚数)
type Hand14AnalysisResult ¶
type Hand14AnalysisResult struct { // 需要切的牌 DiscardTile int // 切的是否为宝牌 IsDiscardDoraTile bool // 切的牌的价值(宝牌或宝牌周边) DiscardTileValue tileValue // 切牌后的手牌分析结果 Result13 *Hand13AnalysisResult DiscardHonorTileRisk int // 剩余可以摸的牌数 LeftDrawTilesCount int // 副露信息(没有副露就是 nil) // 比如用 23m 吃了牌,OpenTiles 就是 [1,2] OpenTiles []int // contains filtered or unexported fields }
func (*Hand14AnalysisResult) String ¶
func (r *Hand14AnalysisResult) String() string
type Hand14AnalysisResultList ¶
type Hand14AnalysisResultList []*Hand14AnalysisResult
func (Hand14AnalysisResultList) Sort ¶
func (l Hand14AnalysisResultList) Sort(improveFirst bool)
按照特定规则排序 若 improveFirst 为 true,则优先按照 AvgImproveWaitsCount 排序(对于三向听及以上来说)
type PointResult ¶
type PointResult struct { Point int FixedPoint float64 // 和牌时的期望点数 // contains filtered or unexported fields }
func CalcAvgPoint ¶
func CalcAvgPoint(playerInfo model.PlayerInfo, waits Waits) (avgPoint float64, pointResults []*PointResult)
已听牌,根据 playerInfo 提供的信息计算加权和率后的平均点数 无役时返回 0 有役时返回平均点数(立直时考虑自摸、一发和里宝)和各种侍牌下的对应点数
func CalcAvgRiichiPoint ¶
func CalcAvgRiichiPoint(playerInfo model.PlayerInfo, waits Waits) (avgRiichiPoint float64, pointResults []*PointResult)
计算立直时的平均点数(考虑自摸、一发和里宝)和各种侍牌下的对应点数 已鸣牌时返回 0 TODO: 剩余不到 4 张无法立直 TODO: 不足 1000 点无法立直
func CalcPoint ¶
func CalcPoint(playerInfo *model.PlayerInfo) (result *PointResult)
已和牌,计算自摸或荣和时的点数(不考虑里宝、一发等情况) 无役时返回的点数为 0(和率也为 0) 调用前请设置 IsTsumo WinTile
type RiskTiles34 ¶
type RiskTiles34 []float64
func CalculateRiskTiles34 ¶
func CalculateRiskTiles34(turns int, safeTiles34 []bool, leftTiles34 []int, doraTiles []int, roundWindTile int, playerWindTile int) (risk34 RiskTiles34)
根据巡目(对于对手而言)、现物、立直后通过的牌、NC、Dora,来计算基础铳率 至于早外、OC 和读牌交给后续的计算 turns: 巡目,这里是对于对手而言的,也就是该玩家舍牌的次数 safeTiles34: 现物及立直后通过的牌 leftTiles34: 各个牌在山中剩余的枚数 roundWindTile: 场风 playerWindTile: 自风
func (RiskTiles34) FixWithEarlyOutside ¶
func (l RiskTiles34) FixWithEarlyOutside(discardTiles []int) RiskTiles34
对 5 巡前的外侧牌的危险度进行调整 粗略调整为 *0.4(参考:科学する麻雀)
func (RiskTiles34) FixWithGlobalMulti ¶
func (l RiskTiles34) FixWithGlobalMulti(multi float64) RiskTiles34
func (RiskTiles34) FixWithPoint ¶
func (l RiskTiles34) FixWithPoint(ronPoint float64) RiskTiles34
根据副露情况对危险度进行修正
type Waits ¶
进张 map[进张牌]剩余数
func CalculateShantenAndWaits13 ¶
3k+1 张牌,计算向听数、进张(考虑了剩余枚数),不计算改良
func (Waits) ParseIndex ¶
type WallSafeTile ¶
type WallSafeTileList ¶
type WallSafeTileList []WallSafeTile
func CalcDNCSafeTiles ¶
func CalcDNCSafeTiles(leftTiles34 []int) (dncSafeTiles WallSafeTileList)
根据剩余牌 leftTiles34 中的某些牌是否为 0(壁),来判断哪些牌较为安全(Double No Chance:只输单骑、双碰)
func CalcDNCSafeTilesWithDiscards ¶
func CalcDNCSafeTilesWithDiscards(leftTiles34 []int, safeTiles34 []bool) (dncSafeTiles WallSafeTileList)
根据剩余牌 leftTiles34 中的某些牌是否为 0(壁),来判断哪些牌较为安全(Double No Chance:只输单骑、双碰) 这里加上现物,相比 CalcDNCSafeTiles 可以得到更加精确的结果 注:虽然说在 4 为现物的情况下,1 也可以认为是只输单骑、双碰的,但这不在壁的讨论范围内,故不考虑这种情况
func CalcNCSafeTiles ¶
func CalcNCSafeTiles(leftTiles34 []int) (ncSafeTiles WallSafeTileList)
根据剩余牌 leftTiles34 中的某些牌是否为 0(壁),来判断哪些牌较为安全(No Chance:不输两面)
func CalcOCSafeTiles ¶
func CalcOCSafeTiles(leftTiles34 []int) (ocSafeTiles WallSafeTileList)
根据剩余牌 leftTiles34 中的某些牌是否为 1(薄壁),来判断哪些牌较为安全(One Chance:早巡大概率不输两面)
func CalcWallTiles ¶
func CalcWallTiles(leftTiles34 []int) (safeTiles WallSafeTileList)
func (WallSafeTileList) FilterWithHands ¶
func (l WallSafeTileList) FilterWithHands(handsTiles34 []int) WallSafeTileList
func (WallSafeTileList) String ¶
func (l WallSafeTileList) String() string
Source Files
¶
- agari.go
- agari_data.go
- agari_rate.go
- agari_rate_data.go
- fu.go
- hand_info.go
- point.go
- point_data.go
- risk_base.go
- risk_data.go
- risk_wall.go
- shanten_base.go
- shanten_improve.go
- shanten_search.go
- tenpai_data.go
- tenpai_rate.go
- tile.go
- tile_converter.go
- true_color.go
- util.go
- yaku.go
- yaku_data.go
- yaku_old.go
- yaku_yakuman.go