Advertisement
ForestFox

Chess(ООП)

Mar 21st, 2022
878
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 12.38 KB | None | 0 0
  1. import symtable
  2.  
  3.  
  4. class Color(object):
  5.     EMPTY = 0
  6.     BLACK = 1
  7.     WHITE = 2
  8.  
  9.     @classmethod
  10.     def invert(cls, color):
  11.         if color == cls.EMPTY:
  12.             return color
  13.         return cls.BLACK if color == cls.WHITE else cls.WHITE
  14.  
  15.  
  16. class Empty(object):
  17.     color = Color.EMPTY
  18.  
  19.     def get_moves(self, board, y, x):
  20.         raise Exception("Error !")
  21.  
  22.     def __repr__(self):
  23.         return ' . '
  24.  
  25.  
  26. class ChessMan(object):
  27.     fig = None
  28.  
  29.     def __init__(self, color):
  30.         self.color = color
  31.  
  32.     def __str__(self):
  33.         return self.fig[0 if self.color == Color.WHITE else 1]
  34.  
  35.     def enemy_color(self):
  36.         return Color.invert(self.color)
  37.  
  38.  
  39. class Pawn(ChessMan):
  40.     fig = (' P ', ' p ')
  41.  
  42.     def get_moves(self, board, y, x):
  43.         moves = []
  44.         if self.color == Color.BLACK and y < 7:
  45.             if board.get_color(y + 1, x) == Color.EMPTY:
  46.                 moves.append([y + 1, x])
  47.             if board.get_color(y + 2, x) == Color.EMPTY:
  48.                 moves.append([y + 2, x])
  49.             if x < 7 and board.get_color(y + 1, x + 1) == self.enemy_color():
  50.                 moves.append([y + 1, x + 1])
  51.             if x > 1 and board.get_color(y + 1, x - 1) == self.enemy_color():
  52.                 moves.append([y + 1, x - 1])
  53.  
  54.         elif self.color == Color.WHITE and y > 0:
  55.             moves = []
  56.             if board.get_color(y - 1, x) == Color.EMPTY:
  57.                 moves.append([y - 1, x])
  58.             if board.get_color(y - 2, x) == Color.EMPTY:
  59.                 moves.append([y - 2, x])
  60.             if x < 7 and board.get_color(y - 1, x + 1) == self.enemy_color():
  61.                 moves.append([y - 1, x + 1])
  62.             if x > 1 and board.get_color(y - 1, x - 1) == self.enemy_color():
  63.                 moves.append([y - 1, x - 1])
  64.  
  65.         return moves
  66.  
  67.  
  68. class King(ChessMan):
  69.     fig = (' K ', ' k ')
  70.  
  71.     def get_moves(self, board, y, x):
  72.         moves = []
  73.         for y2 in range(y - 1, y + 2):
  74.             for x2 in range(x - 1, x + 2):
  75.                 if not y2 == x2 == 0:
  76.                     if board.get_color(y2, x2) != board.get_color(y, x):
  77.                         moves.append([y2, x2])
  78.  
  79.         return moves
  80.  
  81.  
  82. class Knight(ChessMan):
  83.     fig = (' Kn', ' kn')
  84.  
  85.     def get_moves(self, board, y, x):
  86.         moves = []
  87.         for y2 in range(y - 2, y + 3):
  88.             for x2 in range(x - 2, x + 3):
  89.                 if (y2 - y) ** 2 + (x2 - x) ** 2 == 5 and 0 <= y2 <= 7 and 0 <= x2 <= 7:
  90.                     if board.get_color(y2, x2) != board.get_color(y, x):
  91.                         moves.append([y2, x2])
  92.  
  93.         return moves
  94.  
  95.  
  96. class Bishop(ChessMan):
  97.     fig = (' B ', ' b ')
  98.  
  99.     def get_moves(self, board, y, x):
  100.         moves = []
  101.         p = [[1, 1], [-1, 1], [-1, -1], [1, -1]]
  102.         for k in p:
  103.             for i in range(1, 8):
  104.                 y1, x1 = y + i * k[1], x + i * k[0]
  105.                 if not (0 <= y1 <= 7) or not (0 <= x1 <= 7):
  106.                     break
  107.                 else:
  108.                     if board.get_color(y, x) != board.get_color(y1, x1):
  109.                         moves.append([y1, x1])
  110.                     if board.get_color(y1, x1) != Color.EMPTY:
  111.                         break
  112.  
  113.         return moves
  114.  
  115.  
  116. class Rook(ChessMan):
  117.     fig = (' R ', ' r ')
  118.  
  119.     def get_moves(self, board, y, x):
  120.         moves = []
  121.         for x1 in range(x + 1, 8):
  122.             if board.get_color(y, x) != board.get_color(y, x1):
  123.                 moves.append([y, x1])
  124.             if board.get_color(y, x1) != Color.EMPTY:
  125.                 break
  126.         for x1 in range(x - 1, -1, -1):
  127.             if board.get_color(y, x) != board.get_color(y, x1):
  128.                 moves.append([y, x1])
  129.             if board.get_color(y, x1) != Color.EMPTY:
  130.                 break
  131.         for y1 in range(y + 1, 8):
  132.             if board.get_color(y, x) != board.get_color(y1, x):
  133.                 moves.append([y1, x])
  134.             if board.get_color(y1, x) != Color.EMPTY:
  135.                 break
  136.         for y1 in range(y - 1, -1, -1):
  137.             if board.get_color(y, x) != board.get_color(y1, x):
  138.                 moves.append([y1, x])
  139.             if board.get_color(y1, x) != Color.EMPTY:
  140.                 break
  141.         return moves
  142.  
  143.  
  144. class Queen(ChessMan):
  145.     fig = (' Q ', ' q ')
  146.  
  147.     def get_moves(self, board, y, x):
  148.         moves = []
  149.  
  150.         p = [[1, 1], [-1, 1], [-1, -1], [1, -1], [1, 0], [0, 1], [-1, 0], [0, -1]]
  151.         for k in p:
  152.             for i in range(1, 8):
  153.                 y1, x1 = y + i * k[1], x + i * k[0]
  154.                 if not (0 <= y1 <= 7) or not (0 <= x1 <= 7):
  155.                     break
  156.                 else:
  157.                     if board.get_color(y, x) != board.get_color(y1, x1):
  158.                         moves.append([y1, x1])
  159.                     if board.get_color(y1, x1) != Color.EMPTY:
  160.                         break
  161.         return moves
  162.  
  163.  
  164. class Board(object):
  165.     def __init__(self):
  166.         self.board = [[Empty()] * 8 for i in range(8)]
  167.  
  168.     def start(self):
  169.         self.board = [[Empty()] * 8 for i in range(8)]
  170.         for i in range(8):
  171.             self.board[1][i] = Pawn(Color.BLACK)
  172.             self.board[6][i] = Pawn(Color.WHITE)
  173.         self.board[0][0] = Rook(Color.BLACK)
  174.         self.board[7][0] = Rook(Color.WHITE)
  175.         self.board[0][1] = Knight(Color.BLACK)
  176.         self.board[7][1] = Knight(Color.WHITE)
  177.         self.board[0][2] = Bishop(Color.BLACK)
  178.         self.board[7][2] = Bishop(Color.WHITE)
  179.         self.board[0][3] = Queen(Color.BLACK)
  180.         self.board[7][3] = Queen(Color.WHITE)
  181.         self.board[0][4] = King(Color.BLACK)
  182.         self.board[7][4] = King(Color.WHITE)
  183.         self.board[0][5] = Bishop(Color.BLACK)
  184.         self.board[7][5] = Bishop(Color.WHITE)
  185.         self.board[0][6] = Knight(Color.BLACK)
  186.         self.board[7][6] = Knight(Color.WHITE)
  187.         self.board[0][7] = Rook(Color.BLACK)
  188.         self.board[7][7] = Rook(Color.WHITE)
  189.  
  190.         # self.board[4][4] = Queen(Color.WHITE)
  191.  
  192.     def get_color(self, y, x):
  193.         return self.board[y][x].color
  194.  
  195.     def get_moves(self, y, x):
  196.         return self.board[y][x].get_moves(self, y, x)
  197.  
  198.     def move(self, y1, x1, y2, x2):
  199.         self.board[y2][x2] = self.board[y1][x1]
  200.         self.board[y1][x1] = Empty()
  201.  
  202.     def is_empty(self, y, x):
  203.         self.board[y][x] = Empty()
  204.  
  205.     def __str__(self):
  206.         res = '\n' + '  '.join(['   A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']) + '\n\n'
  207.         for y in range(8, 0, -1):
  208.             res = res + f"{y} {''.join(map(str, self.board[8 - y]))} {y} \n"
  209.         res += "\n" + '  '.join(['   A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']) + '\n'
  210.         return res
  211.  
  212.  
  213. class Game(Board):
  214.     def __init__(self):
  215.         b = Board()
  216.         b.start()
  217.         n = Note()
  218.         # spec = SpecialRules()
  219.         # self.board = b.board
  220.         self.movies = 1
  221.         self.player_color = Color.WHITE
  222.         print(b)
  223.         while True:
  224.             if self.player_color == Color.WHITE and self.movies == 1:
  225.                 b.start()
  226.             print(f"Ход {'белых' if self.player_color == Color.WHITE else 'черных'}")
  227.             s = input()
  228.  
  229.             if len(s) == 0:
  230.                 break
  231.             elif s == 'сначала':
  232.                 b.start()
  233.                 self.player_color = Color.WHITE
  234.                 print(b)
  235.  
  236.             elif s == 'запись':
  237.                 print(n.pretty_write())
  238.  
  239.             elif 'вернуть на' in s:
  240.                 moves = int(s.split()[2])
  241.                 b = n.annul(b, moves)
  242.                 print(b)
  243.                 if moves % 2 != 0: self.player_color = Color.invert(self.player_color)
  244.             else:
  245.                 motion1, motion2 = s.split()
  246.                 print(f"Ход от {self.inp_coord(motion1)} в {self.inp_coord(motion2)}")
  247.                 # print(b.get_moves(*self.inp_coord(motion1)))
  248.                 checks = self.check(b, motion1, motion2)
  249.                 if checks == 'Можно':
  250.                     xy_from = self.inp_coord(motion1)
  251.                     xy_to = self.inp_coord(motion2)
  252.                     y1, x1 = xy_from[0], xy_from[1]
  253.                     y2, x2 = xy_to[0], xy_to[1]
  254.  
  255.                     n.read(y1, x1, y2, x2)
  256.                     b.move(y1, x1, y2, x2)
  257.  
  258.                     print(b)
  259.                     if self.player_color == Color.WHITE:
  260.                         self.movies += 1
  261.                         self.player_color = Color.BLACK
  262.                     else:
  263.                         self.player_color = Color.WHITE
  264.                 else:
  265.                     print(checks)
  266.  
  267.     def check(self, b, xy_from, xy_to):
  268.         if self.check_inp(b, xy_from, xy_to):
  269.             motion1, motion2 = xy_from, xy_to
  270.             xy_from = self.inp_coord(xy_from)
  271.             xy_to = self.inp_coord(xy_to)
  272.             y1, x1 = xy_from[0], xy_from[1]
  273.             y2, x2 = xy_to[0], xy_to[1]
  274.             if self.check_color(b, y1, x1, y2, x2):
  275.                 if self.check_move(b, y1, x1, y2, x2):
  276.                     return 'Можно'
  277.                 else:
  278.                     moves = ', '.join(self.return_coords(b.get_moves(y1, x1)))
  279.                     return f'У фигуры на {motion1} хода на {motion2} нет. Возможные ходы из {motion1}: {moves}'
  280.             else:
  281.                 return 'Нельзя ходить пустой клеткой и чужой фигурой'
  282.         else:
  283.             return 'Такой клетки не существует'
  284.  
  285.     def check_inp(self, b, xy_from, xy_to):
  286.         if xy_from[0] in 'abcdefgh' and xy_from[1] in '12345678':
  287.             if xy_to[0] in 'abcdefgh' and xy_to[1] in '12345678':
  288.                 return True
  289.         return False
  290.  
  291.     def check_color(self, b, y1, x1, y2, x2):
  292.         return b.board[y1][x1].color == self.player_color and b.board[y2][x2].color != self.player_color
  293.  
  294.     def check_move(self, b, y1, x1, y2, x2):
  295.         return [y2, x2] in b.get_moves(y1, x1)
  296.         # or SpecialRules().get_moves_spec(b, n, y1, x1)
  297.  
  298.     def inp_coord(self, xy):
  299.         s = "abcdefgh"
  300.         return [8 - int(xy[1]), s.index(xy[0])]
  301.  
  302.     def return_coord(self, y, x):
  303.         y = 8 - y
  304.         return f'{"abcdefgh"[x]}{y}'
  305.  
  306.     def return_coords(self, m):
  307.         k = []
  308.         for i in m:
  309.             k.append(self.return_coord(i[0], i[1]))
  310.         return k
  311.  
  312.  
  313.    
  314.    
  315. class Note(Game):
  316.     def __init__(self):
  317.         self.notes = []
  318.  
  319.     def read(self, y1, x1, y2, x2):
  320.         self.notes.append([[y1, x1], [y2, x2]])
  321.  
  322.     def coords(self, y, x):
  323.         y = 8 - y
  324.         return f'{"abcdefgh"[x]}{y}'
  325.  
  326.     def pretty_write(self):
  327.         k = ''
  328.         n = self.notes
  329.         for i in range(len(n)):
  330.             ki = ''
  331.             for j in range(2):
  332.                 xy = self.coords(n[i][j][0], n[i][j][1])
  333.                 ki += xy
  334.             if i % 2 == 0:
  335.                 k = f"{k}{str((i + 2) // 2)}. {ki} |"
  336.             else:
  337.                 k = f'{k} {ki} \n'
  338.         return k
  339.  
  340.     def annul(self, b, moves):
  341.         n = self.notes
  342.         b.start()
  343.         for i in range(len(n) - moves):
  344.             y1, x1, y2, x2 = n[i][0][0], n[i][0][1], n[i][1][0], n[i][1][1]
  345.             b.move(y1, x1, y2, x2)
  346.  
  347.         return b
  348.  
  349.  
  350. class SpecialRules(Note):
  351.     def __init__(self, notes):
  352.         self.n = notes
  353.  
  354.     def get_moves_spec(self, b, y, x):
  355.         moves = []
  356.         n = self.n
  357.         if len(n) < 2:
  358.             return moves
  359.  
  360.         if y == 4 and b.board[y][x] == Pawn(Color.BLACK):
  361.             if b.board[y][x - 1] == Pawn(Color.WHITE) and n[-1] == [[6, x - 1], [4, x - 1]]:
  362.                 moves.append([5, x - 1])
  363.             if b.board[y][x + 1] == Pawn(Color.WHITE) and n[-1] == [[6, x + 1], [4, x + 1]]:
  364.                 moves.append([5, x + 1])
  365.  
  366.         if y == 3 and b.board[y][x] == Pawn(Color.WHITE):
  367.             if b.board[y][x - 1] == Pawn(Color.WHITE) and n[-1] == [[1, x - 1], [3, x - 1]]:
  368.                 moves.append([2, x - 1])
  369.             if b.board[y][x + 1] == Pawn(Color.WHITE) and n[-1] == [[1, x + 1], [3, x + 1]]:
  370.                 moves.append([2, x + 1])
  371.  
  372.         if y == 7 and b.board[y][x] == Pawn(Color.BLACK):
  373.             moves.append(['Bishop', 'Rook', 'Knight', 'Queen'])
  374.  
  375.         if y == 0 and b.board[y][x] == Pawn(Color.WHITE):
  376.             moves.append(['Bishop', 'Rook', 'Knight', 'Queen'])
  377.  
  378.         return moves
  379.  
  380.  
  381. Game()
  382.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement