Advertisement
ForestFox

Chess Class

May 13th, 2022
470
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  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 y == 1 and 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 y == 6 and 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 = (' N ', ' n ')
  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 Templar(ChessMan):
  97.     fig = (' T ', ' t ')
  98.  
  99.     def get_moves(self, board, y, x):
  100.         moves = []
  101.         for y2 in range(y - 3, y + 4):
  102.             for x2 in range(x - 3, x + 4):
  103.                 if (y2 - y) ** 2 + (x2 - x) ** 2 == 5 and 0 <= y2 <= 7 and 0 <= x2 <= 7:
  104.                     if board.get_color(y2, x2) != board.get_color(y, x):
  105.                         moves.append([y2, x2])
  106.                 if (y2 - y) ** 2 + (x2 - x) ** 2 == 13 and 0 <= y2 <= 7 and 0 <= x2 <= 7:
  107.                     if board.get_color(y2, x2) == Color.EMPTY:
  108.                         moves.append([y2, x2])
  109.  
  110.         return moves
  111.  
  112.  
  113. class Champion(ChessMan):
  114.     fig = (' C ', ' c ')
  115.  
  116.     def get_moves(self, board, y, x):
  117.         moves = []
  118.         for y2 in range(y - 2, y + 3):
  119.             for x2 in range(x - 2, x + 3):
  120.                 if 0 <= y2 <= 7 and 0 <= x2 <= 7:
  121.                     s = (x2 - x) ** 2 + (y2 - y) ** 2
  122.                     if s == 1 or s == 4 or s == 8:
  123.                         if board.get_color(y2, x2) != board.get_color(y, x):
  124.                             moves.append([y2, x2])
  125.  
  126.         return moves
  127.  
  128.  
  129. class Wizard(ChessMan):
  130.     fig = (' W ', ' w ')
  131.  
  132.     def get_moves(self, board, y, x):
  133.         moves = []
  134.         for y2 in range(y - 3, y + 4):
  135.             for x2 in range(x - 3, x + 4):
  136.                 if 0 <= y2 <= 7 and 0 <= x2 <= 7:
  137.                     if board.get_color(y2, x2) != board.get_color(y, x):
  138.                         d_y, d_x = abs(y2 - y), abs(x2 - x)
  139.                         if (d_y, d_x) == (1, 3) or (d_y, d_x) == (3, 1) or (d_x, d_y) == (1, 3) or (d_x, d_y) == (
  140.                                 3, 1) or (x2 - x) ** 2 + (y2 - y) ** 2 == 1:
  141.                             moves.append([y2, x2])
  142.  
  143.         return moves
  144.  
  145.  
  146. class Bishop(ChessMan):
  147.     fig = (' B ', ' b ')
  148.  
  149.     def get_moves(self, board, y, x):
  150.         moves = []
  151.         p = [[1, 1], [-1, 1], [-1, -1], [1, -1]]
  152.         for k in p:
  153.             for i in range(1, 8):
  154.                 y1, x1 = y + i * k[1], x + i * k[0]
  155.                 if not (0 <= y1 <= 7) or not (0 <= x1 <= 7):
  156.                     break
  157.                 else:
  158.                     if board.get_color(y, x) != board.get_color(y1, x1):
  159.                         moves.append([y1, x1])
  160.                     if board.get_color(y1, x1) != Color.EMPTY:
  161.                         break
  162.  
  163.         return moves
  164.  
  165.  
  166. class Rook(ChessMan):
  167.     fig = (' R ', ' r ')
  168.  
  169.     def get_moves(self, board, y, x):
  170.         moves = []
  171.         for x1 in range(x + 1, 8):
  172.             if board.get_color(y, x) != board.get_color(y, x1):
  173.                 moves.append([y, x1])
  174.             if board.get_color(y, x1) != Color.EMPTY:
  175.                 break
  176.         for x1 in range(x - 1, -1, -1):
  177.             if board.get_color(y, x) != board.get_color(y, x1):
  178.                 moves.append([y, x1])
  179.             if board.get_color(y, x1) != Color.EMPTY:
  180.                 break
  181.         for y1 in range(y + 1, 8):
  182.             if board.get_color(y, x) != board.get_color(y1, x):
  183.                 moves.append([y1, x])
  184.             if board.get_color(y1, x) != Color.EMPTY:
  185.                 break
  186.         for y1 in range(y - 1, -1, -1):
  187.             if board.get_color(y, x) != board.get_color(y1, x):
  188.                 moves.append([y1, x])
  189.             if board.get_color(y1, x) != Color.EMPTY:
  190.                 break
  191.         return moves
  192.  
  193.  
  194. class Queen(ChessMan):
  195.     fig = (' Q ', ' q ')
  196.  
  197.     def get_moves(self, board, y, x):
  198.         moves = []
  199.  
  200.         p = [[1, 1], [-1, 1], [-1, -1], [1, -1], [1, 0], [0, 1], [-1, 0], [0, -1]]
  201.         for k in p:
  202.             for i in range(1, 8):
  203.                 y1, x1 = y + i * k[1], x + i * k[0]
  204.                 if not (0 <= y1 <= 7) or not (0 <= x1 <= 7):
  205.                     break
  206.                 else:
  207.                     if board.get_color(y, x) != board.get_color(y1, x1):
  208.                         moves.append([y1, x1])
  209.                     if board.get_color(y1, x1) != Color.EMPTY:
  210.                         break
  211.         return moves
  212.  
  213.  
  214. class Board(object):
  215.     def __init__(self):
  216.         self.board = [[Empty()] * 8 for i in range(8)]
  217.  
  218.     def start(self):
  219.         self.board = [[Empty()] * 8 for i in range(8)]
  220.         for i in range(8):
  221.             self.board[1][i] = Pawn(Color.BLACK)
  222.             self.board[6][i] = Pawn(Color.WHITE)
  223.         self.board[0][0] = Rook(Color.BLACK)
  224.         self.board[7][0] = Rook(Color.WHITE)
  225.         self.board[0][1] = Knight(Color.BLACK)
  226.         self.board[7][1] = Knight(Color.WHITE)
  227.         self.board[0][2] = Bishop(Color.BLACK)
  228.         self.board[7][2] = Bishop(Color.WHITE)
  229.         self.board[0][3] = Queen(Color.BLACK)
  230.         self.board[7][3] = Queen(Color.WHITE)
  231.         self.board[0][4] = King(Color.BLACK)
  232.         self.board[7][4] = King(Color.WHITE)
  233.         self.board[0][5] = Bishop(Color.BLACK)
  234.         self.board[7][5] = Bishop(Color.WHITE)
  235.         self.board[0][6] = Knight(Color.BLACK)
  236.         self.board[7][6] = Knight(Color.WHITE)
  237.         self.board[0][7] = Rook(Color.BLACK)
  238.         self.board[7][7] = Rook(Color.WHITE)
  239.         # self.board[4][4] = Champion(Color.WHITE)
  240.         # self.board[5][5] = Wizard(Color.WHITE)
  241.         # self.board[4][6] = Templar(Color.WHITE)
  242.         # self.board[4][4] = Queen(Color.WHITE)
  243.  
  244.     def get_color(self, y, x):
  245.         return self.board[y][x].color
  246.  
  247.     def get_moves(self, y, x):
  248.         return self.board[y][x].get_moves(self, y, x)
  249.  
  250.     def move(self, y1, x1, y2, x2):
  251.         self.board[y2][x2] = self.board[y1][x1]
  252.         self.board[y1][x1] = Empty()
  253.  
  254.     def is_empty(self, y, x):
  255.         self.board[y][x] = Empty()
  256.  
  257.     def b_with_possibilities(self, y1, x1):
  258.         c = self.board
  259.         if self.board[y1][x1].color == Color.EMPTY:
  260.             return c
  261.         pos = self.get_moves(y1, x1)
  262.  
  263.         for i in pos:
  264.             y, x = i[0], i[1]
  265.             c[y][x] = f"*{str(c[y][x]).replace(' ', '')}*"
  266.  
  267.         return c
  268.  
  269.     def __str__(self):
  270.         res = '\n' + '  '.join(['   A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']) + '\n\n'
  271.         for y in range(8, 0, -1):
  272.             res = res + f"{y} {''.join(map(str, self.board[8 - y]))} {y} \n"
  273.         res += "\n" + '  '.join(['   A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']) + '\n'
  274.         return res
  275.  
  276.  
  277. class Game(Board):
  278.     def __init__(self):
  279.         b = Board()
  280.         b.start()
  281.         n = Note()
  282.         # spec = SpecialRules()
  283.         # self.board = b.board
  284.         self.movies = 1
  285.         self.player_color = Color.WHITE
  286.         print(b)
  287.         while True:
  288.             if self.player_color == Color.WHITE and self.movies == 1:
  289.                 b.start()
  290.             print(f"Ход {'белых' if self.player_color == Color.WHITE else 'черных'}")
  291.             s = input()
  292.  
  293.             if len(s) == 0:
  294.                 break
  295.             elif s == 'сначала':
  296.                 b.start()
  297.                 self.player_color = Color.WHITE
  298.                 print(b)
  299.  
  300.             elif s == 'запись':
  301.                 print(n.pretty_write())
  302.  
  303.             elif 'вернуть на' in s:
  304.                 moves = int(s.split()[2])
  305.                 b = n.annul(b, moves)
  306.                 print(b)
  307.                 if moves % 2 != 0: self.player_color = Color.invert(self.player_color)
  308.  
  309.             elif 'возможные ходы' in s:
  310.                 motion1 = self.inp_coord(s.split()[2])
  311.                 y, x = motion1[0], motion1[1]
  312.                 c = b
  313.                 # c = self.b_with_possibilities(b, y, x)
  314.                 c.b_with_possibilities(y, x)
  315.                 print(c)
  316.                 b = n.annul(b, 0)
  317.             else:
  318.                 motion1, motion2 = s.split()
  319.                 print(f"Ход от {self.inp_coord(motion1)} в {self.inp_coord(motion2)}")
  320.                 # print(b.get_moves(*self.inp_coord(motion1)))
  321.                 checks = self.check(b, motion1, motion2)
  322.                 if checks == 'Можно':
  323.                     xy_from = self.inp_coord(motion1)
  324.                     xy_to = self.inp_coord(motion2)
  325.                     y1, x1 = xy_from[0], xy_from[1]
  326.                     y2, x2 = xy_to[0], xy_to[1]
  327.  
  328.                     n.read(y1, x1, y2, x2)
  329.                     b.move(y1, x1, y2, x2)
  330.  
  331.                     print(b)
  332.                     if self.player_color == Color.WHITE:
  333.                         self.movies += 1
  334.                         self.player_color = Color.BLACK
  335.                     else:
  336.                         self.player_color = Color.WHITE
  337.                 else:
  338.                     print(checks)
  339.  
  340.     def check(self, b, xy_from, xy_to):
  341.         if self.check_inp(b, xy_from, xy_to):
  342.             motion1, motion2 = xy_from, xy_to
  343.             xy_from = self.inp_coord(xy_from)
  344.             xy_to = self.inp_coord(xy_to)
  345.             y1, x1 = xy_from[0], xy_from[1]
  346.             y2, x2 = xy_to[0], xy_to[1]
  347.             if self.check_color(b, y1, x1, y2, x2):
  348.                 if self.check_move(b, y1, x1, y2, x2):
  349.                     return 'Можно'
  350.                 else:
  351.                     moves = ', '.join(self.return_coords(b.get_moves(y1, x1)))
  352.                     return f'У фигуры на {motion1} хода на {motion2} нет. Возможные ходы из {motion1}: {moves}'
  353.             else:
  354.                 return 'Нельзя ходить пустой клеткой и чужой фигурой'
  355.         else:
  356.             return 'Такой клетки не существует'
  357.  
  358.     def check_inp(self, b, xy_from, xy_to):
  359.         if xy_from[0] in 'abcdefgh' and xy_from[1] in '12345678':
  360.             if xy_to[0] in 'abcdefgh' and xy_to[1] in '12345678':
  361.                 return True
  362.         return False
  363.  
  364.     def check_color(self, b, y1, x1, y2, x2):
  365.         return b.board[y1][x1].color == self.player_color and b.board[y2][x2].color != self.player_color
  366.  
  367.     def check_move(self, b, y1, x1, y2, x2):
  368.         return [y2, x2] in b.get_moves(y1, x1)
  369.         # or SpecialRules().get_moves_spec(b, n, y1, x1)
  370.  
  371.     def inp_coord(self, xy):
  372.         s = "abcdefgh"
  373.         return [8 - int(xy[1]), s.index(xy[0])]
  374.  
  375.     def return_coord(self, y, x):
  376.         y = 8 - y
  377.         return f'{"abcdefgh"[x]}{y}'
  378.  
  379.     def return_coords(self, m):
  380.         k = []
  381.         for i in m:
  382.             k.append(self.return_coord(i[0], i[1]))
  383.         return k
  384.  
  385.     # def b_with_possibilities(self, b, y1, x1):
  386.     #     c = b.board
  387.     #     pos = b.get_moves(y1, x1)
  388.     #     for i in pos:
  389.     #         y, x = i[0], i[1]
  390.     #         c[y][x] = f'*{c[y][x]}*'
  391.     #     return c
  392.  
  393.  
  394. class Note(Game):
  395.     def __init__(self):
  396.         self.notes = []
  397.  
  398.     def read(self, y1, x1, y2, x2):
  399.         self.notes.append([[y1, x1], [y2, x2]])
  400.  
  401.     def coords(self, y, x):
  402.         y = 8 - y
  403.         return f'{"abcdefgh"[x]}{y}'
  404.  
  405.     def pretty_write(self):
  406.         k = ''
  407.         n = self.notes
  408.         for i in range(len(n)):
  409.             ki = ''
  410.             for j in range(2):
  411.                 xy = self.coords(n[i][j][0], n[i][j][1])
  412.                 ki += xy
  413.             if i % 2 == 0:
  414.                 k = f"{k}{str((i + 2) // 2)}. {ki} |"
  415.             else:
  416.                 k = f'{k} {ki} \n'
  417.         return k
  418.  
  419.     def annul(self, b, moves):
  420.         n = self.notes
  421.         b.start()
  422.         for i in range(len(n) - moves):
  423.             y1, x1, y2, x2 = n[i][0][0], n[i][0][1], n[i][1][0], n[i][1][1]
  424.             b.move(y1, x1, y2, x2)
  425.  
  426.         return b
  427.  
  428.  
  429. Game()
Advertisement
Advertisement
Advertisement
RAW Paste Data Copied
Advertisement