Stage 8 ゲームを進行する
8-4 リザインを処理する
リザインのイベントコードの処理はこんなもん。
# resign code
if main_board.s in ['X', 'x']:
winner = -main_board.player
break
「1-0」とかでリザインできることを知らない人のために、脱出用のコマンド X を用意してあげています。
入力している人が負けを認める形にしたいので、winner は相手です。これがもし winner を自分にできるようにしてしまうと、ゲーム始まった瞬間に
はい俺の勝ちー
とできてしまいますので。
break は大枠の while ループからの脱出。これでゲーム終了させます。
~~~~~~~~~~~~~~~
"Z" は Stage 9 でやります。
Stage 9 でやります。
そんな突っかかるなって
これ以外の正規の入力は s_analyze メソッドで対処できますね。対処できるように Stage 7 であんなに頑張って s_analyze をコーディングしたんですから。
では一度ここから先のコードを見てみましょう。
# motion detection
motion = main_board.s_analyze()
# game set (resign)
if type(motion) is int:
if motion == EMPTY:
# necessary to agree to end the game
if main_board.player == WHITE:
print('Do you agree, BLACK (y/n)? >>>', end=' ')
elif main_board.player == BLACK:
print('Do you agree, WHITE (y/n)? >>>', end=' ')
else:
logger.error('UNEXPECTED VALUE of PLAYER in the while loop')
print('SYSTEM ERROR')
sys.exit('SYSTEM ERROR')
# when agreed
if input() in ['y', 'Y']:
winner = EMPTY
break
# when rejected
else:
main_board.print(turnmode=turnmode, reverse=False)
continue
continue
elif motion == WHITE == -main_board.player:
winner = WHITE
break
elif motion == BLACK == -main_board.player:
winner = BLACK
break
else:
print('IVNALID INPUT')
continue
# invalid input (here, valid motion is conducted)
if motion == False or main_board.move(*motion) == False:
print('INVALID INPUT/MOTION')
continue
...
相変わらずなげーな
プレーヤーによって場合わけすることが多いので、見た目よりも記述量は少なく感じると思いますよ。
~~~~~~~~~~~~~~~
まず s_analyze の結果を motion という変数に格納しています。
# motion detection
motion = main_board.s_analyze()
# game set (resign)
if type(motion) is int:
...
s_analyze の返り値の型はこんな感じ。
駒を動かす | list | [frFILE, frRANK, toFILE, toRANK, promote] | |
勝敗 | int | 白勝ち (1-0) | WHITE (== 1) |
黒勝ち (0-1) | BLACK (== -1) | ||
引き分け (1/2 - 1/2) | EMPTY (== 0) | ||
エラー | bool | False |
したがって、motion からもリザインを判断できるようにしなければいけません。
おいおい、1-0 ってちゃんと書いたのにゲーム終わんねーぞクソが
とか言われないようにね。
表の通り、motion が int 型であればリザインですから、
if type(motion) is int:
として判断します。
if の中身はイベントコードで "X" を入力した時と大体変わらないんですが、引き分けの時はしっかり相手の許可をとりましょう。
ちょっとこの感じ負ける気しかしないから引き分けにしとくわ
って乱発されたらたまったもんじゃないでしょう。だから必ず相手に同意するか聞いてください。
~~~~~~~~~~~~~~~
では相手が同意するかお伺いをたてる機能を実装します。
if motion == EMPTY:
# necessary to agree to end the game
if main_board.player == WHITE:
print('Do you agree, BLACK (y/n)? >>>', end=' ')
elif main_board.player == BLACK:
print('Do you agree, WHITE (y/n)? >>>', end=' ')
else:
logger.error('UNEXPECTED VALUE of PLAYER in the while loop')
print('SYSTEM ERROR')
sys.exit('SYSTEM ERROR')
# when agreed
if input() in ['y', 'Y']:
winner = EMPTY
break
# when rejected
else:
main_board.print(turnmode=turnmode, reverse=False)
continue
一つ一つみていきましょう。まず最初の if 分岐は「引き分けかどうか」です。引き分けでなければ相手の同意は不要でしょ?
ダメだ。勝手に負けるのは許さん
って、漫画とかならよくありそうですが現実ではあまり機会がないでしょう。
~~~~~~~~~~~~~~~
その次は実際に相手プレーヤーにお伺いする文言です。「引き分けしたいって言ってますけど、よろしいですか?」ということ。
# necessary to agree to end the game
if main_board.player == WHITE:
print('Do you agree, BLACK (y/n)? >>>', end=' ')
elif main_board.player == BLACK:
print('Do you agree, WHITE (y/n)? >>>', end=' ')
else:
logger.error('UNEXPECTED VALUE of PLAYER in the while loop')
print('SYSTEM ERROR')
sys.exit('SYSTEM ERROR')
もし答えが yes なら引き分けとしますので、winner を EMPTY にして全体を回してる while ループから脱出します。8-2 からずっと回してるやつ。
# when agreed
if input() in ['y', 'Y']:
winner = EMPTY
break
それ以外ではもちろんゲームを終わらせるわけにはいきませんから、8-4 のヘルプの後のように盤面を再表示して while 先頭に戻ります。
# when rejected
else:
main_board.print(turnmode=turnmode, reverse=False)
continue
ここまでで引き分けのリザインの実装は完了です。
~~~~~~~~~~~~~~~
負けを認める場合のコードも実装しますよ。てかそもそもこっちが本題。
elif motion == WHITE == -main_board.player:
winner = WHITE
break
elif motion == BLACK == -main_board.player:
winner = BLACK
break
motion が WHITE であれば黒が負けを認めていますので、winner は WHITE, 逆も然りです。またリザインは必ず
自分が負けを認める
形でないといけませんから、motion が WHITE のときは player が BLACK か、逆なら逆かもみてあげる必要があります。
~~~~~~~~~~~~~~~
最後に motion が int でありながら、ここまでどこにも引っかかってこなかった可哀想な子たちをどうにかしてあげます。
else:
print('IVNALID INPUT')
continue
以上でリザインの処理は終了です。お疲れ様でした。