Python [ 2日]でチェスゲームを書く
6359 ワード
我々はまだCOVID - 19のためにロックダウンにあります、そして、私は私の12 yoでテキストチェスゲームを実装するために時間を使っています.このシリーズでは、私たちがしたこととプロジェクトがどのように進化したかを共有します.
私たちは2次元ボードを印刷する方法で出発しました.
私たちは、次のステップについて少し話をしました-ユーザーからの入力を得て、それを解析してください、さもなければ、動きの論理を実行し始めてください.12 yo移動を実装するために選んだ.彼が言ったことによると、このメソッドの動作方法を定義しましたユーザーは移動するために、そして、それが行くべきであるところ(目標正方形) の名前を提供しますは、移動が有効であるかどうか決定し、一致する部分 を見つける移動が有効な場合、我々は、ターゲットの正方形に一致する部分を移動します. この点で、12 yoは、チェス行がランクとコラムと呼ばれていることを指摘しました、そして、コラムはファイルです.まあ、sorrrrry:アイロール:.これが定義されたインターフェースです.
ターゲットの四角形には、同じ色の部分がないことを確認する必要があります.
最初に、我々は同じランクの上で、または、目標広場と同じファイルの上にルークがあるかどうかチェックする必要があります.
待って、しかし、作品が既にターゲットの広場にある場合?
実は.ターゲットの正方形に同じ色の部分があるかどうかをチェックした状態で既にカバーされています.さあ、動きましょう.
次のことを確認する必要がある別の部分は、ターゲットの広場に我々の方法をブロックしている場合です.しかし、我々の前の実装は、私たちにこれを理解するのに十分な情報を与えませんでした.それで、我々が我々が作品を見つけたところのインデックスを含むように我々の実装を変えましょう.我々は実際には、後で我々は移動を実行するが、スポイラーを取得する必要があります!
今日の最後のコードはこちら
私たちは2次元ボードを印刷する方法で出発しました.
私たちは、次のステップについて少し話をしました-ユーザーからの入力を得て、それを解析してください、さもなければ、動きの論理を実行し始めてください.12 yo移動を実装するために選んだ.彼が言ったことによると、このメソッドの動作方法を定義しました
def is_valid_move(piece, target_rank, target_file):
pass
最初にチェックするのは、ターゲットの正方形がボードの境界にある場合です.def is_valid_move(piece, target_rank, target_file):
# out of bounds
if 0 > target_rank > 7:
return False
if 0 > target_file > 7:
return False
OK、クール.次は何ですか.ターゲットの四角形には、同じ色の部分がないことを確認する必要があります.
...
# piece with same color is in the target cell
if board[target_rank][target_file][0] == piece[0]:
return False
今何?12 yoは我々がRookのために有効であるかどうかチェックし始めることを提案しました. ...
if piece in ("WR", "BR"):
pass
どうやってこれをやるの?最初に、我々は同じランクの上で、または、目標広場と同じファイルの上にルークがあるかどうかチェックする必要があります.
...
found = False
for i in range(8):
if (board[target_rank][i] == piece):
found = True
break
for i in range(8):
if (board[i][target_file] == piece):
found = True
break
return found
Remember that we're doing a naive solution and we'll deal with optimizations later, there are definitely better ways to write this code!
待って、しかし、作品が既にターゲットの広場にある場合?
実は.ターゲットの正方形に同じ色の部分があるかどうかをチェックした状態で既にカバーされています.さあ、動きましょう.
次のことを確認する必要がある別の部分は、ターゲットの広場に我々の方法をブロックしている場合です.しかし、我々の前の実装は、私たちにこれを理解するのに十分な情報を与えませんでした.それで、我々が我々が作品を見つけたところのインデックスを含むように我々の実装を変えましょう.我々は実際には、後で我々は移動を実行するが、スポイラーを取得する必要があります!
...
found_rank = -1
found_file = -1
for i in range(8):
if board[target_rank][i] == piece:
found_rank = target_rank
found_file = i
break
# TODO: deal with the case where there are two matching pieces
if found_rank > -1:
for i in range(8):
if board[i][target_file] == piece:
found_rank = i
found_file = target_file
break
if found_rank < 0 or found_file < 0:
return False
それでは、見つけた作品とターゲットセルの間に何かがあるか確認しましょう....
if found_rank == target_rank:
if found_file > target_file:
for i in range(target_file+1, found_file):
if board[target_rank][i] != " ":
return False
else: # found_file < target_file
for i in range(found_file+1, target_file):
if board[target_rank][i] != " ":
return False
else: # found_file == target_file
if found_rank > target_rank:
for i in range(target_rank+1, found_rank):
if board[i][target_file] != " ":
return False
else: # found_rank < target_rank
for i in range(found_rank+1, target_rank):
if board[i][target_file] != " ":
return False
return True
私はその文字列比較を好まないので、それをより明確にするために定数に変えました.EMPTY = " "
すべてのロジックを別々のメソッドに詰め込みましょう.私たちも、白が底にあるけれども、インデックスが0 - 7であると理解しました、したがって、我々はおそらく我々が板を定義して、それをボトムアップに印刷する方法を逆にしたいです.今日の最後のコードはこちら
EMPTY = " "
def print_board(board):
row_number = 8
print(" ", end="")
print(" ----"*8)
for row in reversed(board):
print(row_number, end=" ")
row_number -= 1
for cell in row:
print("| {} ".format(cell), end="")
print("|")
print(" ", end="")
print(" ----"*8)
print(" ", end="")
for letter in ['a','b','c','d','e','f','g','h']:
print(" {} ".format(letter), end="")
print("")
board = [[EMPTY]*8]*8
board[0] = ["WR","WN","WB","WQ","WK","WB","WN","WR"]
board[1] = ["WP","WP","WP","WP","WP","WP","WP","WP"]
board[6] = ["BP","BP","BP","BP","BP","BP","BP","BP"]
board[7] = ["BR","BN","BB","BQ","BK","BB","BN","BR"]
def is_valid_move(piece, target_rank, target_file):
# out of bounds
if 0 > target_rank > 7:
return False
if 0 > target_file > 7:
return False
# piece with same color is in the target cell
if board[target_rank][target_file][0] == piece[0]:
return False
if piece in ("WR", "BR"):
return is_valid_rook_move(piece, target_rank, target_file)
def is_valid_rook_move(piece, target_rank, target_file):
found_rank = -1
found_file = -1
for i in range(8):
if board[target_rank][i] == piece:
found_rank = target_rank
found_file = i
break
if found_rank > -1:
for i in range(8):
if board[i][target_file] == piece:
found_rank = i
found_file = target_file
break
if found_rank < 0 or found_file < 0:
return False
if found_rank == target_rank:
if found_file > target_file:
for i in range(target_file+1, found_file):
if board[target_rank][i] != EMPTY:
return False
else: # found_file < target_file
for i in range(found_file+1, target_file):
if board[target_rank][i] != EMPTY:
return False
else: # found_file == target_file
if found_rank > target_rank:
for i in range(target_rank+1, found_rank):
if board[i][target_file] != EMPTY:
return False
else: # found_rank < target_rank
for i in range(found_rank+1, target_rank):
if board[i][target_file] != EMPTY:
return False
return True
私はこの権利を得たかどうかわからないが、12 yoは疲れていたので、ここで止まりました.テストのために明日我々に加わってください!Reference
この問題について(Python [ 2日]でチェスゲームを書く), 我々は、より多くの情報をここで見つけました https://dev.to/rinaarts/writing-a-chess-game-in-python-day-2-3blnテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol