Перейти к содержимому

Как написать шахматы на python

  • автор:

Написание шахмат за 1 час с помощью СhatGPT

Цель этого эксперимента — проверить способности написания кода chatGPT.

Давайте посмотрим на диалог, который у меня был с chatGPT

Вопрос: Давай вместе напишем программу шахмат на Python

Ответ: Конечно, это звучит очень интересно! Прежде чем мы начнём, я должен упомянуть, что написание полнофункциональной шахматной программы является нетривиальной задачей и, вероятно, потребует значительного количества времени и усилий. Однако мы, безусловно, можем начать с обсуждения некоторых основных концепций и идей, которые были бы задействованы в таком проекте.

Для начала нам нужно было бы представить состояние шахматной доски в нашей программе. Это можно было бы сделать с помощью двумерного массива, где каждый элемент массива представляет собой один квадрат на шахматной доске. Нам нужно было бы сохранить тип фигуры, которая занимает каждый квадрат, а также любую другую соответствующую информацию, такую как переместилась ли фигура, угрожают ли ей какие-либо другие фигуры и т.д.

Как только у нас появится способ представить состояние шахматной доски, нам нужно будет внедрить правила шахмат. Это включало бы такие вещи, как обеспечение того, чтобы фигуры двигались только теми способами, которые им разрешены (например, слон может двигаться только по диагонали), предотвращение совершения игроками незаконных ходов (таких как перемещение фигуры на квадрат, который занят одной из их собственных фигур), и обработка специальных ходов, таких как рокировка и взятие на проходе.

Далее нам нужно было бы реализовать логику игры, которая включала бы отслеживание того, чья очередь, проверку окончания игры (например, когда игрок ставит мат) и обработку других аспектов игры, таких как продвижение пешки и захват фигур.

Наконец, нам нужно было бы реализовать какой-то пользовательский интерфейс, такой как интерфейс командной строки или графический пользовательский интерфейс, чтобы позволить игрокам взаимодействовать с программой и делать свои ходы.

В целом, при написании шахматной программы необходимо учитывать множество различных аспектов, и для её правильного выполнения потребуется хорошее понимание правил шахмат и тщательное планирование. Тем не менее, я думаю, что это был бы сложный и полезный проект для работы, и я с нетерпением жду возможности услышать больше о ваших идеях о том, как подойти к нему!

Вопрос: Начни с генерации кода шахматной доски

Ответ: Конечно, мы можем начать с внедрения шахматной доски. Как я упоминал ранее, одним из способов сделать это было бы использование двумерного массива, где каждый элемент массива представляет собой один квадрат на шахматной доске. Вот один из возможных способов сделать это:

Saved searches

Use saved searches to filter your results more quickly

Cancel Create saved search

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.

Шахматы на Python

SergeyLebidko/PyChess

This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Switch branches/tags
Branches Tags
Could not load branches
Nothing to show
Could not load tags
Nothing to show

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Cancel Create

  • Local
  • Codespaces

HTTPS GitHub CLI
Use Git or checkout with SVN using the web URL.
Work fast with our official CLI. Learn more about the CLI.

Sign In Required

Please sign in to use Codespaces.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching Xcode

If nothing happens, download Xcode and try again.

Launching Visual Studio Code

Your codespace will open once ready.

There was a problem preparing your codespace, please try again.

Latest commit

555f6f7 Aug 5, 2020

Git stats

Files

Failed to load latest commit information.

Latest commit message
Commit time
August 5, 2020 16:49
November 12, 2019 20:07
September 26, 2019 00:33
September 26, 2019 00:33
September 26, 2019 00:33
September 26, 2019 00:33
September 26, 2019 00:33
September 26, 2019 01:01
September 26, 2019 01:01

README.md

