Advertisement
ForestFox

chess(28.03.22)

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