python으로 체스 게임 작성 [3일차]
11918 단어 codenewbiepython
우리는 그 중에서 체스 스텝의 기본적인 유효성과 스텝이 유효한지 검사하는 방법을 끝냈지만, 우리는 여전히 그것들을 테스트하지 않았기 때문에, 우리는 그것들이 유효한지 모른다.또는, 더 정확히 말하자면, 코드가 테스트를 거치지 않았기 때문에, 나는 코드가 예상대로 작동하지 않을 것이라고 절대 믿는다. 우리는 어디에 문제가 생겼는지 찾기만 하면 된다.오늘 우리는 테스트를 진행할 것이다.
테스트의 첫 번째 규칙은 테스트가 서로 독립되어야 한다는 것이다. 따라서 우리는 모든 테스트 설정에서 다시 사용하기 위해 회로판 창설 논리를 하나의 단독 방법으로 이동할 것이다.
def create_board():
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"]
return board
12당신이 return
에게 무엇을 했느냐고 물었을 때 나는 설명하기가 좀 어려웠다. 이것은 정말 교육에서 가장 어려운 부분이다. 당신이 잘 아는 것이 당신의 사고방식에 완전히 박혀 있을 때--당신은 return
을 어떻게 설명합니까?내가 생각한 것은 누군가가 이 방법을 호출할 때, 마치 선생님이 우리에게 숙제를 완성하라고 하신 것과 같다는 것이다.만약 우리가 결과를 되돌려 주지 않는다면, 그들은 우리의 일에 접근할 수 없을 것이다. 그것은 우리의 가정 컴퓨터 (방법 범위) 에 남아 있고, 선생님은 그것을 보고 평점을 받을 수 없을 것이다.아마도 나는 본래 더 잘 설명할 수 있었지만, 효과는 매우 좋았다.지금, 나는 우리가 우리의 코드를 테스트하고 싶다고 말했다.우리 어떻게 해야 돼?12yo의 대답은 대체로 코드를 읽고 우리가 어떤 것도 빠뜨리지 않도록 하는 것이다.현재, 이 화이트보드 면접은 매우 좋다. 그러나 우리는 이곳에서 고품질의 소프트웨어를 작성하고, 우리는 테스트를 작성하여, 개발 기간과 생산에 들어간 후에 우리의 안전을 보장하기를 바란다.우리는 우리의 코드를 실행하기 위해 테스트를 작성해야 하며, 그것이 우리의 목적에 도달할 수 있도록 확보해야 한다.
12yo가 테스트를 결정하는 첫 번째 일은 우리가
is_valid_rook_move
방법을 정확하게 실현했는지의 여부이다.이것이 바로 그가 생각한 것이다.def test_rook_is_not_blocked():
board = create_board()
board[1][0] = EMPTY
result = is_valid_rook_move(board, "WR", 2, 0)
print(board)
print(result)
출력: ---- ---- ---- ---- ---- ---- ---- ----
8 | BR | BN | BB | BQ | BK | BB | BN | BR |
---- ---- ---- ---- ---- ---- ---- ----
7 | BP | BP | BP | BP | BP | BP | BP | BP |
---- ---- ---- ---- ---- ---- ---- ----
6 | | | | | | | | |
---- ---- ---- ---- ---- ---- ---- ----
5 | | | | | | | | |
---- ---- ---- ---- ---- ---- ---- ----
4 | | | | | | | | |
---- ---- ---- ---- ---- ---- ---- ----
3 | | | | | | | | |
---- ---- ---- ---- ---- ---- ---- ----
2 | | WP | WP | WP | WP | WP | WP | WP |
---- ---- ---- ---- ---- ---- ---- ----
1 | WR | WN | WB | WQ | WK | WB | WN | WR |
---- ---- ---- ---- ---- ---- ---- ----
a b c d e f g h
False
잠깐만, 뭐라고?이것은 마땅히 효과적인 행동이어야 한다!이 차의 길은 완전히 개방되었다.우리는 코드에 print
명령을 추가했는데, 첫 번째 순환 후에 우리가 막 종료한 것을 발견했다.def is_valid_rook_move(board, 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:
...
읊다, 읊조리다그래...아마 if found_rank == -1
!!!우리는 목표 파일 (열) 에서 한 부분을 찾으려고 하지만, 전제는 목표 열 (줄) 에서 찾지 못했다는 것이다.고쳤어, 성공했어!출력:
---- ---- ---- ---- ---- ---- ---- ----
8 | BR | BN | BB | BQ | BK | BB | BN | BR |
---- ---- ---- ---- ---- ---- ---- ----
7 | BP | BP | BP | BP | BP | BP | BP | BP |
---- ---- ---- ---- ---- ---- ---- ----
6 | | | | | | | | |
---- ---- ---- ---- ---- ---- ---- ----
5 | | | | | | | | |
---- ---- ---- ---- ---- ---- ---- ----
4 | | | | | | | | |
---- ---- ---- ---- ---- ---- ---- ----
3 | | | | | | | | |
---- ---- ---- ---- ---- ---- ---- ----
2 | | WP | WP | WP | WP | WP | WP | WP |
---- ---- ---- ---- ---- ---- ---- ----
1 | WR | WN | WB | WQ | WK | WB | WN | WR |
---- ---- ---- ---- ---- ---- ---- ----
a b c d e f g h
True
쿨!여기 assert
명령을 소개했습니다.나는 그에게 만약 우리가 많은 테스트를 썼다면, 우리는 모든 테스트의 예상 결과를 기억하기 어려울 것이다. 우리가 원하는 것은 간단하고 사용하기 쉬운 것이며, 우리에게 신뢰할 수 있는 빠른 결과를 줄 수 있을 것이라고 말했다.단언문: 이 말이 사실입니까?만약 없다면, 우리가 편리하게 사용할 수 있도록 빨간색 오류가 발생할 것이다.오류가 없으면 테스트가 성공적으로 실행되었는지 확인하기 위해 인쇄해야 합니다. (이 부분을 썼습니다.)def test_rook_is_not_blocked():
board = create_board()
board[1][0] = EMPTY
result = is_valid_rook_move(board, "WR", 2, 0)
assert result
print("test_rook_is_not_blocked passed")
출력:test_rook_is_not_blocked passed
우리는 막힌 차를 대상으로 하는 테스트와 수평 이동을 위한 테스트 용례를 추가했다. (완전한 코드가 앞에 있으니 지금은 걱정할 필요가 없다.)그리고 저희도 기본적인
is_valid_move
방법을 테스트해 보도록 하겠습니다. 맞혀보세요!우리도 거기서 벌레 한 마리를 발견했어...if 0 > target_file > 7
부작용: 얼굴 손바닥:.다음으로 변경:
def is_valid_move(board, piece, target_rank, target_file):
# out of bounds
if target_rank < 0 or target_rank > 7:
return False
if target_file < 0 or 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)
return True
우리는 마침내 다음과 같은 테스트 세트를 얻었다. (내가 휴대전화에서 소셜 미디어를 볼 때 그가 이 모든 것을 썼다. 와)def test_is_rank_valid():
board = create_board()
result = is_valid_move(board, "xx", 22, 4)
assert not result
result = is_valid_move(board, "xx", -2020, 4)
assert not result
result = is_valid_move(board, "xx", 0, 4)
assert result
print("test_is_rank_valid passed")
def test_is_file_valid():
board = create_board()
result = is_valid_move(board, "xx", 0, 22)
assert not result
result = is_valid_move(board, "xx", 0, -2020)
assert not result
result = is_valid_move(board, "xx", 0, 4)
assert result
print("test_is_file_valid passed")
def test_is_target_square_taken():
board = create_board()
result = is_valid_move(board, "Wx", 0, 1)
assert not result
print("test_is_target_square_taken passed")
def test_rook_is_blocked():
board = create_board()
result = is_valid_rook_move(board, "BR", 5, 0)
assert not result
board[7][5] = EMPTY
result = is_valid_rook_move(board, "BR", 7, 5)
assert not result
print("test_rook_is_blocked passed")
def test_rook_is_not_blocked():
board = create_board()
board[1][0] = EMPTY
result = is_valid_rook_move(board, "WR", 2, 0)
assert result
board[0][1] = EMPTY
result = is_valid_rook_move(board, "WR", 0, 1)
assert result
print("test_rook_is_not_blocked passed")
def run_tests():
test_is_rank_valid()
test_is_file_valid()
test_is_target_square_taken()
test_rook_is_blocked()
test_rook_is_not_blocked()
run_tests()
출력:test_is_rank_valid passed
test_is_file_valid passed
test_is_target_square_taken passed
test_rook_is_blocked passed
test_rook_is_not_blocked passed
그래!!!내가 처리해야 할 마지막 일은
is_valid_rook_move
의 믿을 수 없는 플러그인if and 순환이다.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
나는 12yo에게 우리가 여기서 추출할 수 있는 공통된 논리가 있는지 물었다. 솔직히 그는 없었다. 그러나 괜찮아. 이것은 좀 이해하기 어렵다.목표 블록을 찾기 전이나 후에 찾든 논리는 똑같다. 코드가 어디에서 시작되고 언제 끝날지 알려주기만 하면 된다.우리는 이렇게 색인을 추출한다. (나는 이 부분을 썼다.)if found_rank == target_rank:
start_file = min(target_file+1, found_file+1)
end_file = max(target_file, found_file)
for i in range(start_file, end_file):
if board[target_rank][i] != EMPTY:
return False
else: # found_file == target_file
start_rank = min(target_rank+1, found_rank+1)
end_rank = max(target_rank, found_rank)
for i in range(start_rank, end_rank):
if board[i][target_file] != EMPTY:
return False
테스트를 다시 실행합니다.test_is_rank_valid passed
test_is_file_valid passed
test_is_target_square_taken passed
test_rook_is_blocked passed
test_rook_is_not_blocked passed
두 배야!!!오늘의 최종 코드(위의 화려한 테스트 세트까지):
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("")
def create_board():
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"]
return board
def is_valid_move(board, piece, target_rank, target_file):
# out of bounds
if target_rank < 0 or target_rank > 7:
return False
if target_file < 0 or 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)
return True
def is_valid_rook_move(board, 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:
start_file = min(target_file+1, found_file+1)
end_file = max(target_file, found_file)
for i in range(start_file, end_file):
if board[target_rank][i] != EMPTY:
return False
else: # found_file == target_file
start_rank = min(target_rank+1, found_rank+1)
end_rank = max(target_rank, found_rank)
for i in range(start_rank, end_rank):
if board[i][target_file] != EMPTY:
return False
return True
오늘은 여기까지.내일 저희에 가입하세요. 저희가 칠판에서 루트를 실제로 이동할 때...
Reference
이 문제에 관하여(python으로 체스 게임 작성 [3일차]), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/rinaarts/writing-a-chess-game-in-python-day-3-2k0m텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)