Es scheint, dass die Wahrscheinlichkeit von Tenwa einmal in 330.000 Mal ist Ich wollte es versuchen, also schrieb ich es in Python, Das war nerviger als ich erwartet hatte.
Der Algorithmus ist hier. http://www.onionsoft.net/hsp/mahjong.txt
Die Rolle oder das Warten ist in Ordnung ... Wenn es mir gut geht ~~ Ich schreibe es das nächste Mal ~~.
Ich habe es geschrieben @ [25.09.2014] http://qiita.com/arc279/items/1a7853ad8e2dc35961d1
Bestätigter Vorgang mit python2.7.6.
Ich habe es ehrlich geschrieben. Ich habe list von builtin geerbt, weil es problematisch ist, aber ich denke, dass es besser ist, es zu delegieren.
Das Waschen wird auf zufällig geworfen.
mj.py
#!/usr/bin/env python
# -*- coding: utf8 -*-
import itertools
import random
from collections import OrderedDict
class Yama(list):
u'''Wand'''
WANPAI_NUM = 14
class TsumoDoesNotRemain(Exception):
u'''Nur der König ist noch übrig'''
pass
def __init__(self):
pais = [ Pai.from_index(i)
for i in range(Pai.TOTAL_KIND_NUM * Pai.NUM_OF_EACH_KIND) ]
#Waschen
random.shuffle(pais)
super(Yama, self).__init__(pais)
def tsumo(self):
u'''Eigenständigkeit'''
if len(self) <= self.WANPAI_NUM:
raise self.TsumoDoesNotRemain
return self.pop(0)
def wanpai(self):
return self[-self.WANPAI_NUM:]
def haipai(self):
u'''Verteilung'''
tehais = [ Tehai(), Tehai(), Tehai(), Tehai() ] #Osten(Elternteil)Südwesten Nord
# 4*3 Runden
for j in range(0, 3):
for tehai in tehais:
for i in range(0, 4):
pai = self.tsumo()
tehai.append(pai)
#Choncho
for tehai in tehais:
pai = self.tsumo()
tehai.append(pai)
pai = self.tsumo()
tehais[0].append(pai)
return tehais
class Pai(object):
u'''牌'''
TOTAL_KIND_NUM = 34 # M/P/S +Alle Arten von Zeichen
NUM_OF_EACH_KIND = 4 #4 Blatt pro Typ
NUM_OF_EACH_NUMBER_PAIS = 9 # M/P/Die Anzahl von S ist 1..Bis zu 9
class Suit:
M = 0 #Mann
P = 1 #Tube
S = 2 #Messen
J = 3 #Charakter
NAMES = {
M: u"Mann",
P: u"Tube",
S: u"Messen",
J: u" ",
}
class Num:
NAMES = {
1: u"einer",
2: u"zwei",
3: u"drei",
4: u"vier",
5: u"Fünf",
6: u"Sechs",
7: u"Sieben",
8: u"Acht",
9: u"Neun",
}
class Jihai:
E = 1
S = 2
W = 3
N = 4
HAK = 5
HAT = 6
CHU = 7
NAMES = {
E: u"Osten",
S: u"Süden",
W: u"Westen",
N: u"Norden",
HAK: u"Weiß",
HAT: u"Abwehrmittel",
CHU: u"Während ~",
}
@classmethod
def yaochupai(cls):
u'''么 9 牌'''
return [
cls(cls.Suit.M, 1),
cls(cls.Suit.M, 9),
cls(cls.Suit.P, 1),
cls(cls.Suit.P, 9),
cls(cls.Suit.S, 1),
cls(cls.Suit.S, 9),
cls(cls.Suit.J, cls.Jihai.E),
cls(cls.Suit.J, cls.Jihai.S),
cls(cls.Suit.J, cls.Jihai.W),
cls(cls.Suit.J, cls.Jihai.N),
cls(cls.Suit.J, cls.Jihai.HAK),
cls(cls.Suit.J, cls.Jihai.HAT),
cls(cls.Suit.J, cls.Jihai.CHU),
]
def __init__(self, suit, num):
self.suit = suit
self.num = num
@property
def index(self):
return self.suit * self.NUM_OF_EACH_NUMBER_PAIS + self.num
def __repr__(self):
#return str((self.suit, self.num)) #Taple-Anzeige
if self.suit == Pai.Suit.J:
return Pai.Jihai.NAMES[self.num].encode('utf-8')
else:
return (Pai.Num.NAMES[self.num] + Pai.Suit.NAMES[self.suit]).encode('utf-8')
def __eq__(self, other):
return self.suit == other.suit and self.num == other.num
@classmethod
def from_index(cls, index):
kind = index % cls.TOTAL_KIND_NUM
if True:
suit = kind / cls.NUM_OF_EACH_NUMBER_PAIS
num = kind % cls.NUM_OF_EACH_NUMBER_PAIS + 1
else:
if 0 <= kind < 9:
suit = cls.Suit.M
num = kind - 0 + 1
elif 9 <= kind < 18:
suit = cls.Suit.P
num = kind - 9 + 1
elif 18 <= kind < 27:
suit = cls.Suit.S
num = kind - 18 + 1
elif 27 <= kind < 34:
suit = cls.Suit.J
num = kind - 27 + 1
assert(cls.Suit.M <= suit <= cls.Suit.J)
assert(1 <= num <= cls.NUM_OF_EACH_NUMBER_PAIS)
return cls(suit, num)
class Tehai(list):
u'''Handwerk'''
@staticmethod
def sorter(a, b):
u'''Wie macht man'''
return a.suit - b.suit if a.suit != b.suit else a.num - b.num
def rihai(self):
u'''Rimu'''
self.sort(cmp=self.sorter)
return self
def aggregate(self):
u'''{牌 Samen:Anzahl der Blätter}Aggregat in Form von'''
hash = { x[0]: len(list(x[1])) for x in itertools.groupby(self.rihai()) }
ret = OrderedDict()
#Schlüsselkacheln bleiben jetzt sortiert
for x in sorted(hash.keys(), cmp=self.sorter):
ret[x] = hash[x]
return ret
def show(self):
u'''Anzeige in leicht lesbarer Form'''
line1 = u"|"
line2 = u"|"
for pai in self.rihai():
if pai.suit != Pai.Suit.J:
line1 += Pai.Num.NAMES[pai.num] + u"|"
line2 += Pai.Suit.NAMES[pai.suit] + u"|"
else:
line1 += Pai.Jihai.NAMES[pai.num] + u"|"
line2 += u" |"
print line1.encode("utf-8")
print line2.encode("utf-8")
Gibt es sieben Kinderpaare und Kokushi Musou? Dieser Bereich hängt von der Interpretation ab, also ist es gut. Hier schrieb ich, dass die sieben Paare keinen Spatzenkopf hatten und der Kokushi Musou zwei Spatzenköpfe hatte.
Es war mühsam, den Urteilsteil für die Klasse auszuschneiden, also benutzte ich einen Verschluss.
mj.py
def check_hohra(tehai):
u'''Überprüfen Sie die Form des Endes'''
assert(len(tehai) == 14)
pais = tehai.aggregate()
keys = pais.keys()
length = len(keys)
#print pais, keys, length
def check_chitoitsu(pais):
u'''Sieben Paare prüfen'''
if all([ num == 2 for pai, num in pais.items()]):
return (), [ (pai, pai) for pai, num in pais.items() ]
return None
def check_kokushimusou(pais):
u'''Kokushi Musou Check'''
if length != 13:
return None
yaochupai = Pai.yaochupai()
mentsu = []
for pai, num in pais.items():
if pai not in yaochupai:
return None
# TODO:Ist es in Ordnung, zwei von ihnen hier zu haben?
if num == 2:
atama = (pai, pai)
else:
assert(num == 1)
mentsu.append(pai)
return atama, mentsu
def search_syuntu(pais):
u'''Finde Junko'''
for i in range(length):
if pais[keys[i]] >= 1:
first = keys[i]
try:
second = keys[i+1]
third = keys[i+2]
except IndexError as e:
#Es gibt keine verbleibenden 2 Typen
continue
if first.suit == Pai.Suit.J:
#Charaktere können nicht Junko sein
continue
if not (first.suit == second.suit and first.suit == third.suit):
#Verschiedene Typen
continue
if not ((second.num == first.num+1) and (third.num == first.num+2)):
#Keine Seriennummer
continue
if pais[second] >= 1 and pais[third] >= 1:
pais[first] -= 1
pais[second] -= 1
pais[third] -= 1
return (first, second, third)
return None
def search_kohtu(pais):
u'''Finde die Gravur'''
for j in range(length):
if pais[keys[j]] >= 3:
pais[keys[j]] -= 3
return (keys[j], keys[j], keys[j])
return None
#Sieben Paare
tmp = pais.copy()
ret = check_chitoitsu(tmp)
if ret:
return [ ret ]
#Kokushi Musou
tmp = pais.copy()
ret = check_kokushimusou(tmp)
if ret:
return [ ret ]
#Grundform
candidate = []
for i in range(length):
#Finde den Kopf
if not (pais[keys[i]] >= 2):
continue
tmp = pais.copy()
atama = (keys[i], keys[i])
tmp[keys[i]] -= 2
mentsu = []
while True:
#print tmp
ret = search_syuntu(tmp) or search_kohtu(tmp)
if ret is None:
ret = search_kohtu(tmp) or search_syuntu(tmp)
if ret is None:
#Ich kann weder Junko noch Kiko machen
break
mentsu.append(ret)
#print atama, mentsu, tmp
if len(mentsu) == 4:
#4 Gesicht 1 Spatzenkopfform
candidate.append( (atama, mentsu) )
return candidate
Es wäre schön, wenn es nach dem Arrangement der Eltern wie ein Agari geformt wäre, also wäre es so.
mj.py
def check_tenho():
for cnt in (x for x in itertools.count()):
yama = Yama()
oya, _, _, _ = yama.haipai()
ret = check_hohra(oya)
if ret:
print cnt
oya.show()
for atama, mentsu in ret:
print atama, mentsu
break
if __name__ == '__main__':
#Versuchen Sie es ungefähr 100 Mal
for x in range(100):
check_tenho()
Wenn es auch nach 600.000 Versuchen nicht herauskommt, kommt es nicht heraus, und wenn es herauskommt, kommt es ungefähr 20.000 Mal heraus.
Nun, wenn die Anzahl der Versuche zunimmt, denke ich, dass sie sich nach dem Gesetz der großen Anzahl auf 330.000 Mal niederschlagen wird. vielleicht. Es dauert lange und ist nervig, deshalb habe ich es nur ungefähr 10 Mal versucht. Ich war zufrieden, als ich es schrieb.
Wenn Sie zwischen Rollen und Warten unterscheiden möchten, müssen Sie es wahrscheinlich neu schreiben ...
Das zum Debuggen.
mj.py
class Debug:
u'''for debug'''
TEST_TEHAIS = [
[2, 3, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7],
[0, 0, 8, 8, 13, 13, 20, 20, 25, 25, 29, 29, 31, 31], #Wann
[0, 8, 9, 17, 18, 26, 27, 28, 29, 30, 31, 32, 33, 9], #Quietschend
[33, 33, 33, 32, 32, 32, 31, 31, 31, 0, 0, 0, 2, 2], #Daisangen
[0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 8, 1], #Churenpoto
[19, 19, 20, 20, 21, 21, 23, 23, 23, 25, 25, 32, 32, 32], #Ryu-so
[0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 5, 0, 1, 2], #Chinitsu Ittsu Epaco
]
@classmethod
def tehai_from_indexes(cls, indexes):
assert(len(indexes) == 13 or len(indexes) == 14)
return Tehai([ Pai.from_index(x) for x in indexes ])
@classmethod
def test_tehai(cls, idx = None):
if not idx:
#14 selbst gemacht
yama = Yama()
return Tehai([ yama.tsumo() for x in range(14) ])
else:
return cls.tehai_from_indexes(cls.TEST_TEHAIS[idx])
Probieren Sie es mit Ihren eigenen Händen aus!
Recommended Posts