Es ist kein Algorithmus, um die Anzahl der Hörungen zu ermitteln, der prüft, ob die Fertigstellung von 14 Handarbeiten abgeschlossen ist.
ONE-HOT wird für die Daten der Kacheln verwendet. Ich habe ONE-HOT gewählt, weil es einfacher ist, den Kopf und die Gravur zu beurteilen, wenn die Summe der ONE-HOT-Sequenzen in Zeilenrichtung genommen wird.
# ONE-HOT Expression Handwerk
[
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
]
#Nehmen Sie die Summe in Zeilenrichtung
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 1, 1, 1, 4, 1, 1, 0, 0, 0, 0, 0, 0, 0]
#Zur Beurteilung der Gravur werden 3 oder mehr Teile verwendet
# [1, 1, 1]Falten Sie es ein und verwenden Sie 3 oder mehr Teile, um Junko zu beurteilen.
#Es gibt Vorteile wie (ich denke)
Überprüfen Sie, ob der Abschluss mit dem oben beschriebenen Verfahren abgeschlossen ist.
import itertools
import multiprocessing
import numpy as np
import os
import sys
import time
# m1-m9, p1-p9, s1-s9, dw, dg, dr, we, ww, ws, wn
#Drei Elemente = Drache
#Wind = Wind
tileKeyIndex = [
"m1", "m2", "m3", "m4", "m5", "m6", "m7", "m8", "m9",
"p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9",
"s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9",
"dw", "dg", "dr",
"we", "ww", "ws", "wn",
]
MTileBits = [
1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0,
0, 0, 0, 0
]
PTileBits = [
0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0,
0, 0, 0, 0
]
STileBits = [
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0,
0, 0, 0, 0
]
DTileBits = [
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1,
0, 0, 0, 0
]
WTileBits = [
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0,
1, 1, 1, 1
]
KokusiBits = [
1, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 1,
1, 1, 1, 1
]
KokusiBits = np.array(KokusiBits)
# m1m2m3m4m5m6m7m8m9s1s2s3wnwn
def parseTehai(s):
if len(s) != 28:
print("error in {}, len(s)={}".format(sys._getframe().f_code.co_name, len(s)))
sys.exit()
tileMatrix = np.zeros((14, len(tileKeyIndex)))
for i in range(14):
pos = i * 2
idx = tileKeyIndex.index(s[pos:pos + 2])
tileMatrix[i][idx] = 1
return tileMatrix
def isShuntsuCompleted(tileMatrix):
indexes = []
for tbits in [MTileBits, PTileBits, STileBits]:
target = tileMatrix * tbits
while True:
targetB = (target != 0).astype(int) # [1, 1, 2]Konvertieren Sie alle in 1, um ein solches Array zu vermeiden
b = np.convolve(targetB, [1, 1, 1], mode="valid")
if np.max(b) != 3:
break
idxs = np.where(b == 3)[0]
idx = idxs[0]
target[idx:idx + 3] -= 1 #Entfernen Sie die inspizierte Fliese
indexes = indexes + list(np.arange(idx, idx + 3, 1))
return indexes
def isCompleted(tileMatrix):
rowSum = np.sum(tileMatrix, axis=0)
headerIdxs = np.where(rowSum >= 2)[0]
atama, kotsu, shuntsu = [], [], []
#Cheet Toys
if len(headerIdxs) == 7:
return 1, list(headerIdxs) * 2, [], []
#Kokushi
kokusiCheck = (rowSum != 0).astype(int)
if np.sum(kokusiCheck * KokusiBits) == 13 and np.sum(rowSum * KokusiBits) == 14:
return 1, np.where(np.array(KokusiBits) == 1)[0], [], []
#Befestigen Sie den Kopf
#Alle Gravurmuster werden im Voraus ausgegeben, und Junko wird durch Fixieren jedes Musters überprüft.
for hidx in headerIdxs:
#Erstellen Sie eine Kopie, damit Sie das ursprüngliche Array nicht manipulieren
calcBuffer = np.array(rowSum)
#Den Kopf loswerden
calcBuffer[hidx] -= 2
#Erkennen Sie alle möglichen Gravuren
kotsuPos = np.where(calcBuffer >= 3)[0]
#Nur eine der erkannten Gravuren ist gültig, nur zwei der erkannten Gravuren sind gültig ... Erstellen Sie alle Muster aller erkannten Gravuren.
kotsuPatterns = []
for i in range(len(kotsuPos)):
comb = list(itertools.combinations(kotsuPos, i + 1))
kotsuPatterns = kotsuPatterns + comb
#Fügen Sie ein Muster hinzu, für das keine Gravur gültig ist
kotsuPatterns.append(None)
for kotsuIndexes in kotsuPatterns:
#Erstellen Sie eine Kopie, damit Sie das ursprüngliche Array nicht manipulieren
calcBuffer2 = np.array(calcBuffer)
if isinstance(kotsuIndexes, type(None)):
pass
else:
#Entfernen Sie die Gravur
for kidx in kotsuIndexes:
calcBuffer2[kidx] -= 3
#Junko
shuntsuIndexes = isShuntsuCompleted(calcBuffer2)
for idx in shuntsuIndexes:
#Werde Junko los
calcBuffer2[idx] -= 1
#Wenn nach dem Entfernen des Kopfes, der Gravur und von Junko keine Kacheln mehr vorhanden sind, ist der Vorgang abgeschlossen.
#print("np.sum(calcBuffer)", np.sum(calcBuffer2))
if np.sum(calcBuffer2) == 0:
atama.append(np.full(2, hidx))
kotsu.append(kotsuIndexes)
shuntsu.append(shuntsuIndexes)
return len(atama), atama, kotsu, shuntsu
def Test1():
#2333345677778
#2333344567888
#2345666777888
#3344455566777
#2223344455677
#1112345556677
#4556677888999
#Warten auf 1425869
#Warten auf 14725869
#Warten auf 1245678
#Warten auf 36258
#Warten auf 6257
#Warten auf 672583
#Warten auf 789436
#tileMatrix = parseTehai("m1m2m3m4m5m6m7m8m9s1s2s3wnwn")
#tileMatrix = parseTehai("wewewewwwwwwwswswsm9m9m9s1s1")
#tileMatrix = parseTehai("s2s3s3s3s3s4s5s6s7s7s7s7s8s9") # s1, s2, s4, s5, s6, s8, s9
#tileMatrix = parseTehai("m2m3m3m3m3m4m4m5m6m7m8m8m8m1") #
#tileMatrix = parseTehai("m2m3m4m5m6m6m6m7m7m7m8m8m8?")
#tileMatrix = parseTehai("m3m3m4m4m4m5m5m5m6m6m7m7m7?")
#tileMatrix = parseTehai("p2p2p2p3p3p4p4p4p5p5p6p7p7?")
#tileMatrix = parseTehai("p1p1p1p2p3p4p5p5p5p6p6p7p7?")
#tileMatrix = parseTehai("p4p5p5p6p6p7p7p8p8p8p9p9p9?")
tileMatrix = parseTehai("m1m9p1p9s1s9wewswwwndwdgdrm1")
completeCount, atama, kotsu, shuntsu = isCompleted(tileMatrix)
if completeCount > 0:
print("OK")
print(atama)
print(kotsu)
print(shuntsu)
else:
print("NG")
def tileMatrixToTehaiString(tileMatrix):
s = ""
for r in tileMatrix:
idx = np.where(r == 1)[0][0]
s += tileKeyIndex[idx]
return s
def appendFile(fileName, data):
with open(fileName, mode="a") as f:
f.write(data + "\n")
def TenhohTestSub(args):
seed = time.time()
seed = int((seed - int(seed)) * 10000000)
np.random.seed(seed)
instanceId, tryCount = args
size = len(tileKeyIndex)
allTile = []
for i in range(size):
tmp = [0] * size
tmp[i] = 1
for n in range(4):
allTile.append(tmp)
for i in range(tryCount):
np.random.shuffle(allTile)
tiles = np.array(allTile[:14])
completeCount, atama, kotsu, shuntsu = isCompleted(tiles)
if completeCount > 0:
tehaiStr = tileMatrixToTehaiString(tiles)
appendFile("tenhoh_{}.txt".format(instanceId), tehaiStr)
def TenhohTest():
#TenhohTestSub(1, 400000)
tryCount = 1000000
args = []
for i in range(4):
args.append([i, tryCount])
with multiprocessing.Pool(4) as p:
p.map(TenhohTestSub, args)
def main():
#Test1()
TenhohTest()
if __name__ == "__main__":
main()
# python main.py
def main():
#Test1()
TenhohTest()
Test1 () überprüft die manuell vorbereitete Punktzahl im Quellcode. In TenhohTest () werden 4 Kerne verwendet, um zufällig eine Punktzahl 1 Million Mal pro Kern zu erstellen. Wenn es sich um eine Gewinnform handelt, wird diese aufgezeichnet, und die Aufzeichnung wird mit einer Nummer für jeden Kern wie "tenhoh_0.txt" aufgezeichnet. ..
Ist es Tenwa mit dem unten hinzugefügten Bildkonvertierungsprogramm? Sie können die von Ihnen erzielte Punktzahl visualisieren.
Wir werden ein Programm veröffentlichen, um Text abzubilden. Die Verwendung wird später beschrieben.
import PIL.Image
import os
import sys
tileKeyIndex = [
"m1", "m2", "m3", "m4", "m5", "m6", "m7", "m8", "m9",
"p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9",
"s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9",
"dw", "dg", "dr",
"we", "ww", "ws", "wn",
]
haiImageNames = [
"p_ms1_1.gif", "p_ms2_1.gif", "p_ms3_1.gif", "p_ms4_1.gif", "p_ms5_1.gif", "p_ms6_1.gif", "p_ms7_1.gif", "p_ms8_1.gif", "p_ms9_1.gif",
"p_ps1_1.gif", "p_ps2_1.gif", "p_ps3_1.gif", "p_ps4_1.gif", "p_ps5_1.gif", "p_ps6_1.gif", "p_ps7_1.gif", "p_ps8_1.gif", "p_ps9_1.gif",
"p_ss1_1.gif", "p_ss2_1.gif", "p_ss3_1.gif", "p_ss4_1.gif", "p_ss5_1.gif", "p_ss6_1.gif", "p_ss7_1.gif", "p_ss8_1.gif", "p_ss9_1.gif",
"p_no_1.gif", "p_ji_h_1.gif", "p_ji_c_1.gif",
"p_ji_e_1.gif", "p_ji_w_1.gif", "p_ji_s_1.gif", "p_ji_n_1.gif",
]
def parseTehai(s):
if len(s) != 28:
print("error in {}, len(s)={}".format(sys._getframe().f_code.co_name, len(s)))
sys.exit()
indexes, tehai = [], []
for i in range(14):
pos = i * 2
idx = tileKeyIndex.index(s[pos:pos + 2])
indexes.append(idx)
tehai.append(s[pos:pos + 2])
return indexes, tehai
def enumFile():
files = []
for v in os.listdir("./"):
if os.path.isfile(v) and v.startswith("tenhoh_"):
files.append(v)
return files
def readFile(fileName):
with open(fileName, "r") as f:
return f.read()
def tileIndexesToImage(indexes):
images = []
for idx in indexes:
imageFile = os.path.join("./images", haiImageNames[idx])
im = PIL.Image.open(imageFile)
images.append(im)
imageWidth = 0
maxHeight = 0
for im in images:
imageWidth += im.width
if im.height > maxHeight:
maxHeight = im.height
dst = PIL.Image.new('RGB', (imageWidth, maxHeight))
for i, im in enumerate(images):
dst.paste(im, (im.width * i, 0))
return dst
def main():
files = enumFile()
for f in files:
lines = readFile(f).split("\n")
basename = os.path.basename(f)
basename, _ = os.path.splitext(basename)
for j, l in enumerate(lines):
if len(l) < 28:
continue
indexes, tehai = parseTehai(l)
indexes = sorted(indexes)
image = tileIndexesToImage(indexes)
destFile = "{}_{:03d}.png ".format(basename, j)
destFile = os.path.join("./dest", destFile)
image.save(destFile)
if __name__ == "__main__":
main()
# https://mj-king.net/sozai/
# python tehai_2_image.py
Die Datei "tenhoh _ ???. Txt" im selben Ordner wird automatisch gelesen und das Bild wird basierend auf dem Bild in ./images an ./dest ausgegeben.
** m7s5p2p6s7p4m6p7s6p5m5p2p5p6 **
↓
Sortieren und konvertieren Sie das Bild auf diese Weise.
Entpacken Sie die von "Manko 2", "Tsutsuko 2", "Ryoko 2" und "Character 2" heruntergeladenen Bilddaten in ./images.
Die Ordnerstruktur sieht folgendermaßen aus: D: \ tmp ist der Programmordner.
Erstellen Sie im Voraus einen Ordner für die Ausgabe
python tehai_2_image.py
Bei normaler Ausführung wird die abgebildete Partitur an ./dest ausgegeben.
das ist alles.
Recommended Posts