Advertisement
ForestFox

Checker

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