Простая шахматная программа. Написана на python 3.7 (с использованием библиотеки pygame 1.9.6). Для начала новой партии необходимо запустить файл start_white.pyw (играть белыми) или start_black.pyw (играть черными). Файлы пакета game_pack:

  • game.py Функции, входящие в файл необходимы для создания и работы интерфейса. Они отрисовывают доску, фигуры, доступные ходы, сообщения, выводимые пользователю, принимают и обрабатывают щелчки мышкой.
  • params.py Параметры игры: цветовые константы, типы ходов, список приоритетов фигур и т.д.
  • figures.py Файл содержит классы, описывающие шахматные фигуры. Все они унаследованы от одного общего класса Figure (в свою очередь унаследованного от pygame.sprite.Sprite), содержащего код, необходимый для хранения координат фигур и их перерисовки. Каждый класс фигуры, содержит метод get_actions, который возвращает список клеток, на которые могла бы походить фигура.
  • boards.py Содержит классы, необходимые для представления игрового поля (Board), ходов (Move) и селектора фигур (SelectorBoard), используемого при выборе фигуры, на которую следует заменить пешку, дошедшую до края поля. Самый сложный и функциональный из них — Board. Он представляет игровое поле и действия на нём. Board содержит методы для получения списка доступных на поле ходов, применения ходов и их отката, а так же оценки текущей позиции. При получении списка доступных ходов учитывается возможность рокировки (как левой, так и правой), взятия пешки на проходе, конверсии пешки в другую фигуру. Также ходы фильтруются и отбрасываются те, которые ведут к шаху собственному королю (например, ходы, открывающие удар дальнобойным фигурам противника). При получении оценки текущей позиции учитываются относительная сила отдельных фигур (конь ценнее пешки, ферзь ценнее коня), позиция фигур на доске (слонам предпочтительно занять главные диагонали, коням предпочтительно быть как можно ближе к центру поля и т.д.), защита своих фигур и атака на чужие (напрмер, чем больше фигур противника находится под ударом, тем сильнее ваша позиция).
  • ai.py В файле содержится код, необходимый для расчета ответного хода компьютера. Использован алгоритм минимакс с отсечением заведомо неудачных позиций. Для ускорения работы просчет ведется на 4 хода вперед (таким образом, на ответный ход компьютер тратит максимум несколько секунд на процессоре core i5-2500). Также оптимизирован порядок просчета ходов: вначале оцениваются ходы-взятия, которые заведомо быстрее ведут к значимым изменениям на доске и быстрее вызывают отсечение.

Скриншоты приведены ниже

Шахматы на Python

Шахматы в Python
Приветствую! Есть проблема с задачей, связанной с шахматами. Есть белый король и две черные фигуры.

