现在我们有了排序的过程,我们将创建判断完成的过程。
…但是那很困难。
我担心的是如何用Python编写,而不是首先考虑哪种逻辑。
我提到过很多网站,但是
我想成为一名真正的工程师的网站最容易理解。
完成判断
考虑到Seiichi的情况,简单的逻辑不起作用。
(可能无法用Junko制作面孔或刻有雕刻的面孔。)
,但是使用以下逻辑创建进程似乎很好。
①首先,提取麻雀图案
(2)确定是否可以用麻雀头以外的其他12个瓷砖制作四面瓷砖。
当雕刻机的数量为0,为1时,为2时,判断是否可以形成四面。
分为3和4种情况。
在程序中编写时会看起来像以下内容吗?
1 2 3 4 5 6 7 8 9 10 11 12 | tehai = [,,,] # 手牌を格納する配列型の変数 14個の牌を格納 # 雀頭の候補 l_janto = find_janto(tehai) # 手牌から雀頭となり得る牌を返却 # 4面子作れるかの判定 for janto in l_janto: # 雀頭の候補ごとに4面子作れるか判定する agari_koutsu0(tehai)# 刻子が0個のパターンの判定 agari_koutsu1(tehai)# 刻子が1個のパターンの判定 agari_koutsu2(tehai)# 刻子が2個のパターンの判定 agari_koutsu3(tehai)# 刻子が3個のパターンの判定 agari_koutsu4(tehai)# 刻子が4個のパターンの判定 |
我想知道是否可以在不考虑Chiitoitsu或Kokushi Musou的情况下使用以上逻辑。
Web应用程序
我用上述逻辑做出了判断逻辑,并将其整合到Flask框架中。
在浏览器上显示14个图块,丢弃单击的图块,然后拾取新的图块。
感觉很简单。
main.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | from flask import Flask import mahjong app = Flask(__name__) yamahai = [] tehai = [] # 配牌 @app.route('/') def main(): global tehai global yamahai yamahai = mahjong.create_yamahai() tehai = [yamahai.pop(0) for i in range(14)] # 配牌 tehai.sort(key=lambda hai: hai.sort_info()) # 理牌 # 画像表示 return ''.join(map(lambda i: f'<a href="/change/{i}"><img src=/static/pic/{tehai[i].pic}></a>', range(len(tehai)))) # 自摸 @app.route('/change/<int:position>') def change(position): tehai.pop(position) # 打牌 tehai.sort(key=lambda hai: hai.sort_info()) # 理牌 tehai.append(yamahai.pop(0)) # 自摸 if mahjong.judge(tehai): # あがり判定 return ''.join(map(lambda i: f'<img src=/static/pic/{tehai[i].pic}>', range(len(tehai) - 1))) \ + f' <img src=/static/pic/{tehai[len(tehai) - 1].pic}>' \ + f'<br><a href="/"><img src=/static/pic/win.png></a>' else: return ''.join(map(lambda i: f'<a href="/change/{i}"><img src=/static/pic/{tehai[i].pic}></a>', range(len(tehai) - 1)))\ + f' <a href="/change/{len(tehai) - 1}"><img src=/static/pic/{tehai[len(tehai) - 1].pic}></a>' if __name__ == '__main__': app.run(port=8080) |
当访问
上下文根('/')时,
执行def main()分发第一个Tehai。
链接附加到图块图像,因此,如果按图块图像,
定义更改(位置)被执行,被按下的图块将被丢弃,并拾取新的图块。
由于命中判断是通过def变化(位置)做出的,因此
如果命中,将显示其周围的图像。
印象数
暂时,我觉得它已经形成了。
我感觉它已经变了,但是似乎还有很多改进。
?因为yamahai和tehai被设置为全局变量,所以它非常适合一个人。
我想将其提高到aws和heroku,因为这很重要。
我想使用智能手机。
?我不知道是否还有剩余的图块,因为未显示丢弃的图块。
我还希望您判断上升的作用。
我也想计算分数。
我想实施影响力判断(临时判断)。
首先使用python使其有意义吗?
客户端JavaScript 而不是在服务器上一一做出判断
这样做更好吗?
或者说,永远单独打麻将有什么乐趣...?
您会找时间尝试各种事情吗?
奖金
命中判断程序
麻将
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 | import random import copy # 麻雀牌のクラス class Tile: SUUPAI = 'pinzu', 'manzu', 'souzu' JIHAI = 'sufonpai', 'sangenpai' WINDS = '東南西北' COLORS = '白發中' def __init__(self, kind, value): self.kind = kind # 麻雀牌の種類(萬子?筒子?索子?四風牌?三元牌) self.value = value # 麻雀牌の値(1~9 東南西北白発中) self.pic = f'{kind}_{value}.png' # 画像ファイル名 def __repr__(self): return self.pic def __eq__(self, other): if not isinstance(other, Tile): return False return self.pic == other.pic def __hash__(self): return hash(self.pic) def sort_info(self): if Tile.SUUPAI[0] == self.kind: return f'0_{self.value}' elif Tile.SUUPAI[1] == self.kind: return f'1_{self.value}' elif Tile.SUUPAI[2] == self.kind: return f'2_{self.value}' elif Tile.JIHAI[0] == self.kind: return f'3_{self.value}' elif Tile.JIHAI[1] == self.kind: return f'4_{self.value}' # 山牌 シャッフルされた136個のTileオブジェクトリストを返却 def create_yamahai(): tiles = [Tile(kind, str(value)) for kind in Tile.SUUPAI for value in range(1, 1 + 9)] tiles += [Tile(Tile.JIHAI[0], value) for value, label in enumerate(Tile.WINDS, 1)] tiles += [Tile(Tile.JIHAI[1], value) for value, label in enumerate(Tile.COLORS, 1)] tiles *= 4 random.shuffle(tiles) random.shuffle(tiles) random.shuffle(tiles) return tiles # 通常あがり牌 class Agari: def __init__(self, janto, mentsu1, mentsu2, mentsu3, mentsu4): self.janto = janto self.mentsu1 = mentsu1 self.mentsu2 = mentsu2 self.mentsu3 = mentsu3 self.mentsu4 = mentsu4 def __repr__(self): return f'[{repr(self.janto[0])},{repr(self.janto[1])}],' \ f'[{repr(self.mentsu1.tiles[0])},{repr(self.mentsu1.tiles[1])},{repr(self.mentsu1.tiles[2])}],' \ f'[{repr(self.mentsu2.tiles[0])},{repr(self.mentsu2.tiles[1])},{repr(self.mentsu2.tiles[2])}],' \ f'[{repr(self.mentsu3.tiles[0])},{repr(self.mentsu3.tiles[1])},{repr(self.mentsu3.tiles[2])}],' \ f'[{repr(self.mentsu4.tiles[0])},{repr(self.mentsu4.tiles[1])},{repr(self.mentsu4.tiles[2])}]' class Janto: def __init__(self, tiles): self.tiles = tiles class Mentsu: KIND = 'syuntsu', 'koutsu' def __init__(self, kind, tiles): self.kind = kind self.tiles = tiles class NoMentsu(Exception): pass # 七対子 class Titoitsu: def __init__(self, l_toitsu): self.l_toitsu = l_toitsu def __repr__(self): return f'[{repr(self.l_toitsu[0])},{repr(self.l_toitsu[0])}],' \ f'[{repr(self.l_toitsu[1])},{repr(self.l_toitsu[1])}],' \ f'[{repr(self.l_toitsu[2])},{repr(self.l_toitsu[2])}],' \ f'[{repr(self.l_toitsu[3])},{repr(self.l_toitsu[3])}],' \ f'[{repr(self.l_toitsu[4])},{repr(self.l_toitsu[4])}],' \ f'[{repr(self.l_toitsu[5])},{repr(self.l_toitsu[5])}],' \ f'[{repr(self.l_toitsu[6])},{repr(self.l_toitsu[6])}]' # 国士無双 class Kokushimusou: def __init__(self, l_tile): self.l_tile = l_tile def __repr__(self): return f'{self.l_tile}' def judge(tehai): agari_hai = [] # 雀頭の種類 l_janto = sorted([x for x in set(tehai) if tehai.count(x) >= 2], key=lambda hai: f'{hai.kind}{hai.value}') if len(l_janto) == 0: return agari_hai # 国士無双 if check_kokushimusou(tehai, l_janto): return Kokushimusou(tehai) # 七対子 if len(l_janto) == 7: agari_hai.append(Titoitsu(l_janto)) # 通常役 for janto in l_janto: mentsu_kouho = copy.deepcopy(tehai) mentsu_kouho.remove(janto) mentsu_kouho.remove(janto) mentsu_kouho.sort(key=lambda hai: f'{hai.kind}{hai.value}') # 刻子の種類 l_koutsu = sorted([x for x in set(mentsu_kouho) if mentsu_kouho.count(x) >= 3], key=lambda hai: f'{hai.kind}{hai.value}') # 刻子が0個のパターン agari_hai.extend(agari_koutsu0(mentsu_kouho, janto)) # 刻子が1個のパターン agari_hai.extend(agari_koutsu1(mentsu_kouho, janto, l_koutsu)) # 刻子が2個のパターン agari_hai.extend(agari_koutsu2(mentsu_kouho, janto, l_koutsu)) # 刻子が3個のパターン agari_hai.extend(agari_koutsu3(mentsu_kouho, janto, l_koutsu)) # 刻子が4個のパターン agari_hai.extend(agari_koutsu4(janto, l_koutsu)) return len(agari_hai) > 0 # 刻子が0個のあがりパターン def agari_koutsu0(mentsu_kouho, janto): try: hanteiyou = copy.deepcopy(mentsu_kouho) first = find_one_syuntu(hanteiyou) hanteiyou.remove(first.tiles[0]) hanteiyou.remove(first.tiles[1]) hanteiyou.remove(first.tiles[2]) second = find_one_syuntu(hanteiyou) hanteiyou.remove(second.tiles[0]) hanteiyou.remove(second.tiles[1]) hanteiyou.remove(second.tiles[2]) third = find_one_syuntu(hanteiyou) hanteiyou.remove(third.tiles[0]) hanteiyou.remove(third.tiles[1]) hanteiyou.remove(third.tiles[2]) fourth = find_one_syuntu(hanteiyou) return [Agari([janto for x in range(2)], first, second, third, fourth)] except NoMentsu: return [] # 刻子が1個のあがりパターン def agari_koutsu1(mentsu_kouho, janto, l_koutsu): if len(l_koutsu) < 1: return [] result = [] for koutsu in l_koutsu: try: hanteiyou = copy.deepcopy(mentsu_kouho) first = Mentsu(Mentsu.KIND[1], [koutsu for x in range(3)]) hanteiyou.remove(first.tiles[0]) hanteiyou.remove(first.tiles[1]) hanteiyou.remove(first.tiles[2]) second = find_one_syuntu(hanteiyou) hanteiyou.remove(second.tiles[0]) hanteiyou.remove(second.tiles[1]) hanteiyou.remove(second.tiles[2]) third = find_one_syuntu(hanteiyou) hanteiyou.remove(third.tiles[0]) hanteiyou.remove(third.tiles[1]) hanteiyou.remove(third.tiles[2]) fourth = find_one_syuntu(hanteiyou) result.append(Agari([janto for x in range(2)], first, second, third, fourth)) except NoMentsu: continue return result # 刻子が2個のあがりパターン def agari_koutsu2(mentsu_kouho, janto, l_koutsu): if len(l_koutsu) < 2: return [] result = [] for i in range(len(l_koutsu) - 1): for j in range(i + 1, len(l_koutsu)): try: hanteiyou = copy.deepcopy(mentsu_kouho) first = Mentsu(Mentsu.KIND[1], [l_koutsu[i] for x in range(3)]) hanteiyou.remove(first.tiles[0]) hanteiyou.remove(first.tiles[1]) hanteiyou.remove(first.tiles[2]) second = Mentsu(Mentsu.KIND[1], [l_koutsu[j] for x in range(3)]) hanteiyou.remove(second.tiles[0]) hanteiyou.remove(second.tiles[1]) hanteiyou.remove(second.tiles[2]) third = find_one_syuntu(hanteiyou) hanteiyou.remove(third.tiles[0]) hanteiyou.remove(third.tiles[1]) hanteiyou.remove(third.tiles[2]) fourth = find_one_syuntu(hanteiyou) result.append(Agari([janto for x in range(2)], first, second, third, fourth)) except NoMentsu: continue return result # 刻子が3個のあがりパターン def agari_koutsu3(mentsu_kouho, janto, l_koutsu): if len(l_koutsu) != 3: return [] try: hanteiyou = copy.deepcopy(mentsu_kouho) first = Mentsu(Mentsu.KIND[1], [l_koutsu[0] for x in range(3)]) hanteiyou.remove(first.tiles[0]) hanteiyou.remove(first.tiles[1]) hanteiyou.remove(first.tiles[2]) second = Mentsu(Mentsu.KIND[1], [l_koutsu[1] for x in range(3)]) hanteiyou.remove(second.tiles[0]) hanteiyou.remove(second.tiles[1]) hanteiyou.remove(second.tiles[2]) third = Mentsu(Mentsu.KIND[1], [l_koutsu[2] for x in range(3)]) hanteiyou.remove(third.tiles[0]) hanteiyou.remove(third.tiles[1]) hanteiyou.remove(third.tiles[2]) fourth = find_one_syuntu(hanteiyou) return [Agari([janto for x in range(2)], first, second, third, fourth)] except NoMentsu: return [] # 刻子が4個のあがりパターン def agari_koutsu4(janto, l_koutsu): if len(l_koutsu) != 4: return [] return [Agari([janto for x in range(2)], Mentsu(Mentsu.KIND[1], [l_koutsu[0] for x in range(3)]), Mentsu(Mentsu.KIND[1], [l_koutsu[1] for x in range(3)]), Mentsu(Mentsu.KIND[1], [l_koutsu[2] for x in range(3)]), Mentsu(Mentsu.KIND[1], [l_koutsu[3] for x in range(3)]))] # 国士無双のチェック(前提として雀頭があること) def check_kokushimusou(tehai, l_koutsu): if len(l_koutsu) != 1: return [] if Tile(Tile.SUUPAI[0], '1') in tehai \ and Tile(Tile.SUUPAI[0], '9') in tehai \ and Tile(Tile.SUUPAI[1], '1') in tehai \ and Tile(Tile.SUUPAI[1], '9') in tehai \ and Tile(Tile.SUUPAI[2], '1') in tehai \ and Tile(Tile.SUUPAI[2], '9') in tehai \ and Tile(Tile.JIHAI[0], Tile.WINDS[0]) in tehai \ and Tile(Tile.JIHAI[0], Tile.WINDS[1]) in tehai \ and Tile(Tile.JIHAI[0], Tile.WINDS[2]) in tehai \ and Tile(Tile.JIHAI[0], Tile.WINDS[3]) in tehai \ and Tile(Tile.JIHAI[1], Tile.COLORS[0]) in tehai \ and Tile(Tile.JIHAI[1], Tile.COLORS[1]) in tehai \ and Tile(Tile.JIHAI[1], Tile.COLORS[2]) in tehai: return True # 順子をひとつ見つける def find_one_syuntu(hanteiyou): hanteiyou.sort(key=lambda hai: f'{hai.kind}{hai.value}') for hanteiyou_one_tile in hanteiyou: syuntsu_kouho = create_syuntsu(hanteiyou_one_tile) if syuntsu_kouho is None: continue if syuntsu_kouho[1] in hanteiyou and syuntsu_kouho[2] in hanteiyou: return Mentsu(Mentsu.KIND[0], syuntsu_kouho) raise NoMentsu() # 自身を一番最初とした順子を返却 def create_syuntsu(tile): if tile.kind in Tile.SUUPAI and int(tile.value) <= 7: return [Tile(tile.kind, str(value)) for value in range(int(tile.value), int(tile.value) + 3)] def test(): l_haipai = [] for pattern in ['23333444556688', '22333456667788', '22344445556677', '11123334445577', '22223333444556', '11222345556677', '22333344555667', '11333445566678', '11122223334455', '22555566677788', '23333444555566', '22566667778899', '22444567778899', '22444455666778', '12222333445599', '22223344455688', '11123334445555', '33344555566678', '44455667778999', '11112233344566', '11444556667778', '11225566778899', '44445555666778', '12222333445588', '22234555667777', '33345666778888', '11122334445666', '22223334445588', '33345666777788', '11122334445677', '22233345556677', '11223344667799', '11123444555566', '44455567778899', '33444455666778', '22234445556666', '11222334455567', '44456667778888', '11123344455688', '11222334445556', '11444566777889', '11123334445588', '11333344555667', '22234555666677', '11122333444566', '44566667778899', '55666677788899', '33334455566799', '11555667778889', '11333455566677', '22223344455699', '33344445556677', '33555566777889', '22233445556799', '11122333444588', '11122223344456', '22223334445599', '34444555666677', '44445566677899', '55556666777889', '22444556677789', '11122333444599', '11112223334499', '11334455667799', '33345566677899', '11123344455666', '33334445556699', '33444566777889', '11122233444556', '11666677788899', '33344555666788', '22233334445556', '11123334445566', '11566667778899', '11224466778899', '11224455667799', '22444556667778', '12222333444455', '22234445556677', '33444455566677', '22333344455566', '11123334445599', '33444556677789', '11122333444577', '11112223334466', '11122223334445', '22234455566667', '22223334445577', '11223355668899', '11444455666778', '11123444556688', '44555667778889', '11122334445699', '11333456667788', '11112223334488', '55566667778889', '11233334445566', '11334455668899', '33345556667799', '22233344555667', '34444555667799', '11223344557799', '11224455667788', '22333445556667', '22234445556688', '22234444555667', '11224455668899', '22234555667799', '11112233344599', '33344445556667', '44445566677888', '11112223334477', '55556677788999', '11112233344588', '11112222333445', '22234455566799', '11123444556699', '33555667778889', '22333445566678', '33566667778899', '12222333445577', '22444566777889', '22233444455567', '44455666677789', '22555677788899', '44455556677789', '44555566777889', '22233445556788', '11224455778899', '44455566777889', '33444567778899', '11444566677788', '44456667778899', '22335566778899', '33334444555667', '11223344668899', '22234455566777', '44456777888899', '33344556667899', '44455556667778', '11223344557788', '33666677788899', '11112233344555', '55567778889999', '11444455566677', '11455556667788', '33345556667788', '33344456667788', '22233444555699', '44555566677788', '11222233444556', '11122333344456', '11344445556677', '11222344555667', '44445556667799', '33555677788899', '22233444555677', '11123344455699', '11333445556667', '44456677788889', '22333455666778', '33455556667788', '11123344455556', '11334466778899', '33555566677788', '11444556677789', '44456677788999', '11122234445566', '22555667778889', '22455556667788', '33444556667778', '22233445556777', '33344445566678', '11555566677788', '33344555666799', '22555566777889', '33345566677778', '33345556667777', '33334455566788', '22233334455567', '22234445556699', '33334445556688', '11333344455566', '44455556667788', '33345566677888', '11123333444556', '33344556667888', '11222344455566', '33345555666778', '22234455566788', '22333455566677', '44455666777899', '23333444556699', '11333455666778', '11223344558899', '11444567778899', '11335566778899', '33334455566777', '45555666777788', '44456666777889', '11123344455677', '33444566677788', '11123444556666', '22444455566677', '22223344455666', '22233444555688', '11222233344455', '44456777889999', '44555677788899', '22444566677788', '22666677788899', '22233334445566', '44666677788899', '11122334445688', '22334455668899', '33344455666778', '56666777888899', '11555566777889', '55566667778899', '11112233344577', '22223344455677', '11555677788899']: l_haipai.append([Tile('manzu', value) for value in list(pattern)]) l_haipai.append( [Tile(Tile.SUUPAI[0], '1'), Tile(Tile.SUUPAI[0], '9'), Tile(Tile.SUUPAI[1], '1'), Tile(Tile.SUUPAI[1], '9'), Tile(Tile.SUUPAI[2], '1'), Tile(Tile.SUUPAI[2], '9'), Tile(Tile.JIHAI[0], Tile.WINDS[0]), Tile(Tile.JIHAI[0], Tile.WINDS[1]), Tile(Tile.JIHAI[0], Tile.WINDS[2]), Tile(Tile.JIHAI[0], Tile.WINDS[3]), Tile(Tile.JIHAI[1], Tile.COLORS[0]), Tile(Tile.JIHAI[1], Tile.COLORS[1]), Tile(Tile.JIHAI[1], Tile.COLORS[2]), Tile(Tile.SUUPAI[0], '1')]) for haipai in l_haipai: print(f'配牌:{haipai}') print(f'上り:{judge(haipai)}') if __name__ == '__main__': test() |