Ce n'est pas un algorithme pour trouver le nombre d'écoutes, qui vérifie si l'achèvement de 14 travaux manuels est terminé.
ONE-HOT est utilisé pour les données des tuiles J'ai choisi ONE-HOT car il est plus facile de juger la tête et la gravure si la somme des séquences ONE-HOT est prise dans le sens des rangées.
# ONE-Artisanat d'expression à chaud
[
[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]
]
#Prenez la somme dans le sens de la ligne
[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]
#3 pièces ou plus seront utilisées pour juger de la gravure
# [1, 1, 1]Pliez-le et utilisez 3 parties ou plus pour juger Junko.
#Il y a des avantages tels que (je pense)
Vérifiez si l'achèvement est terminé par la procédure ci-dessus.
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
#Trois éléments = Dragon
#Vent = Vent
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]Convertissez tout en 1 pour éviter un tel tableau
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 #Retirer la tuile inspectée
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 Jouets
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], [], []
#Fixer la tête
#Tous les motifs de gravure sont imprimés à l'avance et Junko est inspecté en fixant chaque motif.
for hidx in headerIdxs:
#Faites une copie pour ne pas manipuler le tableau d'origine
calcBuffer = np.array(rowSum)
#Débarrassez-vous de la tête
calcBuffer[hidx] -= 2
#Détecter toutes les gravures possibles
kotsuPos = np.where(calcBuffer >= 3)[0]
#Une seule des gravures détectées est valide, seuls deux des graveurs détectés sont valides ... Créez tous les motifs de toutes les gravures détectées
kotsuPatterns = []
for i in range(len(kotsuPos)):
comb = list(itertools.combinations(kotsuPos, i + 1))
kotsuPatterns = kotsuPatterns + comb
#Ajouter un motif pour lequel aucune gravure n'est valide
kotsuPatterns.append(None)
for kotsuIndexes in kotsuPatterns:
#Faites une copie pour ne pas manipuler le tableau d'origine
calcBuffer2 = np.array(calcBuffer)
if isinstance(kotsuIndexes, type(None)):
pass
else:
#Retirer la gravure
for kidx in kotsuIndexes:
calcBuffer2[kidx] -= 3
#Junko
shuntsuIndexes = isShuntsuCompleted(calcBuffer2)
for idx in shuntsuIndexes:
#Débarrassez-vous de Junko
calcBuffer2[idx] -= 1
#S'il ne reste plus de tuiles après avoir retiré la tête, la gravure et le Junko, c'est terminé.
#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
#En attente de 1425869
#En attente de 14725869
#En attente de 1245678
#En attente de 36258
#En attente de 6257
#En attente de 672583
#En attente de 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 () inspecte le score préparé manuellement dans le code source. Dans TenhohTest (), 4 cœurs sont utilisés pour créer aléatoirement un score 1 million de fois par cœur, et s'il s'agit d'une forme gagnante, un enregistrement est pris. L'enregistrement est enregistré avec un numéro pour chaque cœur tel que "tenhoh_0.txt". ..
Est-ce Tenwa en utilisant le programme de conversion d'image ajouté ci-dessous? Vous pouvez visualiser le score que vous avez réalisé.
Nous publierons un programme de texte image, son utilisation sera décrite plus loin.
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
Le fichier "tenhoh _ ???. Txt" dans le même dossier est lu automatiquement et l'image est sortie vers ./dest en fonction de l'image en ./images.
** m7s5p2p6s7p4m6p7s6p5m5p2p5p6 **
↓
Triez et convertissez l'image de cette manière.
Décompressez les données d'image téléchargées depuis «Manko 2», «Tsutsuko 2», «Ryoko 2» et «Character 2» dans ./images
La structure des dossiers ressemble à ceci, D: \ tmp est le dossier du programme.
Créer un dossier pour la sortie à l'avance
python tehai_2_image.py
Si elle est exécutée normalement, la partition imagée sera sortie vers ./dest.
c'est tout.
Recommended Posts