Advertisement
sacr1ficerq

chess

Dec 14th, 2022
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.06 KB | None | 0 0
  1. import os
  2. from copy import deepcopy
  3. from defaults import *
  4. from move import Move
  5.  
  6. from checker import Checker
  7.  
  8. '''
  9. В данном варианте шахмат реализованны пункты:
  10. 1) Реализовать чтение записи шахматной партии из выбранного пользователем файла в полной нотации.
  11. После чтения должна быть возможность двигаться вперед и назад по записи партии (с соответствующим изменением на поле).
  12. Должна быть возможность в выбранной позиции перейти из режима просмотра партии в обычный режим игры.(Сложность 2)
  13. 3) Реализовать возможность записи разыгрываемой шахматной партии в текстовый файл в полной нотации.
  14. Записанная партия должна корректно воспроизводиться в режиме чтения записи партии. (Сложность 2)
  15. 9) Реализовать возможность «отката» ходов.
  16. С помощью специальной команды можно возвращаться на ход (или заданное количество ходов) назад вплоть до начала партии. (Сложность 1)
  17. '''
  18.  
  19.  
  20. class Chess:
  21.  
  22.     def __init__(self):
  23.         self.moves_n = 0  # Сколько было сделано ходов
  24.         self.color = {0: 'белыми', 1: 'черными'}
  25.         self.field = DEFAULT_FIELD
  26.         self.moves = {}
  27.         self.filemode = False
  28.         self.filemoves = []
  29.  
  30.         print(self.play('start'))
  31.  
  32.     # распечатать поле
  33.     def print_field(self):
  34.         print('\n  A B C D E F G H  ')
  35.         print('                 ')
  36.         for line in self.field:
  37.             print(line)
  38.         print('                 ')
  39.         print('  A B C D E F G H  \n')
  40.  
  41.     @staticmethod
  42.     def reverse_field(field: list) -> list:
  43.         y = 0
  44.         result = []
  45.         for row in reversed(field):
  46.             str_inner = f'{8 - y} '
  47.             for s in row:
  48.                 str_inner = str_inner + s + ' '
  49.             str_inner = str_inner + f'{8 - y}'
  50.             y += 1
  51.             # print(str_inner)
  52.             result.append(str_inner)
  53.         return result
  54.  
  55.     # обновить поле после хода
  56.     def update_field(self, list_field, move):
  57.         piece_to_move = list_field[move.cord_from.y][move.cord_from.x]
  58.         list_field[move.cord_to.y][move.cord_to.x] = piece_to_move
  59.         list_field[move.cord_from.y][move.cord_from.x] = '.'
  60.  
  61.         reversed_field = self.reverse_field(list_field)
  62.         self.field = deepcopy(reversed_field)
  63.  
  64.     # запрос действий от пользователя
  65.     def receive_message(self, message: str) -> str:
  66.         result = input(message)
  67.         return result
  68.  
  69.     # конфертировать поле в список списков
  70.     def field_to_list(self) -> list:
  71.         copy_field = deepcopy(self.field)
  72.         list_my = []
  73.  
  74.         for t in reversed(copy_field):
  75.             i = 0
  76.             list_inner = []
  77.             for s in t:
  78.                 if i % 2 == 0 and i != 0 and i != len(t) - 1:
  79.                     list_inner.append(s)
  80.                 i += 1
  81.             list_my.append(list_inner)
  82.         # print(list_my)
  83.         return list_my
  84.  
  85.     # первый ход
  86.     def start(self) -> str:
  87.         print('\nСписок основных команд:\n\n',
  88.               'end - прекращение партии\n',
  89.               'return x - возвращает партию на x ходов назад (x задает пользователь)\n',
  90.               'file x.txt - пошагово считывает партию из файлика x.txt (x.txt задает пользователь)\n'
  91.               )
  92.         with open(f"{os.path.dirname(os.path.abspath(__file__))}/{DEFAULT_FILE}", "w") as wfile:
  93.             wfile.write('')     # обнуляем файл
  94.  
  95.         self.print_field()
  96.         if self.filemode == True:
  97.             result = self.filemoves[0]
  98.             print(f"Начинаем игру. Делаем ход {self.color[self.moves_n % 2]} по номером {self.moves_n + 1}: {result}")
  99.             return result
  100.         else:
  101.             result = self.receive_message("Начинаем игру. Сделайте ход белыми: ")
  102.             return result
  103.  
  104.     # откатить ходы назад
  105.     def return_move(self, move_n_str: str):
  106.         move_n = move_n_str[7:]
  107.  
  108.         parse_error_msg = "После return должно быть указано число ходов на которое хотим откатить. Попробуйте сделать ход вновь :"
  109.  
  110.         #parsing
  111.         try:
  112.             move_n = int(move_n)
  113.         except:
  114.             result = self.receive_message(parse_error_msg)
  115.             return self.play(result)
  116.  
  117.         if move_n > self.moves_n:
  118.             result = self.receive_message(f"В этой игре еще не было сделано {move_n} ходов. Попробуйте сделать ход вновь :")
  119.             return self.play(result)
  120.  
  121.         self.moves_n = self.moves_n - move_n
  122.         self.field = self.moves[self.moves_n]    # loading field from state dictionary
  123.         result = self.receive_message(
  124.             f"Партия возвращена к {self.moves_n + 1} ходу. Сделайте следующий ход {self.color[self.moves_n % 2]}:")
  125.         return self.play(result)
  126.  
  127.     # загрузка ходов из файла
  128.     def load_move(self, user_input: str):
  129.         self.filemode = True
  130.         self.moves_n = 0
  131.         self.field = DEFAULT_FIELD
  132.         file_name = user_input[5:]
  133.  
  134.         with open(f"{os.path.dirname(os.path.abspath(__file__))}/{file_name}", "r") as rfile:
  135.             for line in rfile:
  136.                 dot = line.find('.')    # index
  137.                 if dot != -1:
  138.                     line = line[dot + 1:]   # cut line before dot
  139.                 line = line.strip()  # remove \n
  140.                 moves = line.split()
  141.                 for move_str in moves:
  142.                     move_str = move_str.replace('×', '-').replace('x', '-').replace('?', '').replace('!', '').replace('#', '')
  143.                     if move_str[0].istitle():    # moves made with piece
  144.                         move_str = move_str[1:]
  145.                     self.filemoves.append(move_str)
  146.         # now we have our game in self.filemoves
  147.  
  148.         print(f"Файл с партией '{file_name}' был загружен\n")
  149.         return self.play('start')  # invoke start with filemode = True
  150.  
  151.     def save_move(self, move, file_name=DEFAULT_FILE):
  152.         with open(f"{os.path.dirname(os.path.abspath(__file__))}/{file_name}", "a") as wfile:
  153.             if self.moves_n == 1:
  154.                 move = f"{1 + self.moves_n // 2}. {move} "
  155.             elif self.moves_n % 2 != 0:
  156.                 move = f"\n{1 + self.moves_n // 2}. {move} "
  157.             wfile.write(move)
  158.  
  159.     # остальные ходы
  160.     def play(self, user_input: str):
  161.         # старт игры
  162.         if self.moves_n == 0 and user_input == 'start':
  163.             # print('here')
  164.             user_input = self.start()
  165.         # откат ходов
  166.         if user_input.find('return') == 0:
  167.             user_input = self.return_move(user_input)
  168.         # из файла
  169.         if user_input.find('file') == 0:
  170.             user_input = self.load_move(user_input)
  171.         # конец игры
  172.         if user_input == 'end':
  173.             # print("Партия была завершена")
  174.             return 'end'
  175.  
  176.         # проверка формата сообщения от пользователя
  177.         checker_msg = Checker.check_format(user_input)
  178.         if checker_msg != "ok":
  179.             if self.filemode == True:
  180.                 print(checker_msg)
  181.                 print(f"Была допущена ошибка в файле в блоке: {self.filemoves[self.moves_n]}. Игра будет прервана.")
  182.                 return self.play('end')
  183.             else:
  184.                 result = self.receive_message(checker_msg)
  185.                 return self.play(result)
  186.  
  187.         list_field = self.field_to_list()
  188.         move = Move(user_input)
  189.  
  190.         # проверки корректности хода
  191.         ch_m = Checker.check_move(field=list_field, move=move, moves_n=self.moves_n)
  192.         if ch_m != "ok":
  193.             if self.filemode == True:
  194.                 print(ch_m)
  195.                 print(f"Была допущена ошибка в файле в блоке: {self.filemoves[self.moves_n]}. Игра будет прервана.")
  196.                 return self.play('end')
  197.             else:
  198.                 result = self.receive_message(ch_m)
  199.                 return self.play(result)
  200.  
  201.         # обновляем данные на поле
  202.         self.moves[self.moves_n] = self.field
  203.         self.update_field(list_field, move)
  204.         self.print_field()
  205.         self.moves_n += 1
  206.  
  207.         figure_from = list_field[move.cord_from.y][move.cord_from.x]
  208.         if figure_from not in ['p', 'P', '.']:
  209.             user_input = figure_from.upper() + user_input
  210.         self.save_move(user_input)  # write user input in file
  211.  
  212.         # начинаем следующий ход
  213.         if self.filemode == True:
  214.             if len(self.filemoves) == self.moves_n:
  215.                 print(f"Данные из файла кончились")
  216.                 result = 'n'
  217.             else:
  218.                 result = self.receive_message(f"Переходим к следующему ходу(y/n) или начнем игру?:")
  219.             if result == 'y':
  220.                 print(
  221.                     f"Ход из файла. Делаем ход {self.color[self.moves_n % 2]} по номером {self.moves_n + 1}: {self.filemoves[self.moves_n]}")
  222.                 return self.play(self.filemoves[self.moves_n])
  223.             elif result == 'n':
  224.                 result = self.receive_message(
  225.                     f"Сделайте следующий ход {self.color[self.moves_n % 2]} по номером {self.moves_n + 1}:")
  226.                 self.filemode = False
  227.                 return self.play(result)
  228.             else:
  229.                 print(
  230.                     f"Вы ввели некорректное значение. Был Автоматически сделан следующий ход из файла: {self.filemoves[self.moves_n]}")
  231.                 return self.play(self.filemoves[self.moves_n])
  232.         else:
  233.             result = self.receive_message(
  234.                 f"Сделайте следующий ход {self.color[self.moves_n % 2]} по номером {self.moves_n + 1}:")
  235.             return self.play(result)
  236.  
  237.  
  238. ch = Chess()     # starting function
  239. # print(ch.play('file chess.txt'))
  240.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement