Advertisement
ForestFox

Checkers(new)

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