Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import os
- from copy import deepcopy
- from defaults import *
- from move import Move
- from checker import Checker
- '''
- В данном варианте шахмат реализованны пункты:
- 1) Реализовать чтение записи шахматной партии из выбранного пользователем файла в полной нотации.
- После чтения должна быть возможность двигаться вперед и назад по записи партии (с соответствующим изменением на поле).
- Должна быть возможность в выбранной позиции перейти из режима просмотра партии в обычный режим игры.(Сложность 2)
- 3) Реализовать возможность записи разыгрываемой шахматной партии в текстовый файл в полной нотации.
- Записанная партия должна корректно воспроизводиться в режиме чтения записи партии. (Сложность 2)
- 9) Реализовать возможность «отката» ходов.
- С помощью специальной команды можно возвращаться на ход (или заданное количество ходов) назад вплоть до начала партии. (Сложность 1)
- '''
- class Chess:
- def __init__(self):
- self.moves_n = 0 # Сколько было сделано ходов
- self.color = {0: 'белыми', 1: 'черными'}
- self.field = DEFAULT_FIELD
- self.moves = {}
- self.filemode = False
- self.filemoves = []
- print(self.play('start'))
- # распечатать поле
- def print_field(self):
- print('\n A B C D E F G H ')
- print(' ')
- for line in self.field:
- print(line)
- print(' ')
- print(' A B C D E F G H \n')
- @staticmethod
- def reverse_field(field: list) -> list:
- y = 0
- result = []
- for row in reversed(field):
- str_inner = f'{8 - y} '
- for s in row:
- str_inner = str_inner + s + ' '
- str_inner = str_inner + f'{8 - y}'
- y += 1
- # print(str_inner)
- result.append(str_inner)
- return result
- # обновить поле после хода
- def update_field(self, list_field, move):
- piece_to_move = list_field[move.cord_from.y][move.cord_from.x]
- list_field[move.cord_to.y][move.cord_to.x] = piece_to_move
- list_field[move.cord_from.y][move.cord_from.x] = '.'
- reversed_field = self.reverse_field(list_field)
- self.field = deepcopy(reversed_field)
- # запрос действий от пользователя
- def receive_message(self, message: str) -> str:
- result = input(message)
- return result
- # конфертировать поле в список списков
- def field_to_list(self) -> list:
- copy_field = deepcopy(self.field)
- list_my = []
- for t in reversed(copy_field):
- i = 0
- list_inner = []
- for s in t:
- if i % 2 == 0 and i != 0 and i != len(t) - 1:
- list_inner.append(s)
- i += 1
- list_my.append(list_inner)
- # print(list_my)
- return list_my
- # первый ход
- def start(self) -> str:
- print('\nСписок основных команд:\n\n',
- 'end - прекращение партии\n',
- 'return x - возвращает партию на x ходов назад (x задает пользователь)\n',
- 'file x.txt - пошагово считывает партию из файлика x.txt (x.txt задает пользователь)\n'
- )
- with open(f"{os.path.dirname(os.path.abspath(__file__))}/{DEFAULT_FILE}", "w") as wfile:
- wfile.write('') # обнуляем файл
- self.print_field()
- if self.filemode == True:
- result = self.filemoves[0]
- print(f"Начинаем игру. Делаем ход {self.color[self.moves_n % 2]} по номером {self.moves_n + 1}: {result}")
- return result
- else:
- result = self.receive_message("Начинаем игру. Сделайте ход белыми: ")
- return result
- # откатить ходы назад
- def return_move(self, move_n_str: str):
- move_n = move_n_str[7:]
- parse_error_msg = "После return должно быть указано число ходов на которое хотим откатить. Попробуйте сделать ход вновь :"
- #parsing
- try:
- move_n = int(move_n)
- except:
- result = self.receive_message(parse_error_msg)
- return self.play(result)
- if move_n > self.moves_n:
- result = self.receive_message(f"В этой игре еще не было сделано {move_n} ходов. Попробуйте сделать ход вновь :")
- return self.play(result)
- self.moves_n = self.moves_n - move_n
- self.field = self.moves[self.moves_n] # loading field from state dictionary
- result = self.receive_message(
- f"Партия возвращена к {self.moves_n + 1} ходу. Сделайте следующий ход {self.color[self.moves_n % 2]}:")
- return self.play(result)
- # загрузка ходов из файла
- def load_move(self, user_input: str):
- self.filemode = True
- self.moves_n = 0
- self.field = DEFAULT_FIELD
- file_name = user_input[5:]
- with open(f"{os.path.dirname(os.path.abspath(__file__))}/{file_name}", "r") as rfile:
- for line in rfile:
- dot = line.find('.') # index
- if dot != -1:
- line = line[dot + 1:] # cut line before dot
- line = line.strip() # remove \n
- moves = line.split()
- for move_str in moves:
- move_str = move_str.replace('×', '-').replace('x', '-').replace('?', '').replace('!', '').replace('#', '')
- if move_str[0].istitle(): # moves made with piece
- move_str = move_str[1:]
- self.filemoves.append(move_str)
- # now we have our game in self.filemoves
- print(f"Файл с партией '{file_name}' был загружен\n")
- return self.play('start') # invoke start with filemode = True
- def save_move(self, move, file_name=DEFAULT_FILE):
- with open(f"{os.path.dirname(os.path.abspath(__file__))}/{file_name}", "a") as wfile:
- if self.moves_n == 1:
- move = f"{1 + self.moves_n // 2}. {move} "
- elif self.moves_n % 2 != 0:
- move = f"\n{1 + self.moves_n // 2}. {move} "
- wfile.write(move)
- # остальные ходы
- def play(self, user_input: str):
- # старт игры
- if self.moves_n == 0 and user_input == 'start':
- # print('here')
- user_input = self.start()
- # откат ходов
- if user_input.find('return') == 0:
- user_input = self.return_move(user_input)
- # из файла
- if user_input.find('file') == 0:
- user_input = self.load_move(user_input)
- # конец игры
- if user_input == 'end':
- # print("Партия была завершена")
- return 'end'
- # проверка формата сообщения от пользователя
- checker_msg = Checker.check_format(user_input)
- if checker_msg != "ok":
- if self.filemode == True:
- print(checker_msg)
- print(f"Была допущена ошибка в файле в блоке: {self.filemoves[self.moves_n]}. Игра будет прервана.")
- return self.play('end')
- else:
- result = self.receive_message(checker_msg)
- return self.play(result)
- list_field = self.field_to_list()
- move = Move(user_input)
- # проверки корректности хода
- ch_m = Checker.check_move(field=list_field, move=move, moves_n=self.moves_n)
- if ch_m != "ok":
- if self.filemode == True:
- print(ch_m)
- print(f"Была допущена ошибка в файле в блоке: {self.filemoves[self.moves_n]}. Игра будет прервана.")
- return self.play('end')
- else:
- result = self.receive_message(ch_m)
- return self.play(result)
- # обновляем данные на поле
- self.moves[self.moves_n] = self.field
- self.update_field(list_field, move)
- self.print_field()
- self.moves_n += 1
- figure_from = list_field[move.cord_from.y][move.cord_from.x]
- if figure_from not in ['p', 'P', '.']:
- user_input = figure_from.upper() + user_input
- self.save_move(user_input) # write user input in file
- # начинаем следующий ход
- if self.filemode == True:
- if len(self.filemoves) == self.moves_n:
- print(f"Данные из файла кончились")
- result = 'n'
- else:
- result = self.receive_message(f"Переходим к следующему ходу(y/n) или начнем игру?:")
- if result == 'y':
- print(
- f"Ход из файла. Делаем ход {self.color[self.moves_n % 2]} по номером {self.moves_n + 1}: {self.filemoves[self.moves_n]}")
- return self.play(self.filemoves[self.moves_n])
- elif result == 'n':
- result = self.receive_message(
- f"Сделайте следующий ход {self.color[self.moves_n % 2]} по номером {self.moves_n + 1}:")
- self.filemode = False
- return self.play(result)
- else:
- print(
- f"Вы ввели некорректное значение. Был Автоматически сделан следующий ход из файла: {self.filemoves[self.moves_n]}")
- return self.play(self.filemoves[self.moves_n])
- else:
- result = self.receive_message(
- f"Сделайте следующий ход {self.color[self.moves_n % 2]} по номером {self.moves_n + 1}:")
- return self.play(result)
- ch = Chess() # starting function
- # print(ch.play('file chess.txt'))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement