Advertisement
sphinx2001

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

Apr 14th, 2021
796
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.55 KB | None | 0 0
  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()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement