sphinx2001

Превращение пешки

Apr 14th, 2021
493
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. WHITE = 1
  2. BLACK = 2
  3.  
  4.  
  5. # Удобная функция для вычисления цвета противника
  6. def opponent(color):
  7.     if color == WHITE:
  8.         return BLACK
  9.     else:
  10.         return WHITE
  11.  
  12.  
  13. def print_board(board):  # Распечатать доску в текстовом виде (см. скриншот)
  14.     print('     +----+----+----+----+----+----+----+----+')
  15.     for row in range(7, -1, -1):
  16.         print(' ', row, end='  ')
  17.         for col in range(8):
  18.             print('|', board.cell(row, col), end=' ')
  19.         print('|')
  20.         print('     +----+----+----+----+----+----+----+----+')
  21.     print(end='        ')
  22.     for col in range(8):
  23.         print(col, end='    ')
  24.     print()
  25.  
  26.  
  27. def main():
  28.     # Создаём шахматную доску
  29.     board = Board()
  30.     # Цикл ввода команд игроков
  31.     while True:
  32.         # Выводим положение фигур на доске
  33.         print_board(board)
  34.         # Подсказка по командам
  35.         print('Команды:')
  36.         print('    exit                               -- выход')
  37.         print('    move <row> <col> <row1> <row1>     -- ход из клетки (row, col)')
  38.         print('                                          в клетку (row1, col1)')
  39.         # Выводим приглашение игроку нужного цвета
  40.         if board.current_player_color() == WHITE:
  41.             print('Ход белых:')
  42.         else:
  43.             print('Ход чёрных:')
  44.         command = input()
  45.         if command == 'exit':
  46.             break
  47.         move_type, row, col, row1, col1 = command.split()
  48.         row, col, row1, col1 = int(row), int(col), int(row1), int(col1)
  49.         if board.move_piece(row, col, row1, col1):
  50.             print('Ход успешен')
  51.         else:
  52.             print('Координаты некорректы! Попробуйте другой ход!')
  53.  
  54.  
  55. def correct_coords(row, col):
  56.     '''Функция проверяет, что координаты (row, col) лежат
  57.    внутри доски'''
  58.     return 0 <= row < 8 and 0 <= col < 8
  59.  
  60.  
  61. class Board:
  62.     def __init__(self):
  63.         self.color = WHITE
  64.         self.field = []
  65.         for row in range(8):
  66.             self.field.append([None] * 8)
  67.         self.field[0] = [
  68.             Rook(WHITE), Knight(WHITE), Bishop(WHITE), Queen(WHITE),
  69.             King(WHITE), Bishop(WHITE), Knight(WHITE), Rook(WHITE)
  70.         ]
  71.         self.field[1] = [
  72.             Pawn(WHITE), Pawn(WHITE), Pawn(WHITE), Pawn(WHITE),
  73.             Pawn(WHITE), Pawn(WHITE), Pawn(WHITE), Pawn(WHITE)
  74.         ]
  75.         self.field[6] = [
  76.             Pawn(BLACK), Pawn(BLACK), Pawn(BLACK), Pawn(BLACK),
  77.             Pawn(BLACK), Pawn(BLACK), Pawn(BLACK), Pawn(BLACK)
  78.         ]
  79.         self.field[7] = [
  80.             Rook(BLACK), Knight(BLACK), Bishop(BLACK), Queen(BLACK),
  81.             King(BLACK), Bishop(BLACK), Knight(BLACK), Rook(BLACK)
  82.         ]
  83.  
  84.     def current_player_color(self):
  85.         return self.color
  86.  
  87.     def cell(self, row, col):
  88.         '''Возвращает строку из двух символов. Если в клетке (row, col)
  89.        находится фигура, символы цвета и фигуры. Если клетка пуста,
  90.        то два пробела.'''
  91.         piece = self.field[row][col]
  92.         if piece is None:
  93.             return '  '
  94.         color = piece.get_color()
  95.         c = 'w' if color == WHITE else 'b'
  96.         return c + piece.char()
  97.  
  98.     def get_piece(self, row, col):
  99.         if correct_coords(row, col):
  100.             return self.field[row][col]
  101.         else:
  102.             return None
  103.  
  104.     def move_piece(self, row, col, row1, col1):
  105.         '''Переместить фигуру из точки (row, col) в точку (row1, col1).
  106.        Если перемещение возможно, метод выполнит его и вернёт True.
  107.        Если нет --- вернёт False'''
  108.  
  109.         if not correct_coords(row, col) or not correct_coords(row1, col1):
  110.             return False
  111.         if row == row1 and col == col1:
  112.             return False  # нельзя пойти в ту же клетку
  113.         piece = self.field[row][col]
  114.         if piece is None:
  115.             return False
  116.         if piece.get_color() != self.color:
  117.             return False
  118.         if self.field[row1][col1] is None:
  119.             if not piece.can_move(self, row, col, row1, col1):
  120.                 return False
  121.         elif self.field[row1][col1].get_color() == opponent(piece.get_color()):
  122.             if not piece.can_attack(self, row, col, row1, col1):
  123.                 return False
  124.         else:
  125.             return False
  126.         self.field[row][col] = None  # Снять фигуру.
  127.         self.field[row1][col1] = piece  # Поставить на новое место.
  128.         self.color = opponent(self.color)
  129.         return True
  130.  
  131.     def move_and_promote_pawn(self, row, col, row1, col1, new_char):
  132.         if new_char not in ('Q', 'R', 'N', 'B'):
  133.             return False
  134.         piece = self.field[row][col]
  135.         if (piece is None) or (piece.char() != 'P'):
  136.             return False
  137.         if piece.get_color() == WHITE and row1 != 7:
  138.             return False
  139.         if piece.get_color() == BLACK and row1 != 0:
  140.             return False
  141.         if self.move_piece(row, col, row1, col1):
  142.             # Можно словарь с классами, но это на след. занятии
  143.             if new_char == 'Q':
  144.                 self.field[row1][col1] = Queen(piece.get_color())
  145.             elif new_char == 'R':
  146.                 self.field[row1][col1] = Rook(piece.get_color())
  147.             elif new_char == 'N':
  148.                 self.field[row1][col1] = Knight(piece.get_color())
  149.             elif new_char == 'B':
  150.                 self.field[row1][col1] = Bishop(piece.get_color())
  151.             return True
  152.         return False
  153.  
  154.  
  155. class Rook:
  156.  
  157.     def __init__(self, color):
  158.         self.color = color
  159.  
  160.     def get_color(self):
  161.         return self.color
  162.  
  163.     def char(self):
  164.         return 'R'
  165.  
  166.     def can_move(self, board, row, col, row1, col1):
  167.         # Невозможно сделать ход в клетку, которая не лежит в том же ряду
  168.         # или столбце клеток.
  169.         if row != row1 and col != col1:
  170.             return False
  171.  
  172.         step = 1 if (row1 >= row) else -1
  173.         for r in range(row + step, row1, step):
  174.             # Если на пути по горизонтали есть фигура
  175.             if not (board.get_piece(r, col) is None):
  176.                 return False
  177.  
  178.         step = 1 if (col1 >= col) else -1
  179.         for c in range(col + step, col1, step):
  180.             # Если на пути по вертикали есть фигура
  181.             if not (board.get_piece(row, c) is None):
  182.                 return False
  183.  
  184.         return True
  185.  
  186.     def can_attack(self, board, row, col, row1, col1):
  187.         return self.can_move(board, row, col, row1, col1)
  188.  
  189.  
  190. class Pawn:
  191.  
  192.     def __init__(self, color):
  193.         self.color = color
  194.  
  195.     def get_color(self):
  196.         return self.color
  197.  
  198.     def char(self):
  199.         return 'P'
  200.  
  201.     def can_move(self, board, row, col, row1, col1):
  202.         # Пешка может ходить только по вертикали
  203.         # "взятие на проходе" не реализовано
  204.         if col != col1:
  205.             return False
  206.  
  207.         # Пешка может сделать из начального положения ход на 2 клетки
  208.         # вперёд, поэтому поместим индекс начального ряда в start_row.
  209.         if self.color == WHITE:
  210.             direction = 1
  211.             start_row = 1
  212.         else:
  213.             direction = -1
  214.             start_row = 6
  215.  
  216.         # ход на 1 клетку
  217.         if row + direction == row1:
  218.             return True
  219.  
  220.         # ход на 2 клетки из начального положения
  221.         if (row == start_row
  222.                 and row + 2 * direction == row1
  223.                 and board.field[row + direction][col] is None):
  224.             return True
  225.  
  226.         return False
  227.  
  228.     def can_attack(self, board, row, col, row1, col1):
  229.         direction = 1 if (self.color == WHITE) else -1
  230.         return (row + direction == row1
  231.                 and (col + 1 == col1 or col - 1 == col1))
  232.  
  233.  
  234. class Knight:
  235.     '''Класс коня. Пока что заглушка, которая может ходить в любую клетку.'''
  236.  
  237.     def __init__(self, color):
  238.         self.color = color
  239.  
  240.     def get_color(self):
  241.         return self.color
  242.  
  243.     def char(self):
  244.         return 'N'  # kNight, буква 'K' уже занята королём
  245.  
  246.     def can_move(self, board, row, col, row1, col1):
  247.         return True  # Заглушка
  248.  
  249.     def can_attack(self, board, row, col, row1, col1):
  250.         return self.can_move(self, board, row, col, row1, col1)
  251.  
  252.  
  253. class King:
  254.     '''Класс короля. Пока что заглушка, которая может ходить в любую клетку.'''
  255.  
  256.     def __init__(self, color):
  257.         self.color = color
  258.  
  259.     def get_color(self):
  260.         return self.color
  261.  
  262.     def char(self):
  263.         return 'K'
  264.  
  265.     def can_move(self, board, row, col, row1, col1):
  266.         return True  # Заглушка
  267.  
  268.     def can_attack(self, board, row, col, row1, col1):
  269.         return self.can_move(self, board, row, col, row1, col1)
  270.  
  271.  
  272. class Queen:
  273.     '''Класс ферзя. Пока что заглушка, которая может ходить в любую клетку.'''
  274.  
  275.     def __init__(self, color):
  276.         self.color = color
  277.  
  278.     def get_color(self):
  279.         return self.color
  280.  
  281.     def char(self):
  282.         return 'Q'
  283.  
  284.     def can_move(self, board, row, col, row1, col1):
  285.         return True  # Заглушка
  286.  
  287.     def can_attack(self, board, row, col, row1, col1):
  288.         return self.can_move(self, board, row, col, row1, col1)
  289.  
  290.  
  291. class Bishop:
  292.     '''Класс слона. Пока что заглушка, которая может ходить в любую клетку.'''
  293.  
  294.     def __init__(self, color):
  295.         self.color = color
  296.  
  297.     def get_color(self):
  298.         return self.color
  299.  
  300.     def char(self):
  301.         return 'B'
  302.  
  303.     def can_move(self, board, row, col, row1, col1):
  304.         return True  # Заглушка
  305.  
  306.     def can_attack(self, board, row, col, row1, col1):
  307.         return self.can_move(self, board, row, col, row1, col1)
  308.  
  309.  
  310. # __name__ -- специальная переменная, в которую python записывает имя
  311. # файла (без .py), если этот файл импортирован из другого, и "__main__", если
  312. # этот файл запущен как программа.
  313. # Другими словами, следующие две строчки:
  314. #   запустят функцию main, если файл запущен как программа;
  315. #   не сделают ничего, если этот файл импортирован из другого.
  316. # Второй случай реализуется, например, когда тестирующий скрипт импортирует
  317. # классы из вашего скрипта. В этом случае функция main не будет работать
  318. # и портить вывод теста.
  319.  
  320. if __name__ == "__main__":
  321.     main()
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×