Advertisement
sphinx2001

Ферзь 2

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