import pygame
import copy
pygame.init()
white = (255, 255, 255)
black = (0, 0, 0)
board_white = (238, 238, 210)
board_black = (118, 150, 86)
highlight_color = (255, 255, 0, 100)
address = "safsa/"
try:
imgWhiteRook = pygame.image.load(address + "MEETAMER.png")
imgBlackRook = pygame.image.load(address + "GOCKMINANDPOWER.png")
imgWhiteBishop = pygame.image.load(address + "a.png")
imgBlackBishop = pygame.image.load(address + "b.png")
imgBlackKnight = pygame.image.load(address + "g.png")
imgWhiteKnight = pygame.image.load(address + "l.png")
imgWhitePawn = pygame.image.load(address + "download.png")
imgWhiteQueen = pygame.image.load(address + "zld.png")
imgBlackPawn = pygame.image.load(address + "sada.png")
imgWhiteKing = pygame.image.load(address + "znls.png")
imgBlackQueen = pygame.image.load(address + "zld.png")
imgBlackKing = pygame.image.load(address + "znls.png")
except pygame.error as e:
print(f"이미지 로드 중 오류 발생: {e}")
pygame.quit()
exit()
# 화면 설정
width, height = 1024, 1024
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("Chessboard")
clock = pygame.time.Clock()
# 전역 변수
ic, jc = 8, 8
size = width // jc
current_turn = "white"
dragged_piece = None
start_x, start_y = None, None
offset_x, offset_y = 0, 0
game_over = False
winner = None
# 이미지 크기 조정
def scale_images(size):
global objScaleWhiteRook, objScaleBlackRook, objScaleWhiteBishop, objScaleBlackBishop, \
objScaleBlackKnight, objScaleWhiteKnight, objScaleWhitePawn, objScaleWhiteQueen, \
objScaleWhiteKing, objScaleBlackPawn, objScaleBlackQueen, objScaleBlackKing
objScaleWhiteRook = pygame.transform.scale(imgWhiteRook, (size, size))
objScaleBlackRook = pygame.transform.scale(imgBlackRook, (size, size))
objScaleWhiteBishop = pygame.transform.scale(imgWhiteBishop, (size, size))
objScaleBlackBishop = pygame.transform.scale(imgBlackBishop, (size, size))
objScaleBlackKnight = pygame.transform.scale(imgBlackKnight, (size, size))
objScaleWhiteKnight = pygame.transform.scale(imgWhiteKnight, (size, size))
objScaleWhitePawn = pygame.transform.scale(imgWhitePawn, (size, size))
objScaleWhiteQueen = pygame.transform.scale(imgWhiteQueen, (size, size))
objScaleWhiteKing = pygame.transform.scale(imgWhiteKing, (size, size))
objScaleBlackPawn = pygame.transform.scale(imgBlackPawn, (size, size))
objScaleBlackQueen = pygame.transform.scale(imgBlackQueen, (size, size))
objScaleBlackKing = pygame.transform.scale(imgBlackKing, (size, size))
scale_images(size)
# 기물 클래스
class Piece:
def __init__(self, color, type, image):
self.color = color
self.type = type
self.image = image
self.rect = image.get_rect()
self.has_moved = False # 캐슬링을 위한 변수
def __deepcopy__(self, memo):
if self.color == "white":
if self.type == "rook":
new_image = objScaleWhiteRook
elif self.type == "knight":
new_image = objScaleWhiteKnight
elif self.type == "bishop":
new_image = objScaleWhiteBishop
elif self.type == "queen":
new_image = objScaleWhiteQueen
elif self.type == "king":
new_image = objScaleWhiteKing
elif self.type == "pawn":
new_image = objScaleWhitePawn
else: # self.color == "black":
if self.type == "rook":
new_image = objScaleBlackRook
elif self.type == "knight":
new_image = objScaleBlackKnight
elif self.type == "bishop":
new_image = objScaleBlackBishop
elif self.type == "queen":
new_image = objScaleBlackQueen
elif self.type == "king":
new_image = objScaleBlackKing
elif self.type == "pawn":
new_image = objScaleBlackPawn
new_piece = Piece(self.color, self.type, new_image)
new_piece.rect = self.rect.copy() # Rect는 copy() 가능
new_piece.has_moved = self.has_moved
memo[id(self)] = new_piece # 메모에 추가
return new_piece
# 보드 초기화
def setup_board():
board = [[None for _ in range(jc)] for _ in range(ic)]
pieces_setup = {
"black": {
"rook": objScaleBlackRook, "knight": objScaleBlackKnight, "bishop": objScaleBlackBishop,
"queen": objScaleBlackQueen, "king": objScaleBlackKing, "pawn": objScaleBlackPawn
},
"white": {
"rook": objScaleWhiteRook, "knight": objScaleWhiteKnight, "bishop": objScaleWhiteBishop,
"queen": objScaleWhiteQueen, "king": objScaleWhiteKing, "pawn": objScaleWhitePawn
}
}
# 검은색 기물
back_rank_black = ["rook", "knight", "bishop", "queen", "king", "bishop", "knight", "rook"]
for i, piece_type in enumerate(back_rank_black):
board[0][i] = Piece("black", piece_type, pieces_setup["black"][piece_type])
for i in range(jc):
board[1][i] = Piece("black", "pawn", pieces_setup["black"]["pawn"])
# 흰색 기물
back_rank_white = ["rook", "knight", "bishop", "queen", "king", "bishop", "knight", "rook"]
for i, piece_type in enumerate(back_rank_white):
board[7][i] = Piece("white", piece_type, pieces_setup["white"][piece_type])
for i in range(jc):
board[6][i] = Piece("white", "pawn", pieces_setup["white"]["pawn"])
return board
board = setup_board()
# 기물 위치 설정
def set_piece_positions():
for i in range(ic):
for j in range(jc):
if board[i][j]:
board[i][j].rect.topleft = (j * size, i * size)
set_piece_positions()
def is_valid_move(start_y, start_x, end_y, end_x, piece, current_board):
if start_y == end_y and start_x == end_x:
return False
target_piece = current_board[end_y][end_x]
if target_piece and target_piece.color == piece.color:
return False
valid_piece_move = False
if piece.type == "pawn":
direction = 1 if piece.color == "black" else -1
start_row = 1 if piece.color == "black" else 6
# 전진
if start_x == end_x:
if end_y == start_y + direction and current_board[end_y][end_x] is None:
valid_piece_move = True
elif start_y == start_row and end_y == start_y + 2 * direction and current_board[end_y][end_x] is None and \
current_board[start_y + direction][start_x] is None:
valid_piece_move = True
# 대각선 잡기
elif abs(start_x - end_x) == 1 and end_y == start_y + direction and target_piece is not None:
valid_piece_move = True
elif piece.type == "rook":
if start_x == end_x or start_y == end_y:
dx = 0 if start_x == end_x else (1 if end_x > start_x else -1)
dy = 0 if start_y == end_y else (1 if end_y > start_y else -1)
curr_x, curr_y = start_x + dx, start_y + dy
while (curr_x, curr_y) != (end_x, end_y):
if not (0 <= curr_y < 8 and 0 <= curr_x < 8): return False
if current_board[curr_y][curr_x] is not None:
return False
curr_x += dx
curr_y += dy
valid_piece_move = True
elif piece.type == "knight":
dx = abs(start_x - end_x)
dy = abs(start_y - end_y)
valid_piece_move = (dx == 1 and dy == 2) or (dx == 2 and dy == 1)
elif piece.type == "bishop":
if abs(start_x - end_x) == abs(start_y - end_y):
dx = 1 if end_x > start_x else -1
dy = 1 if end_y > start_y else -1
curr_x, curr_y = start_x + dx, start_y + dy
while (curr_x, curr_y) != (end_x, end_y):
if not (0 <= curr_y < 8 and 0 <= curr_x < 8): return False
if current_board[curr_y][curr_x] is not None:
return False
curr_x += dx
curr_y += dy
valid_piece_move = True
elif piece.type == "queen":
is_rook_move = (start_x == end_x or start_y == end_y)
is_bishop_move = (abs(start_x - end_x) == abs(start_y - end_y))
if not (is_rook_move or is_bishop_move):
valid_piece_move = False
else:
if is_rook_move:
dx = 0 if start_x == end_x else (1 if end_x > start_x else -1)
dy = 0 if start_y == end_y else (1 if end_y > start_y else -1)
else: # is_bishop_move
dx = 1 if end_x > start_x else -1
dy = 1 if end_y > start_y else -1
curr_x, curr_y = start_x + dx, start_y + dy
while (curr_x, curr_y) != (end_x, end_y):
if not (0 <= curr_y < 8 and 0 <= curr_x < 8): return False
if current_board[curr_y][curr_x] is not None:
return False
curr_x += dx
curr_y += dy
valid_piece_move = True
elif piece.type == "king":
dx = abs(start_x - end_x)
dy = abs(start_y - end_y)
valid_piece_move = (dx <= 1 and dy <= 1)
if not valid_piece_move:
return False
temp_board = copy.deepcopy(current_board)
temp_piece = temp_board[start_y][start_x]
temp_board[end_y][end_x] = temp_piece
temp_board[start_y][start_x] = None
if is_check(temp_board, piece.color):
return False
return True
# --- 체크메이트 로직 시작 ---
def find_king(board, color):
for r in range(8):
for c in range(8):
piece = board[r][c]
if piece and piece.color == color and piece.type == "king":
return r, c
return None, None # 찾지 못했을 경우 None 반환
def is_check(board, color):
king_y, king_x = find_king(board, color)
if king_y is None or king_x is None:
# 킹이 보드에 없으면 체크가 아님 (게임 종료 상태일 수도 있음)
return False
opponent_color = "black" if color == "white" else "white"
# 모든 상대 기물에 대해 킹을 공격할 수 있는지 확인
for r in range(8):
for c in range(8):
piece = board[r][c]
if piece and piece.color == opponent_color:
# 폰 공격
if piece.type == "pawn":
direction = 1 if piece.color == "black" else -1
if (king_y == r + direction) and (abs(king_x - c) == 1):
return True
# 룩 공격 (직선)
elif piece.type == "rook":
if r == king_y: # 같은 행
step = 1 if king_x > c else -1
path_clear = True
for x_coord in range(c + step, king_x, step):
if board[r][x_coord] is not None:
path_clear = False
break
if path_clear: return True
elif c == king_x: # 같은 열
step = 1 if king_y > r else -1
path_clear = True
for y_coord in range(r + step, king_y, step):
if board[y_coord][c] is not None:
path_clear = False
break
if path_clear: return True
# 나이트 공격 (L자)
elif piece.type == "knight":
dx = abs(king_x - c)
dy = abs(king_y - r)
if (dx == 1 and dy == 2) or (dx == 2 and dy == 1):
return True
# 비숍 공격 (대각선)
elif piece.type == "bishop":
if abs(king_x - c) == abs(king_y - r):
dx = 1 if king_x > c else -1
dy = 1 if king_y > r else -1
path_clear = True
curr_x, curr_y = c + dx, r + dy
while (curr_x, curr_y) != (king_x, king_y):
if board[curr_y][curr_x] is not None:
path_clear = False
break
curr_x += dx
curr_y += dy
if path_clear: return True
# 퀸 공격 (직선 또는 대각선)
elif piece.type == "queen":
# 룩처럼 공격하는 경우
if r == king_y:
step = 1 if king_x > c else -1
path_clear = True
for x_coord in range(c + step, king_x, step):
if board[r][x_coord] is not None:
path_clear = False
break
if path_clear: return True
elif c == king_x:
step = 1 if king_y > r else -1
path_clear = True
for y_coord in range(r + step, king_y, step):
if board[y_coord][c] is not None:
path_clear = False
break
if path_clear: return True
# 비숍처럼 공격하는 경우
elif abs(king_x - c) == abs(king_y - r):
dx = 1 if king_x > c else -1
dy = 1 if king_y > r else -1
path_clear = True
curr_x, curr_y = c + dx, r + dy
while (curr_x, curr_y) != (king_x, king_y):
if board[curr_y][curr_x] is not None:
path_clear = False
break
curr_x += dx
curr_y += dy
if path_clear: return True
# 킹 공격 (상대 킹이 체크 상태에 빠진 킹 주위 1칸에 접근하는 경우)
elif piece.type == "king":
dx = abs(king_x - c)
dy = abs(king_y - r)
if dx <= 1 and dy <= 1:
return True
return False # 어떤 상대 기물도 킹을 공격하지 않으면 체크가 아님
def get_all_legal_moves(board, color):
legal_moves = []
for r in range(8):
for c in range(8):
piece = board[r][c]
if piece and piece.color == color:
for target_r in range(8):
for target_c in range(8):
if is_valid_move(r, c, target_r, target_c, piece, board):
legal_moves.append(((r, c), (target_r, target_c)))
return legal_moves
def check_game_over(board, color):
if is_check(board, color):
# 킹이 체크 상태일 때 합법적인 수가 없으면 체크메이트
if not get_all_legal_moves(board, color):
return "checkmate"
else:
if not get_all_legal_moves(board, color):
return "stalemate"
return None
# 게임 루프 (예시)
running = True
selected_piece_coords = None # 선택된 기물의 (y, x) 좌표
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if not game_over:
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1: # 왼쪽 마우스 버튼
mouse_x, mouse_y = event.pos
clicked_col = mouse_x // size
clicked_row = mouse_y // size
if 0 <= clicked_row < 8 and 0 <= clicked_col < 8:
piece = board[clicked_row][clicked_col]
if piece and piece.color == current_turn:
dragged_piece = piece
start_x, start_y = clicked_col, clicked_row
offset_x = mouse_x - piece.rect.x
offset_y = mouse_y - piece.rect.y
selected_piece_coords = (clicked_row, clicked_col)
else:
selected_piece_coords = None
elif event.type == pygame.MOUSEMOTION:
if dragged_piece:
mouse_x, mouse_y = event.pos
dragged_piece.rect.x = mouse_x - offset_x
dragged_piece.rect.y = mouse_y - offset_y
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 1 and dragged_piece:
end_x, end_y = (event.pos[0] // size), (event.pos[1] // size)
# 보드 범위 내에 있는지 확인
if 0 <= end_y < 8 and 0 <= end_x < 8:
if is_valid_move(start_y, start_x, end_y, end_x, dragged_piece, board):
# 이동 수행
board[end_y][end_x] = dragged_piece
board[start_y][start_x] = None
dragged_piece.has_moved = True # 기물 이동 표시
# 폰 승진 확인 (예시: 흰색 폰이 맨 위 줄에 도착)
if dragged_piece.type == "pawn" and \
((dragged_piece.color == "white" and end_y == 0) or \
(dragged_piece.color == "black" and end_y == 7)):
# 퀸으로 승진
if dragged_piece.color == "white":
board[end_y][end_x] = Piece("white", "queen", objScaleWhiteQueen)
else:
board[end_y][end_x] = Piece("black", "queen", objScaleBlackQueen)
set_piece_positions() # 모든 기물 위치 업데이트
# 턴 변경
current_turn = "black" if current_turn == "white" else "white"
# 게임 종료 확인
game_end_status = check_game_over(board, current_turn)
if game_end_status == "checkmate":
game_over = True
winner = "white" if current_turn == "black" else "black"
print(f"{winner} 승리! 체크메이트!")
elif game_end_status == "stalemate":
game_over = True
winner = "draw"
print("스테일메이트! 무승부!")
else:
# 유효하지 않은 이동이면 원위치
dragged_piece.rect.topleft = (start_x * size, start_y * size)
else:
# 보드 밖으로 이동 시도 시 원위치
dragged_piece.rect.topleft = (start_x * size, start_y * size)
dragged_piece = None
selected_piece_coords = None # 드래그 끝났으니 하이라이트 해제
# 화면 그리기
screen.fill(black)
for r in range(ic):
for c in range(jc):
color = board_white if (r + c) % 2 == 0 else board_black
pygame.draw.rect(screen, color, (c * size, r * size, size, size))
# 선택된 기물의 유효 이동 위치 하이라이트
if selected_piece_coords:
s_row, s_col = selected_piece_coords
selected_piece = board[s_row][s_col]
if selected_piece:
for r in range(8):
for c in range(8):
if is_valid_move(s_row, s_col, r, c, selected_piece, board):
highlight_rect = pygame.Surface((size, size), pygame.SRCALPHA)
highlight_rect.fill(highlight_color)
screen.blit(highlight_rect, (c * size, r * size))
# 기물 그리기
for r in range(ic):
for c in range(jc):
if board[r][c] and board[r][c] != dragged_piece:
screen.blit(board[r][c].image, board[r][c].rect)
# 드래그 중인 기물이 있다면 가장 위에 그리기
if dragged_piece:
screen.blit(dragged_piece.image, dragged_piece.rect)
pygame.display.flip()
clock.tick(60)
pygame.quit()
top of page

실제 작동 상태를 확인하려면 라이브 사이트로 이동하세요.
20251002
20251002
댓글 0개
좋아요
댓글(0)
더 이상 게시물에 대한 댓글 기능이 지원되지 않습니다. 자세한 사항은 사이트 소유자에게 문의하세요.
bottom of page