Готические Шахматы и Шахматы Януса
Программы — компьютерные противники, реализующие сабж? — где скачать? (можно лицензионные и платные.

шахматы
здравствуйте пожлуйста напишите мне игру шахматная ситуация, состоящая из 2 королей и из 2.

Шахматы
По умолчанию Ферзь, ладья и конь Ферзь, ладья и конь На шахматной доске 8х8 расположены три.

C++ и шахматы.
Дали такое задание по курсовой, не могу понять как написать программу. Помогите пожалуйста. Даны.

1183 / 759 / 277
Регистрация: 05.09.2021
Сообщений: 1,772
Alina_chebv, давай, выкладывай понемногу свои наработки, я помогу с функциями.
Регистрация: 15.10.2019
Сообщений: 161

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
WHITE = 1 BLACK = 2 def opponent(color): if color == WHITE: return BLACK else: return WHITE def print_board(board): print(' +----+----+----+----+----+----+----+----+') for row in range(7, -1, -1): print(' ', row, end=' ') for col in range(8): print('|', board.cell(row, col), end=' ') print('|') print(' +----+----+----+----+----+----+----+----+') print(end=' ') for col in range(8): print(col, end=' ') print() def main(): board = Board() while True: print_board(board) print('Команды:') print(' exit -- выход') print(' move    -- ход из клетки (row, col)') print(' в клетку (row1, col1)') if board.current_player_color() == WHITE: print('Ход белых:') else: print('Ход чёрных:') command = input() if command == 'exit': break move_type, row, col, row1, col1 = command.split() row, col, row1, col1 = int(row), int(col), int(row1), int(col1) if board.move_piece(row, col, row1, col1): print('Ход успешен') else: print('Координаты некорректы! Попробуйте другой ход!') def correct_coords(row, col): return 0  row  8 and 0  col  8 class Board: def __init__(self): self.color = WHITE self.field = [] for row in range(8): self.field.append([None] * 8) self.field[0] = [ Rook(WHITE), Knight(WHITE), Bishop(WHITE), Queen(WHITE), King(WHITE), Bishop(WHITE), Knight(WHITE), Rook(WHITE) ] self.field[1] = [ Pawn(WHITE), Pawn(WHITE), Pawn(WHITE), Pawn(WHITE), Pawn(WHITE), Pawn(WHITE), Pawn(WHITE), Pawn(WHITE) ] self.field[6] = [ Pawn(BLACK), Pawn(BLACK), Pawn(BLACK), Pawn(BLACK), Pawn(BLACK), Pawn(BLACK), Pawn(BLACK), Pawn(BLACK) ] self.field[7] = [ Rook(BLACK), Knight(BLACK), Bishop(BLACK), Queen(BLACK), King(BLACK), Bishop(BLACK), Knight(BLACK), Rook(BLACK) ] def current_player_color(self): return self.color def cell(self, row, col): piece = self.field[row][col] if piece is None: return ' ' color = piece.get_color() c = 'w' if color == WHITE else 'b' return c + piece.char() def get_piece(self, row, col): if correct_coords(row, col): return self.field[row][col] else: return None def move_piece(self, row, col, row1, col1): if not correct_coords(row, col) or not correct_coords(row1, col1): return False if row == row1 and col == col1: return False piece = self.field[row][col] if piece is None: return False if piece.get_color() != self.color: return False if self.field[row1][col1] is None: if not piece.can_move(self, row, col, row1, col1): return False elif self.field[row1][col1].get_color() == opponent(piece.get_color()): if not piece.can_attack(self, row, col, row1, col1): return False else: return False if piece.__class__.__name__ in {'Rook', 'King'}: piece.move() self.field[row][col] = None self.field[row1][col1] = piece self.color = opponent(self.color) return True def move_and_promote_pawn(self, row, col, row1, col1, char): if self.field[row][col].char() != 'P': return False piece = self.field[row][col] color = self.field[row][col].get_color() if piece.can_move(self, row, col, row1, col1)\ or piece.can_attack(self, row, col, row1, col1): self.move_piece(row, col, row1, col1) if char == 'Q': self.field[row1][col1] = Queen(color) elif char == 'R': self.field[row1][col1] = Rook(color) elif char == 'B': self.field[row1][col1] = Bishop(color) elif char == 'N': self.field[row1][col1] = Knight(color) return True return False def castling0(self): if self.color == WHITE: if self.field[0][0] is None: return False if self.field[0][0].char() != 'R': return False if self.field[0][0].has_moved: return False if self.field[0][4] is None: return False if self.field[0][4].char() != 'K': return False if self.field[0][4].has_moved: return False if self.field[0][0].can_move(self, 0, 0, 0, 3): if self.field[0][3] is not None: return False self.move_piece(0, 0, 0, 3) self.color = opponent(self.color) self.move_piece(0, 4, 0, 2) return True else: if self.field[7][0] is None: return False if self.field[7][0].char() != 'R': return False if self.field[7][0].has_moved: return False if self.field[7][4] is None: return False if self.field[7][4].char() != 'K': return False if self.field[7][4].has_moved: return False if self.field[7][0].can_move(self, 7, 0, 7, 3): if self.field[7][3] is not None: return False self.move_piece(7, 0, 7, 3) self.color = opponent(self.color) self.move_piece(7, 4, 7, 2) return True return False def castling7(self): if self.color == WHITE: if self.field[0][7] is None: return False if self.field[0][7].char() != 'R': return False if self.field[0][7].has_moved: return False if self.field[0][4] is None: return False if self.field[0][4].char() != 'K': return False if self.field[0][4].has_moved: return False if self.field[0][7].can_move(self, 0, 7, 0, 5): if self.field[0][5] is not None: return False self.move_piece(0, 7, 0, 5) self.color = opponent(self.color) self.move_piece(0, 4, 0, 6) return True else: if self.field[7][7] is None: return False if self.field[7][7].char() != 'R': return False if self.field[7][7].has_moved: return False if self.field[7][4] is None: return False if self.field[7][4].char() != 'K': return False if self.field[7][4].has_moved: return False if self.field[7][7].can_move(self, 7, 7, 7, 5): if self.field[7][5] is not None: return False self.move_piece(7, 7, 7, 5) self.color = opponent(self.color) self.move_piece(7, 4, 7, 6) return True return False class Rook: def __init__(self, color): self.color = color self.has_moved = False def move(self): self.has_moved = True def get_color(self): return self.color def char(self): return 'R' def can_move(self, board, row, col, row1, col1): color = board.get_piece(row, col).get_color() if row != row1 and col != col1: return False if row == row1 and col == col1: return False step = 1 if (row1 >= row) else -1 for r in range(row + step, row1, step): # Если на пути по горизонтали есть фигура if not (board.get_piece(r, col) is None): return False step = 1 if (col1 >= col) else -1 for c in range(col + step, col1, step): # Если на пути по вертикали есть фигура if not (board.get_piece(row, c) is None): return False if board.get_piece(row1, col1) is not None: return board.get_piece(row1, col1).get_color() == opponent(color) return True def can_attack(self, board, row, col, row1, col1): return self.can_move(board, row, col, row1, col1) class Pawn: def __init__(self, color): self.color = color def get_color(self): return self.color def char(self): return 'P' def can_move(self, board, row, col, row1, col1): if col != col1: return False if self.color == WHITE: direction = 1 start_row = 1 else: direction = -1 start_row = 6 if row + direction == row1: return board.get_piece(row1, col1) is None if (row == start_row and row + 2 * direction == row1 and board.field[row + direction][col] is None): return board.get_piece(row1, col1) is None return False def can_attack(self, board, row, col, row1, col1): direction = 1 if (self.color == WHITE) else -1 if (row + direction == row1 and (col + 1 == col1 or col - 1 == col1)): return board.get_piece(row1, col1).get_color() == opponent(self.color) class Knight: def __init__(self, color): self.color = color def get_color(self): return self.color def char(self): return 'N' def can_move(self, board, row, col, row1, col1): return True # Заглушка def can_attack(self, board, row, col, row1, col1): return self.can_move(board, row, col, row1, col1) class King: def __init__(self, color): self.color = color self.has_moved = False def get_color(self): return self.color def move(self): self.has_moved = True def char(self): return 'K' def can_move(self, board, row, col, row1, col1): return True # Заглушка def can_attack(self, board, row, col, row1, col1): return self.can_move(board, row, col, row1, col1) class Queen: def __init__(self, color): self.color = color def get_color(self): return self.color def char(self): return 'Q' def can_move(self, board, row, col, row1, col1): color = board.get_piece(row, col).get_color() if abs(row1 - row) == abs(col1 - col) and (row1 != row or col1 != col)\ or row1 == row and col1 != col or row1 != row and col1 == col: row_step = row1 - row if row_step != 0: row_step //= abs(row_step) col_step = col1 - col if col_step != 0: col_step //= abs(col_step) if row_step != 0: cur_col = col for cur_row in range(row + row_step, row1, row_step): cur_col += col_step if board.get_piece(cur_row, cur_col) is not None: return False else: cur_row = row for cur_col in range(col + col_step, col1, col_step): cur_row += row_step if board.get_piece(cur_row, cur_col) is not None: return False if board.get_piece(row1, col1) is not None: return board.get_piece(row1, col1).get_color() == opponent(color) return True return False def can_attack(self, board, row, col, row1, col1): return self.can_move(board, row, col, row1, col1) class Bishop: def __init__(self, color): self.color = color def get_color(self): return self.color def char(self): return 'B' def can_move(self, board, row, col, row1, col1): return True # Заглушка def can_attack(self, board, row, col, row1, col1): return self.can_move(board, row, col, row1, col1) if __name__ == "__main__": main()

Регистрация: 18.03.2022
Сообщений: 3

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
B=[['*']*8 for i in range (8)] def board(B): print(' a b c d e f g h') print(' ---------------') for i in range(8): print(str(8 - i), end = ' ') [print(B[i][j], end = ' ') for j in range(8)] print(str(8 - i)) print(' ---------------') print(' a b c d e f g h') white=['R','N','B','Q','K','B','N','R'] black=['r','n','b','q','k','b','n','r'] for i in range(8): B[0][i] = black[i] B[1][i] = 'p' B[6][i] = 'P' B[7][i] = white[i] def translate(start): try: row = int(start[1]) col = start[0] if row  1 or row > 8: print(start[1] + " не в промежутке 1 - 8") return None if col  'a' or col > 'h': print(start[0] + "не в промежутке a - h") return None dict = {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5, 'g': 6, 'h': 7} return (8 - row, dict[col]) except: print(start + " неверный ввод '[буква][цифра]'") return None step=1 while True: #белый цвет - True или 1, черный - False или 0 color = step % 2 if color == True: print(step, "Ход белых:") else: print(step, "Ход черных:") board(B) start=input('Откуда сделать ход? ') to = input('Куда? ') x,y=translate(start) x1,y1=translate(to) step += 1 B[x1][y1] = B[x][y] B[x][y] = '*' print()

Я создала доску и возможность передвигать фигуры, я не знаю как прописать мат и ходы определенных фигур

«Программное приложение на Python – игра «Шахматы»»

Коркунова Наталья Ивановна

Python очень обширый язык программирования, на котором можно создать бесконечное множество разнообразных проектов. Свой первый проект я решил посвятить шахматам – одной из древнейших настольных игр с достаточно простыми правилами но в то же время заставляющей человека думать и планировать.

Актуальность выбранной темы проекта связана с актуальностью профессионального изучения информатики и программирования в современном мире.

Новизна проекта заключается в сочетании теории и практики, использовании различных ресурсов для написания кода.

Цель проекта – Создать графический интерфейс на основе PyQt для игры в шахматы для 2 игроков

  1. Реализовать классы фигур, механики передвижения.
  2. Создать поле для игры, механику атаки
  3. Реализовать таймер, обработку событий мыши.
  4. С помощью PyQt создаем графический интерфейс

Все фигуры имеют некоторые одинаковые механики, поэтому для начала создадим базовый класс, от которого будем наследовать другие.

Если представить доску в виде матрицы, то можно определять местоположение фигур с помощью координат х и у.

Пешка может двигаться на 1 клетку по вертикали (вверх если белая и вниз если черная), а также на 2 клетки, если её ещё ни разу не двигали. Исходя из этих данных создаем класс:

class Pawn(Piece):
ch = ‘P’

def can_move ( self , board , row , col , row1 , col1):
# Пешка может ходить только по вертикали
# «взятие на проходе» не реализовано
if col != col1:
return False

if not self .is_path_clear(board , row , col , row1 , col1):
return False

# Пешка может сделать из начального положения ход на 2 клетки
# вперёд, поэтому поместим индекс начального ряда в start_row.
if self .color == WHITE:
direction = 1
start_row = 1
else :
direction = — 1
start_row = 6

# ход на 1 клетку
if row + direction == row1:
return True

# ход на 2 клетки из начального положения
if row == start_row and row + 2 * direction == row1:
return True

def can_attack ( self , board , row , col , row1 , col1):
direction = 1 if ( self .color == WHITE) else — 1
return (row + direction == row1
and (col + 1 == col1 or col — 1 == col1))

Эта фигура может двигаться только по вертикали и горизонтали, т.е. должны совпадать координаты до передвижения и после лтбо по вертикали либо по горизонтали. Зная это, реализуем класс:

class Rook(Piece):
ch = ‘R’

def can_move ( self , board , row , col , row1 , col1):
# Невозможно сделать ход в клетку, которая не лежит в том же ряду
# или столбце клеток.
if row != row1 and col != col1:
return False
if not self .is_path_clear(board , row , col , row1 , col1):
return False

Конь двигается буквой «Г», т.е. на 2 по вертикали и 1 по горизонтали и наоборот. При этом направление не важно, значит нужно использовать ф-цию abs(), т.е. модуль.

class Knight(Piece):
ch = ‘N’

def can_move ( self , board , row , col , row1 , col1):
# Конь двигается буквой Г (2 вертикально, 1 горизонтально)
if abs (row — row1) == 2 and abs (col — col1) == 1 :
return True
# Конь двигается буквой Г (1 вертикально, 2 горизонтально)
if abs (row — row1) == 1 and abs (col — col1) == 2 :
return True

Слон двигается по диагонали т.е. его смещение по вертикали должно быть равно смещению по горизонтали:

class Bishop(Piece):
ch = ‘B’

def can_move ( self , board , row , col , row1 , col1):

if not self .is_path_clear(board , row , col , row1 , col1):
return False

# Слон двигается по диагонали
# Смещение по строка должно равняться смещению по столбцам
if abs (row — row1) == abs (col — col1):
return True

Королева двигается по всем сторонам (по горизонтали, вертикали, диагонали). Копируем эти механики из слона и ладьи и получаем:

class Queen(Piece):
ch = ‘Q’

def can_move ( self , board , row , col , row1 , col1):

if not self .is_path_clear(board , row , col , row1 , col1):
return False

# Ферзь двигается вертикально
if col == col1:
return True

# Ферзь двигается горизонтально
if row == row1:
return True

# Ферзь двигается по диагонали
# Смещение по строка должно равняться смещению по столбцам
if abs (row — row1) == abs (col — col1):
return True

Король двигается в любую сторону на расстояние 1:

class King(Piece):
ch = ‘K’

def can_move ( self , board , row , col , row1 , col1):

if not self .is_path_clear(board , row , col , row1 , col1):
return False

# Король двигается в любую клетку с рассотоянием равным 1
if max ( abs (row — row1) , abs (col — col1)) == 1 :
return True

А теперь необходимо реализовать некоторые особые механики игры, например «Превращение пешки» и «Рокировка».

Когда пешка доходит до противоположного конца доски она может стать Ферзем, Ладьей, Слоном или Конем. Для этого мы можем просто изменить класс фигуры, в том месте, где стоит пешка.

Для рокировки нам нужно знать: двигались ли король и ладья, есть ли между ними фигуры, приведет ли рокировка к шаху короля. От этого будет зависеть успешность рокировки или её невозможность.

Представим доску в виде матрицы на координатной оси. Тогда расположение фигур на доске будет записано в двухмерном списке. Записыаем стартовые значения матрицы:

self .field = [[ None ] * 8 for _ in range ( 8 )]
self .field[ 0 ] = [
Rook(WHITE) , Knight(WHITE) , Bishop(WHITE) , Queen(WHITE) ,
King(WHITE) , Bishop(WHITE) , Knight(WHITE) , Rook(WHITE)
]
self .field[ 1 ] = [
Pawn(WHITE) , Pawn(WHITE) , Pawn(WHITE) , Pawn(WHITE) ,
Pawn(WHITE) , Pawn(WHITE) , Pawn(WHITE) , Pawn(WHITE)
]
self .field[ 6 ] = [
Pawn(BLACK) , Pawn(BLACK) , Pawn(BLACK) , Pawn(BLACK) ,
Pawn(BLACK) , Pawn(BLACK) , Pawn(BLACK) , Pawn(BLACK)
]
self .field[ 7 ] = [
Rook(BLACK) , Knight(BLACK) , Bishop(BLACK) , Queen(BLACK) ,
King(BLACK) , Bishop(BLACK) , Knight(BLACK) , Rook(BLACK)
]

Цвет фигуры определяют константы WHITE и BLACK.

Каждая клетка имеет свое значение, так белая пешка обозначена как «wP». В дальнейшем это обозначение определит графическую модель фигурки на доске.

В этом классе создаем ф-цию проверки возможности движения:

def check_move ( self , row: int , col: int , row1: int , col1: int ):
«»»Проверка перемещения фигуру из точки (row, col) в точку (row1, col1).
Если перемещение возможно, метод выполнит его и вернет True.
Если нет — вернет False»»»
check = self .check() # Есть ли шах к перед ходом
if not correct_coords(row , col) or not correct_coords(row1 , col1):
return False
if row == row1 and col == col1:
return False # нельзя пойти в ту же клетку
piece = self .field[row][col]
target = self .field[row1][col1]
if piece is None :
return False
if piece.get_color() != self .color:
return False

if isinstance (piece , King) and self .is_under_attack(row1 , col1 , opponent( self .current_player_color())):
return False

if not (piece.can_move( self .field , row , col , row1 , col1) and target is None ) and \
not (piece.can_attack( self .field , row , col , row1 , col1) and
(target is not None and not isinstance (target , King)
and target.get_color() == opponent( self .current_player_color()))):
return False

old_field = [x.copy() for x in self .field] # Сохранить поле
self .field[row][col] = None # Снять фигуру.
self .field[row1][col1] = piece # Поставить на новое место.
if check and self .check(): # В результате хода избежать шаха не удалось
# Возвращаемся в исходное состояние
self .field = old_field
return False
# Возвращаемся в исходное состояние
self .field = old_field
return True

Ф-ция проверяет сразу все факторы: выход за пределы доски, походила ли фигурка на свое же место, приведет ли ход короля к его шаху или мату и т.д.

Реализуем ф-цию движения в которой используется ф-ция проверки:

def move_piece ( self , row , col , row1 , col1):
«»»Переместить фигуру из точки (row, col) в точку (row1, col1).
Если перемещение возможно, метод выполнит его и вернет True.
Если нет — вернет False»»»
if self .check_move(row , col , row1 , col1):
piece = self .field[row][col]
self .field[row][col] = None # Снять фигуру.
piece.moved()
self .field[row1][col1] = piece # Поставить на новое место.
if self .check_promotion(piece , row1):
self .promotion = True
self .color = opponent( self .color)
self .change = True
return True
return False

Также здесь реализуем механику атаки:

def is_under_attack ( self , row , col , color):
for row1 in range ( 8 ):
for col1 in range ( 8 ):
if self .field[row1][col1] is not None :
if self .field[row1][col1].get_color() == color and \
self .field[row1][col1].can_attack( self .field , row1 , col1 , row , col):
return True
return False

Для короля мы должны реализовать «Шах» и «Мат». Это довольно таки сложно из-за того, что у короля пропадает много возможностей, например «Рокировка». Поэтому я все ещё не полностью смог воссоздать эту механику из шахмат. Но все же в случае шаха игроку будут недоступны ходы, которые приведут к мату.

Таймер и обработка событий мыши

С помощью класса QtTimer от PyQt реализуем таймер для каждого игрока с механикой смены после окончания хода. Также с помощью механизма слотов и сигналов PyQt мы сможем обрабатывать события мыши для удобного взаимодействия с графическим интерфейсом.

Реализация графического интерфейса, пожалуй, одна из самых сложных задач проекта, так как PyQt я знаю ещё очень поверхностно. Но что есть – то есть. Создаем модели фигурок, а также модели иконок и изображение поля. Настраиваем механику обработки мыши под границы моделей клеток и иконок.

Дополняем последние детали в виде кнопок «Новая игра» и «Выйти».

Проект завершен, создан рабочий вариант шахмат.

Во время разработки проекта я узнал о многих механиках программирования, получил знания о классах объектов, познакомился с QT. Этот проект ждет ещё множество новых механик и нововведений: добавление ИИ, реализация более сложных механик, которыми пользуются проффесиональные игроки(прим.: «Взятие на проходе»). В дальнейшем я не собираюсь останавливаться на этом проекте, так как меня ждет ещё множество нереализованных идей, ждущих своего часа.

  1. Pythonworld.ru
  2. Chessmatenok.ru
  3. Учебник PyQt5

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

https://kapelnicza.vyvod-iz-zapoya-v-stacionare-samara12.ru/