-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathchChess.py
1934 lines (1915 loc) · 102 KB
/
chChess.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
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
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
import os
import sys
from re import findall
from secrets import randbelow
from threading import Lock, Semaphore, Thread
os.chdir(os.path.abspath(os.path.dirname(__file__)))#解析进入程序所在目录
PLATFORM = __import__("platform").system().upper()
if PLATFORM == "WINDOWS":
from msvcrt import getch
else:
os.system("setfont /usr/share/consolefonts/Lat2-Terminus16.psf.gz")
import tty
import termios
def getch():
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return bytes(ch, encoding = "utf-8")
EXIT_SUCCESS = 0
EXIT_FAILURE = 1
if "idlelib" in sys.modules or not sys.stdin.isatty(): # 未检测到终端
print("未检测到终端,部分功能无法正常使用,请勿尝试在 IDE 或 IDLE 中启动本程序。")
input("请按下回车键退出。")
sys.exit(EXIT_FAILURE)
try:
from colorama import Fore, Back, Style, init as initColor
if PLATFORM == "WINDOWS" and sys.stdin.isatty(): # 在 Windows 终端
initColor(wrap = True) # Windows 终端
defaultFore = Fore.BLACK
foreRed = Fore.RED # 红方
foreBlack = Fore.GREEN # 黑方
foreRound = Fore.BLUE # 环绕颜色
print(defaultFore + Back.WHITE, end = Style.DIM)
except:
print("未能调用 colorama 库,请尝试在合适的环境中运行“pip install colorama”进行安装。")
print("程序将继续运行,但这可能会影响您的视觉效果,请按任意键继续。")
defaultFore = foreRed = foreBlack = foreRound = "" # 关闭颜色
getch()
try:
import pyttsx3
engine = pyttsx3.init()
del engine
lock = Lock() # 锁定 toSpeakList
lock.acquire()
toSpeakList = []
sem = Semaphore(0) # 信号量
lock.release()
def speak():
engine = pyttsx3.init()
while True:
sem.acquire() # 申请信号量(减少死循环)
lock.acquire()
if toSpeakList:
toSpeak = toSpeakList.pop(0) # 弹出第一个
lock.release()
if toSpeak:
engine.say(toSpeak)
engine.runAndWait()
else:
engine.say("欢迎再次使用!")
engine.runAndWait()
break
t = Thread(target = speak)
t.start()
def doSpeak(text):
lock.acquire()
global toSpeakList # 修改全局变量
toSpeakList.append(text)
lock.release()
sem.release() # 释放信号量
except:
def doSpeak(text): # 初始化失败,设置函数:什么也不干
pass
print("未能调用 pyttsx3 库,请尝试在合适的环境中运行“pip install pyttsx3”进行安装。")
print("程序将继续运行,但这可能会影响您的听觉效果,请按任意键继续。")
getch()
class Board:
mode_statement = { \
0b0000:"中国象棋不用电脑", \
0b0001:"中国象棋电脑执黑", \
0b0010:"中国象棋电脑执红", \
0b0011:"中国象棋电脑执双", \
0b0100:"中国象棋残局不用电脑", \
0b0101:"中国象棋残局电脑执黑", \
0b0110:"中国象棋残局电脑执红", \
0b0111:"中国象棋残局电脑执双", \
0b1000:"中国揭棋随机生成不用电脑", \
0b1001:"中国揭棋随机生成电脑执黑", \
0b1010:"中国揭棋随机生成电脑执红", \
0b1011:"中国揭棋随机生成电脑执双", \
0b1100:"中国揭棋人工指派不用电脑", \
0b1101:"中国揭棋人工指派电脑执黑", \
0b1110:"中国揭棋人工指派电脑执红", \
0b1111:"中国揭棋人工指派电脑执双" \
}
FEN_statement = { \
"rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C2C4/9/RNBAKABNR b":"中炮局(B00)", \
"rnbakab1r/9/1c4nc1/p1p1p1p1p/9/9/P1P1P1P1P/1C2C4/9/RNBAKABNR w":"中炮对进左马(B05)", \
"r1bakab1r/9/1cn3nc1/p1p1p1p1p/9/9/P1P1P1P1P/1C2C1N2/9/RNBAKAB1R w":"中炮对屏风马(C00)", \
"r1bakabr1/9/1cn3nc1/p1p1p1p1p/9/9/P1P1P1P1P/NC2C1N2/9/R1BAKABR1 b":"中炮左边马对屏风马(C05)", \
"r1bakabr1/9/1cn3nc1/p1p1p1p1p/9/9/P1P1P1P1P/1CN1C1N2/9/R1BAKABR1 b":"中炮七路马对屏风马(C01)", \
"r1bakabr1/9/1cn3nc1/p1p1p1p1p/9/9/P1P1P1P1P/3CC1N2/9/RNBAKABR1 b":"五六炮对屏风马(C50)", \
"r1bakabr1/9/1cn3nc1/p1p1p1p1p/9/7R1/P1P1P1P1P/1C2C1N2/9/RNBAKAB2 b":"中炮巡河车对屏风马——红不进左马(C15)", \
"r1bakab1r/9/1cn3nc1/p1p1p3p/6p2/2P6/P3P1P1P/1CN1C1N2/9/R1BAKAB1R b":"中炮七路马对屏风马(C01)", \
"r1bakab1r/9/1cn3nc1/p3p1p1p/2p6/6P2/P1P1P3P/1CN1C1N2/9/R1BAKAB1R b":"中炮七路马对屏风马(C01)", \
"r1bakab1r/9/1cn3nc1/p1p1p1p1p/9/9/P1P1P1P1P/1CN1C1N2/9/R1BAKAB1R b":"中炮七路马对屏风马(C01)", \
"rnbakab1r/9/1c4n1c/p1p1p1p1p/9/9/P1P1P1P1P/1C2C1N2/9/RNBAKAB1R w":"中炮右横车对左三步虎(B22)", \
"rnbakab1r/9/1c4n1c/p1p1p1p1p/9/9/P1P1P1P1P/1C2C1N2/8R/RNBAKAB2 b":"中炮对左三步虎(B20)", \
"r1bakabnr/9/1cn4c1/p1p1p1p1p/9/9/P1P1P1P1P/1C2C4/9/RNBAKABNR w":"中炮对进右马(B01)", \
"r1bakabnr/9/c1n4c1/p1p1p1p1p/9/9/P1P1P1P1P/1C2C1N2/9/RNBAKAB1R w":"中炮对右三步虎(B04)", \
"rnbakabnr/9/1c2c4/p1p1p1p1p/9/9/P1P1P1P1P/1C2C4/9/RNBAKABNR w":"顺炮缓开车局(D00)", \
"rnbakab1r/9/1c2c1n2/p1p1p1p1p/9/9/P1P1P1P1P/1C2C1N2/9/RNBAKABR1 b":"顺炮直车对缓开车(D10)", \
"rnbakab2/8r/1c2c1n2/p1p1p1p1p/9/9/P1P1P1P1P/1C2C1N2/9/RNBAKABR1 w":"顺炮直车对横车(D20)", \
"rnbakab2/8r/1c2c1n2/p1p1p1p1p/9/6P2/P1P1P3P/1C2C1N2/9/RNBAKABR1 b":"顺炮直车对横车——红进三兵(D26)", \
"rnbakab2/8r/1c2c1n2/p1p1p1p1p/9/9/P1P1P1P1P/3CC1N2/9/RNBAKABR1 b":"顺炮直车对横车——红仕角炮(D25)", \
"rnbakab2/8r/1c2c1n2/p1p1p1p1p/9/7R1/P1P1P1P1P/1C2C1N2/9/RNBAKAB2 b":"顺炮直车对横车——红巡河车(D23)", \
"rnbakab2/8r/1c2c1n2/p1p1p1p1p/9/9/P1P1P1P1P/NC2C1N2/9/R1BAKABR1 b":"顺炮直车对横车——红左边马(D22)", \
"rnbakab2/8r/1c2c1n2/p1p1p1p1p/9/2P6/P3P1P1P/1C2C1N2/9/RNBAKABR1 b":"顺炮直车对横车——红进七兵(D27)", \
"rnbakab2/8r/1c2c1n2/p1p1p1p1p/9/9/P1P1P1P1P/1C2C1N2/4A4/RNBAK1BR1 b":"顺炮直车对横车——红先上仕(D21)", \
"rnbakab1r/9/1c2c1n2/p1p1p1p1p/9/9/P1P1P1P1P/1C2C1N2/8R/RNBAKAB2 b":"顺炮横车对缓开车(D03)", \
"rnbakabr1/9/1c2c1n2/p1p1p1p1p/9/9/P1P1P1P1P/1C2C1N2/8R/RNBAKAB2 w":"顺炮横车对直车(D04)", \
"rnbakab2/9/1c2c1n2/p1p1p1p1p/7r1/9/P1P1P1P1P/1C2C1N2/3R5/RNBAKAB2 w":"顺炮横车对直车巡河(D05)", \
"rnbakab2/8r/1c2c1n2/p1p1p1p1p/9/6P2/P1P1P3P/1C2C1N2/9/RNBAKAB1R w":"顺炮缓开车对横车(D01)", \
"rnbakabr1/9/1c2c1n2/p1p1p1p1p/9/6P2/P1P1P3P/1C2C1N2/9/RNBAKAB1R w":"顺炮缓开车对直车(D02)", \
"rnbakabr1/9/1c2c1n2/p1p1p1p1p/9/9/P1P1P1P1P/1CN1C1N2/9/R1BAKAB1R w":"顺炮缓开车对直车(D02)", \
"rnbakab2/8r/1c2c1n2/p1p1p1p1p/9/9/P1P1P1P1P/1CN1C1N2/9/R1BAKAB1R w":"顺炮缓开车对横车(D01)", \
"rnbakabn1/8r/1c2c4/p1p1p1p1p/9/9/P1P1P1P1P/1C2C1N2/9/RNBAKAB1R w":"顺炮缓开车对横车(D01)", \
"rnbakabnr/9/1c2c4/p1p1p1p1p/9/9/P1P1P1P1P/1C2C4/8R/RNBAKABN1 b":"顺炮横车对缓开车(D03)", \
"rnbakabnr/9/4c2c1/p1p1p1p1p/9/9/P1P1P1P1P/1C2C4/9/RNBAKABNR w":"中炮对列炮(D50)", \
"rnbakabnr/9/1c5c1/p1p1p1p1p/9/6P2/P1P1P3P/1C5C1/9/RNBAKABNR b":"仙人指路(E00)", \
"rnbakabnr/9/1c4c2/p1p1p1p1p/9/6P2/P1P1P3P/1C5C1/9/RNBAKABNR w":"仙人指路对卒底炮(E10)", \
"rnbakabnr/9/1c4c2/p1p1p1p1p/9/6P2/P1P1P3P/4C2C1/9/RNBAKABNR b":"仙人指路转左中炮对卒底炮(E13)", \
"rnbaka1nr/9/1c2b1c2/p1p1p1p1p/9/6P2/P1P1P3P/4C2C1/9/RNBAKABNR w":"仙人指路转左中炮对卒底炮飞左象(E20)", \
"rnbaka1nr/9/1c2b1c2/p1p1p1p1p/9/6P2/P1P1P3P/2N1C2C1/9/R1BAKABNR b":"仙人指路转左中炮对卒底炮飞左象——红进左马(E22)", \
"rnbaka1nr/9/1c2b1c2/p1p1p3p/6p2/6P2/P1P1P3P/2N1C2C1/9/R1BAKABNR w":"仙人指路转左中炮对卒底炮飞左象——黑进7卒(E30)", \
"rnbaka1nr/9/1c2b1c2/p1p1p3p/9/6p2/P1P1P3P/2N1C2C1/9/1RBAKABNR w":"仙人指路转左中炮对卒底炮飞左象——黑连进7卒(E31)", \
"rnbaka1nr/9/1c2b1c2/p1p1p3p/9/6p2/P1P1P3P/2N1C2CN/9/R1BAKAB1R w":"仙人指路转左中炮对卒底炮飞左象——黑连进7卒(E31)", \
"1nbaka1nr/r8/1c2b1c2/p1p1p1p1p/9/6P2/P1P1P3P/2N1C2C1/9/R1BAKABNR w":"仙人指路转左中炮对卒底炮飞左象——红进左马对黑右横车(E23)", \
"rnbaka1nr/9/1c2b1c2/p1p1p1p1p/9/6P2/P1P1P3P/4C2CN/9/RNBAKAB1R b":"仙人指路转左中炮对卒底炮飞左象——红右边马(E37)", \
"rnbaka1nr/9/1c2b1c2/p1p1p1p1p/9/6P2/P1P1P3P/4C2C1/4A4/RNBAK1BNR b":"仙人指路转左中炮对卒底炮飞左象——红先上仕(E21)", \
"rnbaka1nr/9/1c2b1c2/p1p1C1p1p/9/6P2/P1P1P3P/7C1/9/RNBAKABNR b":"仙人指路转左中炮对卒底炮飞左象——红炮打中卒(E38)", \
"rn1akabnr/9/1c2b1c2/p1p1p1p1p/9/6P2/P1P1P3P/4C2C1/9/RNBAKABNR w":"仙人指路转左中炮对卒底炮飞右象(E14)", \
"rn1akabnr/9/1c2b1c2/p1p1p1p1p/9/6P2/P1P1P3P/4C2CN/9/RNBAKAB1R b":"仙人指路转左中炮对卒底炮飞右象——红右边马(E15)", \
"rn1akab1r/9/1c2b1c1n/p1p1p1p1p/9/6P2/P1P1P3P/4C2CN/9/RNBAKAB1R w":"仙人指路转左中炮对卒底炮飞右象——互进边马(E16)", \
"rnbakabnr/9/4c1c2/p1p1p1p1p/9/6P2/P1P1P3P/4C2C1/9/RNBAKABNR w":"仙人指路转左中炮对卒底炮转顺炮(E17)", \
"rnbakabnr/9/1c4c2/p1p1p1p1p/9/6P2/P1P1P3P/1C2C4/9/RNBAKABNR b":"仙人指路转右中炮对卒底炮(E12)", \
"rnbakabnr/9/1c4c2/p1p1p1p1p/9/6P2/P1P1P3P/1C2B2C1/9/RN1AKABNR b":"仙人指路飞相对卒底炮(E11)", \
"rnbakabnr/9/1c4c2/p1p1p1p1p/9/6P2/P1P1P3P/1C2B2C1/9/RNBAKA1NR b":"仙人指路飞相对卒底炮(E11)", \
"rnbakabnr/9/1c5c1/p3p1p1p/2p6/6P2/P1P1P3P/1C5C1/9/RNBAKABNR w":"对兵局(E40)", \
"rnbakabnr/9/1c5c1/p3p1p1p/2p6/6P2/P1P1P3P/2C4C1/9/RNBAKABNR b":"对兵转兵底炮(E46)", \
"rnbakabnr/9/4c2c1/p3p1p1p/2p6/6P2/P1P1P3P/2C4C1/9/RNBAKABNR w":"对兵转兵底炮对右中炮(E47)", \
"rnbakabnr/9/1c2c4/p3p1p1p/2p6/6P2/P1P1P3P/2C4C1/9/RNBAKABNR w":"对兵转兵底炮对左中炮(E48)", \
"rnbakabnr/9/1c5c1/p3p1p1p/2p6/6P2/P1P1P3P/1C4NC1/9/RNBAKAB1R b":"对兵进右马局(E41)", \
"r1bakabnr/9/1cn4c1/p3p1p1p/2p6/6P2/P1P1P3P/1C4NC1/9/RNBAKAB1R w":"对兵互进右马局(E42)", \
"r1bakabnr/9/1cn4c1/p3p1p1p/2p6/6P2/P1P1P3P/1C4NC1/8R/RNBAKAB2 b":"对兵互进右马局——红横车(E44)", \
"r1bakabnr/9/1cn4c1/p3p1p1p/2p6/6P2/P1P1P3P/1C4N1C/9/RNBAKAB1R b":"对兵互进右马局——红边炮(E45)", \
"r1bakabnr/9/1cn4c1/p3p1p1p/2p6/6P2/P1P1P3P/1C2B1NC1/9/RN1AKAB1R b":"对兵互进右马局——红飞相(E43)", \
"r1bakabnr/9/1cn4c1/p3p1p1p/2p6/6P2/P1P1P3P/1C2B1NC1/9/RNBAKA2R b":"对兵互进右马局——红飞相(E43)", \
"r1bakabnr/9/1cn4c1/p1p1p1p1p/9/6P2/P1P1P3P/1C5C1/9/RNBAKABNR w":"仙人指路对进右马(E06)", \
"r1bakabnr/9/1cn4c1/p1p1p1p1p/9/6P2/P1P1P3P/1C4NC1/9/RNBAKAB1R b":"仙人指路互进右马局(E07)", \
"r1bakabnr/9/1cn4c1/p1p1p1p1p/9/2P3P2/P3P3P/1C5C1/9/RNBAKABNR b":"两头蛇对进右马(E08)", \
"r1bakabnr/9/1cn3c2/p1p1p1p1p/9/2P3P2/P3P3P/1C5C1/9/RNBAKABNR w":"两头蛇对进右马转卒底炮(E09)", \
"rnbaka1nr/9/1c2b2c1/p1p1p1p1p/9/6P2/P1P1P3P/1C5C1/9/RNBAKABNR w":"仙人指路对飞象(E01)", \
"rnbaka1nr/9/1c2b2c1/p1p1p1p1p/9/6P2/P1P1P3P/1C4NC1/9/RNBAKAB1R b":"仙人指路进右马对飞象(E02)", \
"rnbakabnr/9/4c2c1/p1p1p1p1p/9/6P2/P1P1P3P/1C5C1/9/RNBAKABNR w":"仙人指路对中炮(E03)", \
"rnbakabnr/9/6cc1/p1p1p1p1p/9/6P2/P1P1P3P/1C5C1/9/RNBAKABNR w":"仙人指路对金钩炮(E05)", \
"rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C2B2C1/9/RNBAKA1NR b":"飞相局(A10)", \
"rnbakabnr/9/1c1c5/p1p1p1p1p/9/9/P1P1P1P1P/1C2B2C1/9/RNBAKA1NR w":"飞相对左过宫炮(A30)", \
"rnbakabnr/9/1c1c5/p1p1p1p1p/9/9/P1P1P1P1P/1C2B2C1/9/RNBAKA1NR b":"飞相进右马对左过宫炮(A31)", \
"rnbakabnr/9/3c3c1/p1p1p1p1p/9/9/P1P1P1P1P/1C2B2C1/9/RNBAKA1NR w":"飞相对右士角炮(A21)", \
"rnbakabnr/9/3c3c1/p1p1p1p1p/9/9/P1P1P1P1P/1C2B2C1/R8/1NBAKA1NR b":"飞相横车对右士角炮(A24)", \
"rnbakabnr/9/3c3c1/p1p1p1p1p/9/9/P1P1P1P1P/NC2B2C1/9/R1BAKA1NR b":"飞相左边马对右士角炮(A23)", \
"rnbakabnr/9/3c3c1/p1p1p1p1p/9/9/P1P1P1P1P/1CN1B2C1/9/R1BAKA1NR b":"飞相进左马对右士角炮(A22)", \
"rnbakabnr/9/3c3c1/p1p1p1p1p/9/2P6/P3P1P1P/1C2B2C1/9/RNBAKA1NR b":"飞相进七兵对右士角炮(A26)", \
"rnbakabnr/9/3c3c1/p1p1p1p1p/9/6P2/P1P1P3P/1C2B2C1/9/RNBAKA1NR b":"飞相进三兵对右士角炮(A25)", \
"rnbakabnr/9/1c5c1/p1p1p3p/6p2/9/P1P1P1P1P/1C2B2C1/9/RNBAKA1NR w":"飞相对进7卒(A36)", \
"rnbakabnr/9/1c5c1/p1p1p3p/6p2/2P6/P3P1P1P/1C2B2C1/9/RNBAKA1NR b":"飞相互进七兵局(A38)", \
"rnbakabnr/9/1c5c1/p1p1p3p/6p2/9/P1P1P1P1P/1CN1B2C1/9/R1BAKA1NR b":"飞相进左马对进7卒(A37)", \
"r1bakabnr/9/1cn4c1/p1p1p1p1p/9/9/P1P1P1P1P/1C2B2C1/9/RNBAKA1NR w":"飞相对进右马(A14)", \
"r1bakabnr/9/1cn4c1/p1p1p1p1p/9/6P2/P1P1P3P/1C2B2C1/9/RNBAKA1NR b":"飞相进三兵对进右马(A15)", \
"r1bakabnr/9/1cn4c1/p1p1p1p1p/9/2P6/P3P1P1P/1C2B2C1/9/RNBAKA1NR b":"飞相进七兵对进右马(A16)", \
"rnbakabnr/9/1c2c4/p1p1p1p1p/9/9/P1P1P1P1P/1C2B2C1/9/RNBAKA1NR w":"飞相对左中炮(A27)", \
"rnbakabnr/9/5c1c1/p1p1p1p1p/9/9/P1P1P1P1P/1C2B2C1/9/RNBAKA1NR w":"飞相对右过宫炮(A35)", \
"rnbakabnr/9/1c3c3/p1p1p1p1p/9/9/P1P1P1P1P/1C2B2C1/9/RNBAKA1NR w":"飞相对左士角炮(A20)", \
"rnbaka1nr/9/1c2b2c1/p1p1p1p1p/9/9/P1P1P1P1P/1C2B2C1/9/RNBAKA1NR w":"顺相局(A11)", \
"rnbakab1r/9/1c4nc1/p1p1p1p1p/9/9/P1P1P1P1P/1C2B2C1/9/RNBAKA1NR w":"飞相对进左马(A13)", \
"rnbakabnr/9/1c5c1/p3p1p1p/2p6/9/P1P1P1P1P/1C2B2C1/9/RNBAKA1NR w":"飞相对进3卒(A39)", \
"rn1akabnr/9/1c2b2c1/p1p1p1p1p/9/9/P1P1P1P1P/1C2B2C1/9/RNBAKA1NR w":"列相局(A12)", \
"rnbakabnr/9/4c2c1/p1p1p1p1p/9/9/P1P1P1P1P/1C2B2C1/9/RNBAKA1NR w":"飞相对右中炮(A29)", \
"rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C4NC1/9/RNBAKAB1R b":"起马局(A40)", \
"rnbakabnr/9/1c5c1/p1p1p3p/6p2/9/P1P1P1P1P/1C4NC1/9/RNBAKAB1R":"起马对进7卒(A41)", \
"rnbakabnr/9/1c5c1/p1p1p3p/6p2/2P6/P3P1P1P/1C4NC1/9/RNBAKAB1R b":"起马互进七兵局(A45)", \
"rnbakabnr/9/1c5c1/p1p1p3p/6p2/9/P1P1P1P1P/3C2NC1/9/RNBAKAB1R b":"起马转仕角炮对进7卒(A43)", \
"rnbakabnr/9/1c5c1/p1p1p3p/6p2/9/P1P1P1P1P/1C4N1C/9/RNBAKAB1R b":"起马转边炮对进7卒(A42)", \
"rnbakabnr/9/1c5c1/p1p1p3p/6p2/9/P1P1P1P1P/4C1NC1/9/RNBAKAB1R b":"起马转中炮对进7卒(A44)", \
"rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C1C5/9/RNBAKABNR b":"过宫炮局(A60)", \
"rnbakab1r/9/1c4nc1/p1p1p1p1p/9/9/P1P1P1P1P/1C1C5/9/RNBAKABNR w":"过宫炮对进左马(A61)", \
"rnbakabnr/9/1c2c4/p1p1p1p1p/9/9/P1P1P1P1P/1C1C5/9/RNBAKABNR w":"过宫炮对左中炮(A63)", \
"rnbakabn1/8r/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C1C5/9/RNBAKABNR w":"过宫炮对横车(A62)", \
"rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/3C3C1/9/RNBAKABNR b":"仕角炮局(A50)", \
"rnbakabnr/9/1c2c4/p1p1p1p1p/9/9/P1P1P1P1P/3C3C1/9/RNBAKABNR w":"仕角炮对右中炮(A52)", \
"rnbakabnr/9/1c5c1/p3p1p1p/2p6/9/P1P1P1P1P/3C3C1/9/RNBAKABNR w":"仕角炮对进7卒(A54)", \
"rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/NC5C1/9/R1BAKABNR b":"边马局(A02)", \
"rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1CC6/9/RNBAKABNR b":"金钩炮局(A07)" \
}
Initial_Board_Empty = "9/9/9/9/9/9/9/9/9/9 w - - 0 1"
Initial_Board_Light = "rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1"
Initial_Board_Dark = "xxxxkxxxx/9/1x5x1/x1x1x1x1x/9/9/X1X1X1X1X/1X5X1/9/XXXXKXXXX w - - 0 1"
nodes = "RNHBEAKCPXrnhbeakcpx"
uncovered = list("rnbaabnrccpppppPPPPPCCRNBAABNR") # 初始的未揭的棋
natural_end = 120 # 无吃子步数作和
longGeneral_end = 3 # 长将作负
sameFEN_end = 4 # 不变着判和局面数
def __init__(self, mode = 0b0000, FEN = Initial_Board_Light, prev = None, prevStep = None, next = [], nextStep = [], eaten = [], direction = True) -> tuple:
self.mode = mode # 模式(棋类 | 机器辅助)
self.FEN = FEN # 使用 FEN 记录局面
self.FEN2lists() # 转 lists
assert(self.checkFEN()) # 检查局面
self.prev = prev # 上一个局面(只有一个局面)
self.prevStep = prevStep # 上一步着法(只有一个局面)
self.next = next[::] # 下一个局面(可能有多个局面)
self.nextStep = nextStep[::] # 下一步着法(可能有多个局面)
assert(len(self.next) == len(self.nextStep))
if mode >> 3: # 揭棋
if eaten is None: # 传递为 None 表示上一局面会处理
self.eaten = None
else:
self.eaten = eaten[::] # 被吃子
self.uncovered = Board.uncovered[::] # 初始化未揭子
for line in self.lists[0]: # 去掉局面中已揭开的棋
for piece in line:
if piece == "H": # 马有两种表示
self.uncovered.remove("N")
elif piece == "h": # 马有两种表示
self.uncovered.remove("n")
elif piece == "E": # 相有两种表示
self.uncovered.remove("B")
elif piece == "e": # 象有两种表示
self.uncovered.remove("b")
elif piece not in "XxKk.": # 是其它非将帅明子
self.uncovered.remove(piece)
for piece in self.eaten: # 去掉被吃子
if piece[-1] == "H": # 马有两种表示
self.uncovered.remove("N")
elif piece[-1] == "h": # 马有两种表示
self.uncovered.remove("n")
elif piece[-1] == "E": # 相有两种表示
self.uncovered.remove("B")
elif piece[-1] == "e": # 象有两种表示
self.uncovered.remove("b")
else:
self.uncovered.remove(piece[-1]) # 第一个字符存明暗
boardFEN = self.FEN.split(" ")[0]
assert( \
len(findall("[A-Z]", boardFEN)) + len([piece for piece in self.eaten if "A" <= piece[-1] <= "Z"]) == 16 \
and len(findall("[a-z]", boardFEN)) + len([piece for piece in self.eaten if "a" <= piece[-1] <= "z"]) == 16 \
and boardFEN.count("X") == len([item for item in self.uncovered if "A" <= item <= "Z"]) \
and boardFEN.count("x") == len([item for item in self.uncovered if "a" <= item <= "z"]) \
) # 一方棋盘剩余子与被吃子和 == 16 and 暗子 == 未揭子
else: # 象棋
if eaten is None: # 传递为 None 表示上一局面会处理
self.eaten = None
else:
self.eaten = Board.uncovered[::] # 初始化
for line in self.lists[0]: # 逐行
for piece in line: # 逐子
if piece == "H": # 马有两种表示
self.eaten.remove("N")
elif piece == "h": # 马有两种表示
self.eaten.remove("n")
elif piece == "E": # 相有两种表示
self.eaten.remove("B")
elif piece == "e": # 象有两种表示
self.eaten.remove("b")
elif piece not in "Kk.": # 排除将帅空(遇到 Xx 报错)
self.eaten.remove(piece)
self.uncovered = [] # 未被揭开(象棋无暗子)
self.direction = direction # 视角(红方为 True | 黑方为 False)
tmpJudgement = self.judge() # 是否已终(防止残局无法走子)
self.preMsg = tmpJudgement[2] if tmpJudgement[1] else None # 用于传递(构造函数无法传递返回值)
self.startMsg = None
def checkFEN(self) -> bool: # 局面检查
boardFEN = self.FEN.split(" ")[0]
return ( \
(len(self.lists) == 6 and len(self.lists[0]) == 10 and not any([len(self.lists[0][i]) != 9 for i in range(10)])) \
and (boardFEN.count("R") <= 2 and boardFEN.count("r") <= 2) \
and (boardFEN.count("N") + boardFEN.count("H") <= 2 and boardFEN.count("n") + boardFEN.count("h") <= 2) \
and (boardFEN.count("B") + boardFEN.count("E") <= 2 and boardFEN.count("b") + boardFEN.count("e") <= 2) \
and (boardFEN.count("A") <= 2 and boardFEN.count("a") <= 2) \
and (boardFEN.count("K") == 1 and boardFEN.count("k") == 1) \
and (boardFEN.count("C") <= 2 and boardFEN.count("c") <= 2) \
and (boardFEN.count("P") <= 5 and boardFEN.count("p") <= 5) \
and (len(findall("[A-Z]", boardFEN)) <= 16 and len(findall("[a-z]", boardFEN)) <= 16) \
and self.lists[1] in "WwRrBbGg" \
and self.lists[-2] >> 1 <= self.lists[-1] - 1 \
and (self.mode >> 3 or self.checkChess()) \
and not self.checkIfIsEatingGeneral() \
)
def checkChess(self) -> bool: # 象棋局面检查
for i in range(7, 10): # 不应该出现红兵
if "P" in self.lists[0][i]:
return False
for i in range(3): # 不应该出现黑卒
if "p" in self.lists[0][i]:
return False
B_idx, b_idx, A_idx, a_idx, K_idx, k_idx = set(), set(), set(), set(), set(), set() # 相士将的位置
for i in range(len(self.lists[0])):
for j in range(len(self.lists[0][i])):
if self.lists[0][i][j] in "BE":
B_idx.add((i, j))
elif self.lists[0][i][j] in "be":
b_idx.add((i, j))
elif self.lists[0][i][j] == "A":
A_idx.add((i, j))
elif self.lists[0][i][j] == "a":
a_idx.add((i, j))
elif self.lists[0][i][j] == "K":
K_idx.add((i, j))
elif self.lists[0][i][j] == "k":
k_idx.add((i, j))
return ( \
B_idx < {(5, 2), (5, 6), (7, 0), (7, 4), (7, 8), (9, 2), (9, 6)} \
and b_idx < {(0, 2), (0, 6), (2, 0), (2, 4), (2, 8), (4, 2), (4, 6)} \
and A_idx < {(7, 3), (7, 5), (8, 4), (9, 3), (9, 5)} \
and a_idx < {(0, 3), (0, 5), (1, 4), (2, 3), (2, 5)} \
and K_idx < {(7, 3), (7, 4), (7, 5), (8, 3), (8, 4), (8, 5), (9, 3), (9, 4), (9, 5)} \
and k_idx < {(0, 3), (0, 4), (0, 5), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5)} \
)
def checkStart(self) -> None: # 检查开局局面
if self.mode >> 3 == 0: # 只有象棋开局才有名称
tmpFEN = self.FEN.split(" ")[0] + " " + self.lists[1]
if tmpFEN in Board.FEN_statement:
self.startMsg = Board.FEN_statement[tmpFEN]
else:
tmpFEN = "/".join([line[::-1] for line in self.FEN.split(" ")[0].split("/")]) + " " + self.lists[1]
if tmpFEN in Board.FEN_statement:
self.startMsg = Board.FEN_statement[tmpFEN]
def checkIfIsEatingGeneral(self) -> False: # 当前局面先走方能否直接吃掉将军
availCoor = Node.getAvailableCoordinates(self.mode, self.lists[1] in "WwRr", None, self.lists[0], useMethod = None) # 由于能够直接吃掉对方将军,不考虑是否走得开的问题
for i in list(range(3)) + list(range(7, 10)):
for j in range(3, 6):
if self.lists[0][i][j] == "K":
K_coor = (i, j)
elif self.lists[0][i][j] == "k":
k_coor = (i, j)
for coor in availCoor:
if coor[1] == (k_coor if self.lists[1] in "WwRr" else K_coor):
return True
return False
def FEN2lists(self) -> None: # 转 lists
self.lists = self.FEN.split(" ") # 按空格解剖 FEN
self.lists[0] = self.lists[0].replace("H", "N").replace("E", "B").replace("h", "n").replace("e", "b") # 替换别号
self.FEN = " ".join(self.lists)
for ch in set(self.lists[0]):
if "1" <= ch <= "9":
self.lists[0] = self.lists[0].replace(ch, "." * int(ch)) # 拆解成若干个 .
self.lists[0] = [list(line) for line in self.lists[0].split("/")] # 按行解剖棋盘
self.lists[-1] = int(self.lists[-1])
self.lists[-2] = int(self.lists[-2])
def lists2FEN(self) -> None: # 转 FEN
self.FEN = "/".join("".join(line) for line in self.lists[0]) + " " + " ".join([str(item) for item in self.lists[1:]])
for i in range(9, 0, -1):
self.FEN = self.FEN.replace("." * i, str(i)) # 将连续的 . 替换为数字
def judgeGeneral(self, nextBoard) -> list: # 判断是否长将或将军
availCoor = Node.getAvailableCoordinates(self.mode, self.lists[1] in "WwRr", None, nextBoard.lists[0], useMethod = None)
for i in range(len(nextBoard.lists[0])):
for j in range(len(nextBoard.lists[0][i])):
if nextBoard.lists[0][i][j] == "K":
K_coor = (i, j)
elif nextBoard.lists[0][i][j] == "k":
k_coor = (i, j)
listRet = []
for coor in availCoor:
if coor[1] == (k_coor if self.lists[1] in "WwRr" else K_coor):
listRet.append(nextBoard.lists[0][coor[0][0]][coor[0][1]])
return listRet
def judge(self) -> tuple: # 判断是否终局
if self.lists[-2] >= Board.natural_end: # 无吃子步数达到 120 步
return (True, True, "和棋!无吃子步数达到 {0} 步。".format(Board.natural_end))
if self.mode >> 3: # 揭棋(只有两个将军才能判)
naturalEnd = True
for i in range(len(self.lists[0])): # 判断自然作和
for j in range(len(self.lists[0][i])):
if self.lists[0][i][j] not in "Kk.": # 有则不终止
naturalEnd = False
break
if not naturalEnd: # 只是想要加速运行
break
if naturalEnd:
return (True, True, "自然作和!")
del naturalEnd # 释放内存
else: # 象棋
naturalEnd = True
for i in range(len(self.lists[0])): # 判断自然作和
for j in range(len(self.lists[0][i])):
if self.lists[0][i][j] in "RNHCPXrnhcpx": # 有则不终止
naturalEnd = False
break
if not naturalEnd: # 只是想要加速运行
break
if naturalEnd:
return (True, True, "自然作和!")
del naturalEnd # 释放内存
tmpBoard = self # 遍历链表用
FEN_dicts = {" ".join(tmpBoard.FEN.split(" ")[:2]):1} # 统计数量
while tmpBoard.prev: # 当含有前一个时
tmpBoard = tmpBoard.prev
FEN_dicts.setdefault(" ".join(tmpBoard.FEN.split(" ")[:2]), 0)
FEN_dicts[" ".join(tmpBoard.FEN.split(" ")[:2])] += 1
if FEN_dicts[" ".join(tmpBoard.FEN.split(" ")[:2])] >= Board.longGeneral_end and self.prev.judgeGeneral(self): # 一定有前一个
return (True, True, "此局已终,{0}方长将作负!".format("黑" if self.lists[1] in "WwRr" else "红"))
elif FEN_dicts[" ".join(tmpBoard.FEN.split(" ")[:2])] >= Board.sameFEN_end:
return (True, True, "双方不变着作和!")
else: # 循环自然结束释放内存
FEN_dicts.clear()
del FEN_dicts
tmpBoard = None
del tmpBoard
availCoor = Node.getAvailableCoordinates(self.mode, self.lists[1] in "WwRr", None, self.lists[0], useMethod = None)
for coor in availCoor: # 遍历所有可走的
if Node.judgeWhetherCanGo(self.mode, coor[0], coor[1], self.lists[0], self.lists[1] in "WwRr"): # 只要能走得动
return (True, False, None)
else: # 走不动了
return (True, True, "此局已终,{0}胜!".format("黑" if self.lists[1] in "WwRr" else "红"))
def generateNextBoard(self, movement, isPrintMethod = True) -> tuple: # 根据着法生成下一个局面
#results = (False, False, None) # 是否成功 | 是否终局 | 消息
#p, q = (0, 0), (0, 0)
useMethod = None # 记录着法描述方式
if type(movement) == tuple and len(movement) == 2 and len(movement[0]) == len(movement[1]) == 2 and 0 <= movement[0][0] <= 9 and 0 <= movement[0][1] <= 8 and 0 <= movement[1][0] <= 9 and 0 <= movement[1][1] <= 8:
p, q = movement[0], movement[1]
useMethod = 1
method0 = True
method1 = method2 = method3 = method4 = None # 跳过
else:
movement = str(movement) # 保险起见
method0 = False
method1 = findall("^[\\u4e00-\\u9fa5]?[\\u4e00-\\u9fa5].[进進退平].$", movement)
method2 = findall("^[A-Za-z][1-9a-z+-][+-.][1-9]$", movement) # 匹配 c2-c5 等
method3 = findall("^[A-Ia-i]\\d-?[A-Ia-i]\\d$", movement) # 匹配 c2-c5 等
method4 = findall("\\d\\d-?\\d\\d$", movement) # 匹配 77-74 等
if method4:
method4 = method4[0] # 选取正则表达式数组中的第一个(实际上应该也是唯一一个)
p = (int(method4[0]), int(method4[1]))
q = (int(method4[2]), int(method4[3]))
useMethod = 4
elif method3:
method3 = method3[0] # 选取正则表达式数组中的第一个(实际上应该也是唯一一个)
p = (9 - int(method3[1]), ord(method3[0].upper()) - 65) # ord("A") = 65
q = (9 - int(method3[-1]), ord(method3[-2].upper()) - 65)
useMethod = 3
elif method2:
method2 = method2[0] # 选取正则表达式数组中的第一个(实际上应该也是唯一一个)
if method2[0] not in Board.nodes:
return (False, False, "未知棋子或未知移动方式,请检查。")
elif method2[0] in "HEhe": # 相象和马的别号
method2 = {"H":"N", "E":"B", "h":"n", "e":"b"}[method2[0]] + method2[1:] # 重构字符串
if "1" <= method2[1] <= "9": # 某一路上唯一
p1 = 9 - int(method2[1]) if "A" <= method2[0] <= "Z" else int(method2[1]) - 1 # 红用 9 减黑减 1
if self.mode >> 3 == 0 and method2[0] in "BEAbea": # 象士特殊性
if method2[1:-1] in ("3+", "3-", "7+", "7-"): # B3+1 等
if method2[0] in "BE": # 相
p = (9 if method2[2] == "+" else 5, 6 if method2[1] == "3" else 2)
elif method2[0] in "be": # 象
p = (0 if method2[2] == "+" else 4, 2 if method2[1] == "3" else 6)
else:
return (False, False, "仕士不存在 " + method2[1:] + " 说法,请检查。")
elif method2[1:-1] in ("4+", "4-", "6+", "6-"): # A4+1 等
if method2[0] == "A": # 仕
p = (9 if method2[2] == "+" else 7, 5 if method2[1] == "4" else 3)
elif method2[0] == "a": # 士
p = (0 if method2[2] == "+" else 2, 3 if method2[1] == "4" else 5)
else:
return (False, False, "相象不存在 " + method[1:] + " 说法,请检查。")
elif method2[1] in "159" and method2[2] in "+-": # 唯一
if method2[0] == "A" and method2[1] == "5": # 仕
p = (8, 4)
elif method2[0] == "a" and method2[1] == "5": # 士
p = (1, 4)
elif method2[0] in "BE": # 相
p = (7, 9 - int(method2[1]))
elif method2[0] in "be": # 象
p = (2, int(method2[1]) - 1)
else:
return (False, False, "一五九或159纵路上相象仕士指令不匹配,请检查。")
else:
return (False, False, "象棋模式下相象仕士指令不匹配,请检查。")
else:
cnt = 0
for i in range(10):
if self.lists[0][i][p1] == method2[0]:
p0 = i
cnt += 1
if cnt > 1:
return (False, False, "指代不明,{0}路纵线上有 {1} 个{2},请检查。".format("红方{0}".format("零一二三四五六七八九"[int(method2[1])]) if "A" <= method2[0] <= "Z" else "黑方 {0} ".format(method2[1]), cnt, Node.name_dict[method2[0]]))
elif cnt == 0:
return (False, False, "棋子不存在,{0}路纵线上没有{1},请检查。".format("红方{0}".format("零一二三四五六七八九"[int(method2[1])]) if "A" <= method2[0] <= "Z" else "黑方 {0} ".format(method2[1]), Node.name_dict[method2[0]]))
else:
p = (p0, p1) # 保存坐标
else: # 正则表达式已过滤
multiCnt = 0 # 有多少列重复
repeatIdx = [] # 存储坐标
for j in (range(8, -1, -1) if "A" <= method2[0] <= "Z" else range(0, 9)): # 红方从右往左
lineTmp = [] # 单列记录
for i in (range(0, 10) if "A" <= method2[0] <= "Z" else range(9, -1, -1)): # 红方从上到下
if self.lists[0][i][j] == method2[0]: # 相同兵种
lineTmp.append((i, j))
if len(lineTmp) > 1: # 有重复
multiCnt += 1
repeatIdx += lineTmp # 仅对有重复的列添加
if multiCnt == 1 and len(repeatIdx) == 2 and method2[1] in "+-": # 一列重复且为前后
p = repeatIdx[0 if method2[1] == "+" else -1] # 前为 0 后为 -1
elif method2[1] not in "+-" and 0 <= ord(method2[1]) - 97 < len(repeatIdx): # 多重复(字母已被过滤小写无需容错)
if len(repeatIdx) == 2:
print("警告:写法不规范但依旧能识别,正确的写法应该为:“{0}”。\n指令已修正,请按任意键继续。".format(method2[0] + {"a":"+", "b":"-"}[method2[1]] + method2[2:]))
getch()
if ord(method2[1].lower()) - 97 < len(repeatIdx):
p = repeatIdx[ord(method2[1].lower()) - 97] # 直接指示第几个
else:
return (False, False, "发生越界,请检查。")
else:
return (False, False, "未能识别该格式的第二个字符,请检查。")
if "1" <= method2[3] <= "9": # 识别走法
if method2[0] in "NHnh": # 马
if method2[2] == ".":
return (False, False, "马不能与平搭配,请检查。")
q1 = 9 - int(method2[3]) if method2[0] in "NH" else int(method2[3]) - 1 # 确定路
crossRoad = abs(p[1] - q1) # 确定跨过的路
if crossRoad > 2 or crossRoad == 0: # 超过 2 路或直线报错
return (False, False, "千里神马横跨超过两个纵路或走直线,请检查。")
else:
q0 = p[0] + (3 - crossRoad) * (1 if (method2[2] == "+") ^ (method2[0] in "NH") else -1) # 红马进为负
elif method2[0] in "BEbe": # 相象
if method2[2] == ".":
return (False, False, "相和象不能与平搭配,请检查。")
q1 = 9 - int(method2[3]) if method2[0] in "BE" else int(method2[3]) - 1 # 确定路
if abs(p[1] - q1) != 2: # 检查跨过的路
return (False, False, "小飞象乱飞,请检查。")
else:
q0 = p[0] + (2 if (method2[2] == "+") ^ (method2[0] in "BE") else -2) # 相进为负
elif method2[0] in "Aa": # 仕士
if method2[2] == ".":
return (False, False, "仕和士不能与平搭配,请检查。")
q1 = 9 - int(method2[3]) if method2[0] == "A" else int(method2[3]) - 1 # 确定路
if abs(p[1] - q1) != 1: # 检查跨过的路
return (False, False, "间谍士乱谋,请检查。")
else:
q0 = p[0] + (1 if (method2[2] == "+") ^ (method2[0] == "A") else -1) # 仕进为负
elif method2[0] in "Xx": # 暗
if p[0] == 6 and p[1] % 2 == 0: # 暗兵
if method2[-2:] == "+1":
q0, q1 = 5, p[1]
else:
return (False, False, "暗兵只有一种走法,即前进一步。")
elif p[0] == 3 and p[1] % 2 == 0: # 暗卒
if method2[-2:] == "+1":
q0, q1 = 4, p[1]
else:
return (False, False, "暗卒只有一种走法,即前进一步。")
elif p[0] == 7 and p[1] in (1, 7) or p[0] == 9 and p[1] in (0, 8): # 暗车炮
if method2[-2] == "+": # 进
q0, q1 = p[0] - int(method2[-1]), p[1]
elif method2[-2] == "-": # 退
q0, q1 = p[0] + int(method2[-1]), p[1]
elif method2[-2] == ".": # 平
q0, q1 = p[0], 9 - int(method2[-1])
elif p[0] == 2 and p[1] in (1, 7) or p[0] == 0 and p[1] in (0, 8): # 暗車砲
if method2[-2] == "+": # 进
q0, q1 = p[0] + int(method2[-1]), p[1]
elif method2[-2] == "-": # 退
q0, q1 = p[0] - int(method2[-1]), p[1]
elif method2[-2] == ".": # 平
q0, q1 = p[0], int(method2[-1]) - 1
elif p[0] == 9 and p[1] in (1, 7): # 暗马
if method2[-2] == "+": # 进
if method2[-1] in "1379":
q0, q1 = 7, 9 - int(method2[-1])
elif method2[-1] in "46":
q0, q1 = 8, 9 - int(method2[-1])
else:
return (False, False, "走子失败,请正确使用暗马。")
else:
return (False, False, "走子失败,暗马开局唯有进。")
elif p[0] == 0 and p[1] in (1, 7): # 暗馬
if method2[-2] == "+": # 进
if method2[-1] in "1379":
q0, q1 = 2, int(method2[-1]) - 1
elif method2[-1] in "46":
q0, q1 = 1, int(method2[-1]) - 1
else:
return (False, False, "走子失败,请正确使用暗马。")
else:
return (False, False, "走子失败,暗马开局唯有进。")
elif p[0] == 9 and p[1] in (2, 6): # 暗相
if method2[-2] == "+": # 进
if method2[-1] in "159":
q0, q1 = 7, 9 - int(method2[-1])
else:
return (False, False, "走子失败,请正确使用暗相。")
else:
return (False, False, "走子失败,暗相开局唯有进。")
elif p[0] == 0 and p[1] in (2, 6): # 暗象
if method2[-2] == "+": # 进
if method2[-1] in "159":
q0, q1 = 2, int(method2[-1]) - 1
else:
return (False, False, "走子失败,请正确使用暗象。")
else:
return (False, False, "走子失败,暗象开局唯有进。")
elif p[0] == 9 and p[1] in (3, 5): # 暗仕
if method2[-2:] == "+5": # 进
q0, q1 = 8, 4
else:
return (False, False, "走子失败,暗仕开局唯有进五。")
elif p[0] == 0 and p[1] in (3, 5): # 暗士
if method2[-2:] == "+5": # 进
q0, q1 = 1, 4
else:
return (False, False, "走子失败,暗士开局唯有进5。")
else:
return (False, False, "暗子起始位置异常,走子失败。")
else:
if method2[2] == ".": # 平
q0 = p[0]
q1 = 9 - int(method2[3]) if "A" <= method2[0] <= "Z" else int(method2[3]) - 1 # 确定路
else: # 进退(正则表达式已过滤)
q0 = p[0] + (int(method2[3]) if (method2[2] == "+") ^ ("A" <= method2[0] <= "Z") else -int(method2[3])) # 红进为负
q1 = p[1]
q = (q0, q1)
else:
return (False, False, "未能识别该格式的最后一个数字字符,请检查。")
useMethod = 2
elif method1: # 很难(分类处理)
method1 = method1[0] # 选取正则表达式数组中的第一个(实际上应该也是唯一一个)
ch_num_list = "一二三四五六七八九壹贰叁肆伍陆柒捌玖"
digit_num_list = "123456789123456789"
if method1[-1] not in ch_num_list + digit_num_list:
return (False, False, "未能识别该格式的最后一个汉字或数字字符,请检查。")
if method1[-2] not in "进進退平":
return (False, False, "未能识别该格式的倒数第二个汉字,请检查。")
if method1[0] in list(Node.code_dict.keys()): # 炮二平五
if method1[-1] in ch_num_list: # 中文数字
if method1[1] in ch_num_list: # 是中文数字
walker = True # 红方走子
elif method1[1] in digit_num_list: # 是数字
return (False, False, "数字和中文混合使用,请检查。")
else: # 啥都不是
return (False, False, "无法识别第二个字符,请检查。")
else: # 数字(上文已过滤)
if method1[1] in digit_num_list: # 是数字
walker = False # 黑方走子
elif method1[1] in ch_num_list: # 是汉字
return (False, False, "中文和数字混合使用,请检查。")
else: # 啥也不是
return (False, False, "无法识别第二个字符,请检查。")
node = Node.code_dict[method1[0]].upper() if walker else Node.code_dict[method1[0]].lower() # 棋子代号
if self.mode >> 3 == 0 and method1[0] in "相象仕士": # 象士特殊性
if method1[2] == "平":
return (False, False, "相象仕士没有平的说法,请检查。")
if method1[1] in "三叁七柒3377" and method1[2] in "进進退": # 相三进五 等
if method1[0] in "相象" and walker: # 相
if method1[0] != "相":
print("警告:指令不规范但依旧可以识别,正确的写法为“相" + method1[1:] + "”。")
print("请按任意键继续。")
getch()
p = (9 if method1[2] in "进進" else 5, 6 if method1[1] in "三叁" else 2)
elif method1[0] in "相象" and not walker: # 象
if method1[0] != "象":
print("警告:指令不规范但依旧可以识别,正确的写法为“象" + method1[1:] + "”。")
print("请按任意键继续。")
getch()
p = (0 if method1[2] in "进進" else 4, 2 if method1[1] in "33" else 6)
else:
return (False, False, "仕士不存在“" + method1[1:] + "”说法,请检查。")
elif method1[1] in "四肆六陆4466" and method1[2] in "进進退": # 仕四进五 等
if method1[0] in "仕士" and walker: # 仕
if method1[0] != "仕":
print("警告:指令不规范但依旧可以识别,正确的写法为“仕" + method1[1:] + "”。")
print("请按任意键继续。")
getch()
p = (9 if method1[2] in "进進" else 7, 5 if method1[1] in "四肆" else 3)
elif method1[0] in "仕士" and not walker: # 士
if method1[0] != "士":
print("警告:指令不规范但依旧可以识别,正确的写法为“士" + method1[1:] + "”。")
print("请按任意键继续。")
getch()
p = (0 if method1[2] in "进進" else 2, 3 if method1[1] in "44" else 5)
else:
return (False, False, "相象不存在 " + method[1:] + " 说法,请检查。")
elif method1[1] in "一五九壹伍玖115599" and method1[2] in "进進退": # 唯一
if method1[0] in "仕士" and method1[1] == "五伍55": # 仕士
if walker: # 仕
if method1[0] != "仕":
print("警告:指令不规范但依旧可以识别,正确的写法为“仕" + method1[1:] + "”。")
print("请按任意键继续。")
getch()
p = (8, 4)
else: # 士
if method1[0] != "士":
print("警告:指令不规范但依旧可以识别,正确的写法为“士" + method1[1:] + "”。")
print("请按任意键继续。")
getch()
p = (1, 4)
elif method2[0] in "相象" and walker: # 相
if method1[0] != "相":
print("警告:指令不规范但依旧可以识别,正确的写法为“相" + method1[1:] + "”。")
print("请按任意键继续。")
getch()
p = (7, 8 - ch_num_list.index(method1[1]) % 9)
elif method2[0] in "相象" and not walker: # 象
if method1[0] != "象":
print("警告:指令不规范但依旧可以识别,正确的写法为“象" + method1[1:] + "”。")
print("请按任意键继续。")
getch()
p = (2, ch_num_list.index(method1[1]))
else:
return (False, False, "一五九或159纵路上相象仕士指令不匹配,请检查。")
else:
return (False, False, "象棋模式下相象仕士指令不匹配,请检查。")
else:
p1 = 8 - ch_num_list.index(method1[1]) % 9 if walker else digit_num_list.index(method1[1]) % 9 # 定位列
cnt = 0 # 计数
for i in range(10):
if self.lists[0][i][p1] == node: # 查找该纵列上的子
p0 = i
cnt += 1
if cnt > 1:
return (False, False, "指代不明,{0}路纵线上有 {1} 个{2},请检查。".format("红方" + method1[1] if walker else "黑方" + method1[1], cnt, method1[0]))
elif cnt == 0:
return (False, False, "棋子不存在,{0}路纵线上没有{1},请检查。".format("红方" + method1[1] if walker else "黑方" + method1[1], method1[0]))
else:
p = (p0, p1) # 保存坐标
elif method1[1] in list(Node.code_dict.keys()) or len(method1) == 5 and method1[2] in list(Node.code_dict.keys()): # 前兵进一 或 前兵一进一 或 十二暗进一
walker = method1[-1] in ch_num_list # 最后一个字符为中文数字即红方
if method1[1] in list(Node.code_dict.keys()):
node = Node.code_dict[method1[1]].upper() if walker else Node.code_dict[method1[1]].lower() # 棋子代号
else:
node = Node.code_dict[method1[2]].upper() if walker else Node.code_dict[method1[2]].lower() # 棋子代号
multiCnt = 0 # 有多少列重复
repeatIdx = [] # 存储坐标
for j in (range(8, -1, -1) if walker else range(0, 9)): # 红方从右往左
lineTmp = [] # 单列记录
for i in (range(0, 10) if walker else range(9, -1, -1)): # 红方从上到下
if self.lists[0][i][j] == node: # 相同兵种
lineTmp.append((i, j))
if len(lineTmp) > 1: # 有重复
multiCnt += 1
repeatIdx += lineTmp # 仅对有重复的列添加
if multiCnt == 1: # 一列重复
if len(method1) == 4 and method1[1] in list(Node.code_dict.keys()): # 前兵进一(单列)
if len(repeatIdx) == 2: # 两个用前后
if method1[0] == "前":
if node in "BEAbea": # 象士特殊性
print("警告:指令不规范但依旧可以识别。一般而言,象棋模式中相象仕士不使用前后进行描述。")
print("请按任意键继续。")
getch()
p = repeatIdx[0]
elif method1[0] in "后後":
if node in "BEAbea": # 象士特殊性
print("警告:指令不规范但依旧可以识别。一般而言,象棋模式中相象仕士不使用前后进行描述。")
print("请按任意键继续。")
getch()
p = repeatIdx[-1]
else:
return (False, False, "仅查找到一列重复且重复计数为 2,应用“前后”描述,请检查。")
elif len(repeatIdx) == 3: # 三个用前中后
if method1[0] == "前":
p = repeatIdx[0]
elif method1[0] == "中":
p = repeatIdx[1]
elif method1[0] in "后後":
p = repeatIdx[-1]
else:
return (False, False, "仅查找到一列重复且重复计数为 3,应用“前中后”描述,请检查。")
else: # 前二三四
if method1[0] in "前二三四五六七八九十前贰叁肆伍陆柒捌玖拾":
if "前二三四五六七八九十前贰叁肆伍陆柒捌玖拾".index(method1[0]) % 10 < len(repeatIdx):
p = repeatIdx["前二三四五六七八九十前贰叁肆伍陆柒捌玖拾".index(method1[0]) % 10]
else:
return (False, False, "发生越界,仅有一路有两个或两个以上的{0},该路上仅有 {1} 个{0},请检查。".format(method1[1], len(repeatIdx)))
else:
return (False, False, "仅查找到一列重复且重复计数超过 3,应用“前二三四……”描述,请检查。")
else: # 表达冗余
return (False, False, "仅查找到一列重复,但输入的指令长度为五,请检查。")
else: # 多列重复
if len(method1) == 4 and method1[1] in list(Node.code_dict.keys()): # 前兵进一(多列)
if method1[0] in "一二三四五六七八九十壹贰叁肆伍陆柒捌玖拾":
if "一二三四五六七八九十壹贰叁肆伍陆柒捌玖拾".index(method1[0]) % 10 < len(repeatIdx):
p = repeatIdx["一二三四五六七八九十壹贰叁肆伍陆柒捌玖拾".index(method1[0]) % 10]
else:
return (False, False, "发生越界,有两个或两个以上的{0}的所有纵路中仅有 {1} 个{0},请检查。".format(method1[1], len(repeatIdx)))
else:
return (False, False, "多列重复应用“一二三四……”描述,请检查。")
elif len(method1) == 5 and method1[1] in list(Node.code_dict.keys()): # 前兵一进一
if method1[-1] in ch_num_list: # 中文数字
if method1[2] in digit_num_list: # 是数字
return (False, False, "数字和中文混合使用,请检查。")
elif method1[2] not in ch_num_list: # 啥都不是
return (False, False, "无法识别第二个字符,请检查。")
else: # 数字(上文已过滤)
if method1[2] in ch_num_list: # 是汉字
return (False, False, "中文和数字混合使用,请检查。")
elif method1[2] not in digit_num_list: # 啥也不是
return (False, False, "无法识别第二个字符,请检查。")
p1 = 8 - ch_num_list.index(method1[2]) % 9 if walker else digit_num_list.index(method1[2]) % 9 # 定位列
rpIdx = [] # 单列
for item in repeatIdx:
if item[1] == p1:
rpIdx.append(item)
if len(rpIdx) == 2:
if method1[0] == "前":
p = rpIdx[0]
elif method1[0] in "后後":
p = rpIdx[-1]
else:
return (False, False, "指定列中只有两个重复棋子应用“前后”描述,请检查。")
elif len(rpIdx) == 3:
if method1[0] == "前":
p = rpIdx[0]
elif method1[0] == "中":
p = rpIdx[1]
elif method1[0] in "后後":
p = rpIdx[-1]
else:
return (False, False, "指定列中只有三个重复棋子应用“前中后”描述,请检查。")
else:
if method1[0] in "前二三四五六七八九十前贰叁肆伍陆柒捌玖拾":
if "前二三四五六七八九十前贰叁肆伍陆柒捌玖拾".index(method1[0]) % 10 < len(rpIdx):
p = rpIdx["前二三四五六七八九十前贰叁肆伍陆柒捌玖拾".index(method1[0]) % 10]
else:
return (False, False, "发生越界,手动指派的纵路中仅有 {0} 个{1},请检查。".format(len(rpIdx), method1[1]))
else:
return (False, False, "指定列中超过三个重复棋子应用“前二三四……”描述,请检查。")
elif len(method1) == 5 and method1[2] in list(Node.code_dict.keys()): # 十二暗进一
if len(repeatIdx) != 12: # 不是十二一定越界
return (False, False, "不存在 11 或 12 个多列重复的暗子,请检查。")
if method1[0] in "十拾":
if method1[1] in "一壹":
p = repeatIdx[10]
elif method1[1] in "二贰":
p = repeatIdx[11]
else:
return (False, False, "走子名称位于长度为五的指令中间时前两个字应该为十一或十二,请检查。")
else:
return (False, False, "子名称位于长度为五的指令中间时前两个字应该为十一或十二,请检查。")
else:
return (False, False, "未知棋子名称,请检查。")
if node in "NHnh": # 马
if method1[-2] == "平":
return (False, False, "马不能与平搭配,请检查。")
q1 = 8 - ch_num_list.index(method1[-1]) % 9 if walker else digit_num_list.index(method1[-1]) % 9 # 定位列
crossRoad = abs(p[1] - q1) # 确定跨过的路
if crossRoad > 2 or crossRoad == 0: # 超过 2 路或直线报错
return (False, False, "千里神马横跨超过两个纵路或走直线,请检查。")
else:
q0 = p[0] + (3 - crossRoad) * (1 if (method1[-2] in "进進") ^ walker else -1) # 红马进为负
elif node in "BEbe": # 相象
if method1[-2] == "平":
return (False, False, "相象不能与平搭配,请检查。")
q1 = 8 - ch_num_list.index(method1[-1]) % 9 if walker else digit_num_list.index(method1[-1]) % 9 # 定位列
if abs(p[1] - q1) != 2: # 检查跨过的路
return (False, False, "小飞象乱飞,请检查。")
else:
q0 = p[0] + (2 if (method1[-2] in "进進") ^ walker else -2) # 相进为负
elif node in "Aa": # 仕士
if method1[-2] == "平":
return (False, False, "仕士不能与平搭配,请检查。")
q1 = 8 - ch_num_list.index(method1[-1]) % 9 if walker else digit_num_list.index(method1[-1]) % 9 # 定位列
if abs(p[1] - q1) != 1: # 检查跨过的路
return (False, False, "间谍士乱谋,请检查。")
else:
q0 = p[0] + (1 if (method1[-2] in "进進") ^ walker else -1) # 仕进为负
elif node in "Xx": # 暗
if p[0] == 6 and p[1] % 2 == 0: # 暗兵
if method1[-2] in "进進" and method1[-1] in "一壹":
q0, q1 = 5, p[1]
else:
return (False, False, "暗兵只有一种走法,即前进一步。")
elif p[0] == 3 and p[1] % 2 == 0: # 暗卒
if method1[-2] in "进進" and method1[-1] in "11":
q0, q1 = 4, p[1]
else:
return (False, False, "暗卒只有一种走法,即前进一步。")
elif p[0] == 7 and p[1] in (1, 7) or p[0] == 9 and p[1] in (0, 8): # 暗车炮
if method1[-2] in "进進": # 进
q0, q1 = p[0] - "〇一二三四五六七八九零壹贰叁肆伍陆柒捌玖".index(method1[-1]) % 10, p[1]
elif method1[-2] == "退": # 退
q0, q1 = p[0] + "〇一二三四五六七八九零壹贰叁肆伍陆柒捌玖".index(method1[-1]) % 10, p[1]
elif method1[-2] == "平": # 平
q0, q1 = p[0], 9 - "〇一二三四五六七八九零壹贰叁肆伍陆柒捌玖".index(method1[-1]) % 10
elif p[0] == 2 and p[1] in (1, 7) or p[0] == 0 and p[1] in (0, 8): # 暗車砲
if method1[-2] in "进進": # 进
q0, q1 = p[0] + "01234567890123456789".index(method1[-1]) % 10, p[1]
elif method1[-2] == "退": # 退
q0, q1 = p[0] - "01234567890123456789".index(method1[-1]) % 10, p[1]
elif method1[-2] == "平": # 平
q0, q1 = p[0], "12345678901234567890".index(method1[-1]) % 10
elif p[0] == 9 and p[1] in (1, 7): # 暗马
if method1[-2] in "进進": # 进
if method1[-1] in "一三七九壹叁柒玖":
q0, q1 = 7, 9 - "〇一二三四五六七八九零壹贰叁肆伍陆柒捌玖".index(method1[-1]) % 10
elif method1[-1] in "四六肆陆":
q0, q1 = 8, 9 - "〇一二三四五六七八九零壹贰叁肆伍陆柒捌玖".index(method1[-1]) % 10
else:
return (False, False, "走子失败,请正确使用暗马。")
else:
return (False, False, "走子失败,暗马开局唯有进。")
elif p[0] == 0 and p[1] in (1, 7): # 暗馬
if method1[-2] in "进進": # 进
if method1[-1] in "13791379":
q0, q1 = 2, "12345678901234567890".index(method1[-1]) % 10
elif method1[-1] in "4646":
q0, q1 = 1, "12345678901234567890".index(method1[-1]) % 10
else:
return (False, False, "走子失败,请正确使用暗马。")
else:
return (False, False, "走子失败,暗马开局唯有进。")
elif p[0] == 9 and p[1] in (2, 6): # 暗相
if method1[-2] in "进進": # 进
if method1[-1] in "一五九壹伍玖":
q0, q1 = 7, 9 - "〇一二三四五六七八九零壹贰叁肆伍陆柒捌玖".index(method1[-1]) % 10
else:
return (False, False, "走子失败,请正确使用暗相。")
else:
return (False, False, "走子失败,暗相开局唯有进。")
elif p[0] == 0 and p[1] in (2, 6): # 暗象
if method1[-2] in "进進": # 进
if method1[-1] in "159159":
q0, q1 = 2, "12345678901234567890".index(method1[-1]) % 10
else:
return (False, False, "走子失败,请正确使用暗象。")
else:
return (False, False, "走子失败,暗象开局唯有进。")
elif p[0] == 9 and p[1] in (3, 5): # 暗仕
if method1[-2] in "进進" and method1[-1] in "五伍": # 进
q0, q1 = 8, 4
else:
return (False, False, "走子失败,暗仕开局唯有进五。")
elif p[0] == 0 and p[1] in (3, 5): # 暗士
if method1[-2] in "进進" and method1[-1] in "55": # 进
q0, q1 = 1, 4
else:
return (False, False, "走子失败,暗士开局唯有进5。")
else:
return (False, False, "暗子起始位置异常,走子失败。")
else:
if method1[-2] == "平": # 平
q0 = p[0]
q1 = 8 - ch_num_list.index(method1[-1]) % 9 if walker else digit_num_list.index(method1[-1]) % 9 # 定位列
else: # 进退(正则表达式已过滤)
if walker: # 红棋
q0 = p[0] + (-(ch_num_list.index(method1[-1]) + 1) if method1[-2] in "进進" else (ch_num_list.index(method1[-1]) + 1)) # 红进为负
else:
q0 = p[0] + ((digit_num_list.index(method1[-1]) + 1) if method1[-2] in "进進" else -(digit_num_list.index(method1[-1]) + 1)) # 黑进为正
q1 = p[1]
q = (q0, q1)
useMethod = 1
elif method0:
pass
else:
return (False, False, "未能识别该格式,请检查。")
for sid, statements in enumerate(self.nextStep):
if "{0}{1}{2}{3}".format(p[0], p[1], q[0], q[1]) == statements[-1]:
return (True, False, "当前局面已存在。")
if 0 <= p[0] <= 9 and 0 <= p[1] <= 8 and 0 <= q[0] <= 9 and 0 <= q[1] <= 8:
pNode = self.lists[0][p[0]][p[1]]
qNode = self.lists[0][q[0]][q[1]]
if self.lists[1] in "WwRr" and "A" <= pNode <= "Z" or self.lists[1] in "BbGg" and "a" <= pNode <= "z": # 红方走子选中红子或黑方走子选中黑子
if (q[0], q[1]) in Node.getAvailableCoordinates(self.mode, pNode, p, self.lists[0], useMethod if isPrintMethod else None): # 走子规则检查
if Node.judgeWhetherCanGo(self.mode, p, q, self.lists[0], self.lists[1] in "WwRr", useMethod if isPrintMethod else None): # 被将军或送将检查(走完后对方可打)
statement = Node.getStatement(self.mode, p, q, self.lists[0], [1, 2, 3, 4])
nextBoard = Board(self.mode, FEN = self.FEN[::], prev = self, prevStep = statement, eaten = None) # 创建新局面(同时使其上一个指向自己并传递吃子顺序)
nextBoard.uncovered = self.uncovered[::]
nextBoard.lists[0][p[0]][p[1]] = "." # 走完子后原位置为空
if self.mode >> 3: # 揭棋
if self.lists[0][p[0]][p[1]] in "Xx": # 是暗子才需要指定
chooseField = [piece for piece in self.uncovered if ("A" <= piece <= "Z" if self.lists[1] in "WwRr" else "a" <= piece <= "z")] # 可选子
if self.mode & 0b0100: # 人工指派
print("字典:{0}".format(Node.name_dict))
print("可选子列表:{0}".format(chooseField))
newNode = None
newNode = input("请输入所走暗子的明子:")
while newNode not in chooseField:
print("输入有误,请按任意键继续。")
getch()
newNode = input("请输入所走暗子的明子:")
else:
newNode = chooseField[randbelow(len(chooseField))]