sphinx2001

Ферзь 2

Apr 14th, 2021
408
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.  
  132. class Rook:
  133.  
  134.     def __init__(self, color):
  135.         self.color = color
  136.  
  137.     def get_color(self):
  138.         return self.color
  139.  
  140.     def char(self):
  141.         return 'R'
  142.  
  143.     def can_move(self, board, row, col, row1, col1):
  144.         # Невозможно сделать ход в клетку, которая не лежит в том же ряду
  145.         # или столбце клеток.
  146.         if row != row1 and col != col1:
  147.             return False
  148.  
  149.         step = 1 if (row1 >= row) else -1
  150.         for r in range(row + step, row1, step):
  151.             # Если на пути по горизонтали есть фигура
  152.             if not (board.get_piece(r, col) is None):
  153.                 return False
  154.  
  155.         step = 1 if (col1 >= col) else -1
  156.         for c in range(col + step, col1, step):
  157.             # Если на пути по вертикали есть фигура
  158.             if not (board.get_piece(row, c) is None):
  159.                 return False
  160.  
  161.         return True
  162.  
  163.     def can_attack(self, board, row, col, row1, col1):
  164.         return self.can_move(board, row, col, row1, col1)
  165.  
  166.  
  167. class Pawn:
  168.  
  169.     def __init__(self, color):
  170.         self.color = color
  171.  
  172.     def get_color(self):
  173.         return self.color
  174.  
  175.     def char(self):
  176.         return 'P'
  177.  
  178.     def can_move(self, board, row, col, row1, col1):
  179.         # Пешка может ходить только по вертикали
  180.         # "взятие на проходе" не реализовано
  181.         if col != col1:
  182.             return False
  183.  
  184.         # Пешка может сделать из начального положения ход на 2 клетки
  185.         # вперёд, поэтому поместим индекс начального ряда в start_row.
  186.         if self.color == WHITE:
  187.             direction = 1
  188.             start_row = 1
  189.         else:
  190.             direction = -1
  191.             start_row = 6
  192.  
  193.         # ход на 1 клетку
  194.         if row + direction == row1:
  195.             return True
  196.  
  197.         # ход на 2 клетки из начального положения
  198.         if (row == start_row
  199.                 and row + 2 * direction == row1
  200.                 and board.field[row + direction][col] is None):
  201.             return True
  202.  
  203.         return False
  204.  
  205.     def can_attack(self, board, row, col, row1, col1):
  206.         direction = 1 if (self.color == WHITE) else -1
  207.         return (row + direction == row1
  208.                 and (col + 1 == col1 or col - 1 == col1))
  209.  
  210.  
  211. class Knight:
  212.     '''Класс коня. Пока что заглушка, которая может ходить в любую клетку.'''
  213.  
  214.     def __init__(self, color):
  215.         self.color = color
  216.  
  217.     def get_color(self):
  218.         return self.color
  219.  
  220.     def char(self):
  221.         return 'N'  # kNight, буква 'K' уже занята королём
  222.  
  223.     def can_move(self, board, row, col, row1, col1):
  224.         return True  # Заглушка
  225.  
  226.     def can_attack(self, board, row, col, row1, col1):
  227.         return self.can_move(self, board, row, col, row1, col1)
  228.  
  229.  
  230. class King:
  231.     '''Класс короля. Пока что заглушка, которая может ходить в любую клетку.'''
  232.  
  233.     def __init__(self, color):
  234.         self.color = color
  235.  
  236.     def get_color(self):
  237.         return self.color
  238.  
  239.     def char(self):
  240.         return 'K'
  241.  
  242.     def can_move(self, board, row, col, row1, col1):
  243.         return True  # Заглушка
  244.  
  245.     def can_attack(self, board, row, col, row1, col1):
  246.         return self.can_move(self, board, row, col, row1, col1)
  247.  
  248.  
  249. class Queen:
  250.     '''Класс ферзя. Пока что заглушка, которая может ходить в любую клетку.'''
  251.  
  252.     def __init__(self, color):
  253.         self.color = color
  254.  
  255.     def get_color(self):
  256.         return self.color
  257.  
  258.     def char(self):
  259.         return 'Q'
  260.  
  261.     def can_move(self, board, row, col, row1, col1):
  262.         # Невозможно сделать ход в клетку, которая не лежит в том же ряду
  263.         # или столбце клеток.
  264.         if not correct_coords(row1, col1):
  265.             return False
  266.         piece1 = board.get_piece(row1, col1)
  267.         if not (piece1 is None) and piece1.get_color() == self.color:
  268.             return False
  269.         if row == row1 or col == col1:
  270.             step = 1 if (row1 >= row) else -1
  271.             for r in range(row + step, row1, step):
  272.                 if not (board.get_piece(r, col) is None):
  273.                     return False
  274.             step = 1 if (col1 >= col) else -1
  275.             for c in range(col + step, col1, step):
  276.                 if not (board.get_piece(row, c) is None):
  277.                     return False
  278.             return True
  279.         if row - col == row1 - col1:
  280.             step = 1 if (row1 >= row) else -1
  281.             for r in range(row + step, row1, step):
  282.                 c = col - row + r
  283.                 if not (board.get_piece(r, c) is None):
  284.                     return False
  285.             return True
  286.         if row + col == row1 + col1:
  287.             step = 1 if (row1 >= row) else -1
  288.             for r in range(row + step, row1, step):
  289.                 c = row + col - r
  290.                 if not (board.get_piece(r, c) is None):
  291.                     return False
  292.             return True
  293.         return False
  294.  
  295.     def can_attack(self, board, row, col, row1, col1):
  296.         return self.can_move(self, board, row, col, row1, col1)
  297.  
  298.  
  299. class Bishop:
  300.     '''Класс слона. Пока что заглушка, которая может ходить в любую клетку.'''
  301.  
  302.     def __init__(self, color):
  303.         self.color = color
  304.  
  305.     def get_color(self):
  306.         return self.color
  307.  
  308.     def char(self):
  309.         return 'B'
  310.  
  311.     def can_move(self, board, row, col, row1, col1):
  312.         return True  # Заглушка
  313.  
  314.     def can_attack(self, board, row, col, row1, col1):
  315.         return self.can_move(self, board, row, col, row1, col1)
  316.  
  317.  
  318. # __name__ -- специальная переменная, в которую python записывает имя
  319. # файла (без .py), если этот файл импортирован из другого, и "__main__", если
  320. # этот файл запущен как программа.
  321. # Другими словами, следующие две строчки:
  322. #   запустят функцию main, если файл запущен как программа;
  323. #   не сделают ничего, если этот файл импортирован из другого.
  324. # Второй случай реализуется, например, когда тестирующий скрипт импортирует
  325. # классы из вашего скрипта. В этом случае функция main не будет работать
  326. # и портить вывод теста.
  327.  
  328. if __name__ == "__main__":
  329.     main()
  330.  
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.

×