Example #1
0
    def war_detector(self):
        """
        Проверка на осуществление перехода с боем
        - Проверка на то, чтоб была фигура, которую мы атакуем
        - Поиск и установление координат фигуры, выставление в self.command_dict
        - Проверка на то, чтоб цвет фигуры был не наш
        """
        d = self.command_dict
        board_obj = self.board_obj

        x_start = d["from"]["x"]
        y_start = UtilClass.char2xint(d["from"]["y"])

        x_finish = d["to"]["x"]
        y_finish = UtilClass.char2xint(d["to"]["y"])

        # Соседние точки относительно точки назначения
        middle_points = np.array([
            e for e in [[x_finish - 1, y_finish -
                         1], [x_finish - 1, y_finish + 1]]
            if board_obj.detect_element(*e)
        ])

        # Возможные точки, где стоит фигура
        validated_points = np.array([
            e for e in [[x_start + 1, y_start + 1], [x_start + 1, y_start - 1]]
            if board_obj.detect_element(*e)
        ])

        attack_points = []
        for i in np.arange(middle_points.shape[0]):
            for j in np.arange(validated_points.shape[0]):
                if (middle_points[i][0] == validated_points[j][0]
                        and middle_points[i][1] == validated_points[j][1]):
                    attack_points = middle_points[i]
                    break

        # Если нет точек пересечения
        if len(attack_points) == 0:
            self.results_list.append(False)
            return

        self.command_dict["enemy"] = {}
        self.command_dict["enemy"]["x"], self.command_dict["enemy"][
            "y"] = attack_points
        attack_x, attack_y = attack_points

        # Выбрали точку, где располагается предполагаемый враг
        attack_field = board_obj.board[attack_x][attack_y]
        # Если есть чужая фигура на этой точке
        if (not attack_field.isfree()
                and attack_field.figure_obj.color != d["user_color"]):
            self.results_list.append(True)
        else:
            if self.info:
                f = UtilClass.getfail_coords
                print(
                    "\033[91m[Ошибка]\033[0m Противников между координатами {} и {} нет. Используйте тихий ход для перемещения без боя"
                    .format(f(d["from"]), f(d["to"])))
            self.results_list.append(False)
Example #2
0
    def figure_detector(self):
        """Определение, стоит ли на исходной клетке фигура и если стоит, то своя ли"""

        board_obj = self.board_obj
        d = self.command_dict

        # Проверка на то, существует ли ячейка, с которой мы хотим переставить фигуру
        target_x = d["from"]["x"]
        target_y = UtilClass.char2xint(d["from"]["y"])
        if not board_obj.detect_element(target_x, target_y):
            if self.info:
                print(
                    "\033[91m[Ошибка]\033[0m Выбранной шашки по координатам {} не существует."
                    .format(UtilClass.getfail_coords(d["from"])))
            self.results_list.append(False)
            return

        # Если есть фигура и ее цвет тот, за который мы играем
        selected_field = board_obj.board[target_x][target_y]
        if (not selected_field.isfree()
                and selected_field.figure_obj.color == d["user_color"]):
            self.results_list.append(True)
        elif selected_field.isfree():
            if self.info:
                print(
                    "\033[91m[Ошибка]\033[0m Выбранная клетка {} пуста".format(
                        UtilClass.getfail_coords(d["from"])))
            self.results_list.append(False)
        else:
            if self.info:
                print(
                    "\033[91m[Ошибка]\033[0m Фигура на клетке {} не вашего цвета."
                    .format(UtilClass.getfail_coords(d["from"])))
            self.results_list.append(False)
Example #3
0
    def command_parser(self, cmd):
        """
        Осуществление парсинга и фильтрации команды, которую ввел пользователь
        Если все хорошо - вызывается проверка на уровне
        """

        movement_type_dict = {":": "war", "-": "peace"}
        # Разделитель строки на 2 части
        spliter = ""
        detect_flag = False
        for key in movement_type_dict.keys():
            if key in cmd:
                detect_flag = True
                spliter = key
                break

        if not detect_flag:
            return {}

        command_dict = {
            "from": {},
            "to": {},
            "mode": movement_type_dict[spliter],
            "user_color": self.user_color,
        }
        # Разделяем введенную команду на 2 части
        part1, part2 = cmd.split(spliter)
        if UtilClass.checkxy_value(part1) and UtilClass.checkxy_value(part2):
            command_dict["from"]["x"] = int(part1[1]) - 1
            command_dict["from"]["y"] = part1[0]
            command_dict["to"]["x"] = int(part2[1]) - 1
            command_dict["to"]["y"] = part2[0]
            return command_dict

        return {}
Example #4
0
    def fieldtype_detector(self):
        """
        Проверка на все, что связано с ячейкой.
        - Проверка на существование ячейки
        - Занятость ячейки
        - Цвет ячейки
        """

        # Понятное дело, что мы ячейку на существование проверили на предыдущем шаге в diagonal_detector, но МАЛО ЛИ
        d = self.command_dict
        board_obj = self.board_obj
        x = d["to"]["x"]
        y = UtilClass.char2xint(d["to"]["y"])
        if not board_obj.detect_element(x, y):
            self.results_list.append(False)
            return

        selected_field = board_obj.board[x][y]
        if selected_field.color == "black" and selected_field.isfree():
            self.results_list.append(True)
        elif not selected_field.isfree():
            if self.info:
                print(
                    "\033[91m[Ошибка]\033[0m Вы пытаетесь поставить шашку на занятую клетку {}"
                    .format(UtilClass.getfail_coords(d["to"])))
            self.results_list.append(False)
        else:
            if self.info:
                print(
                    "\033[91m[Ошибка]\033[0m Вы пытаетесь поставить шашку на клетку белого цвета {}"
                    .format(UtilClass.getfail_coords(d["to"])))
            self.results_list.append(False)
Example #5
0
    def user_mode(self):
        """
        Осуществление хода пользователем
        """
        d = self.result_dict
        board = self.board_obj.board

        mode = d["mode"]
        f1 = [d["from"]["x"], UtilClass.char2xint(d["from"]["y"])]
        f2 = [d["to"]["x"], UtilClass.char2xint(d["to"]["y"])]
        x1, y1 = f1
        x2, y2 = f2
        field_from = board[x1][y1]
        field_to = board[x2][y2]

        # Получаем объект фигуры с ячейки и выставлем для него обновленные координаты
        figure_obj = field_from.figure_obj
        figure_obj.coord_x, figure_obj.coord_y = f2
        # Присваиваем фигуру обновленной ячейке
        field_to.field_reserve(figure_obj)
        # Освобождаем из старой
        field_from.field_free()

        # Если мы кого-то бъём, то удаляем фигуру с той ячейки
        if mode == "war":
            attack_x, attack_y = d["enemy"]["x"], d["enemy"]["y"]
            board[attack_x][attack_y].field_free()

        self.board_obj.board = board
Example #6
0
    def diagonal_detector(self):
        """Проверка на осуществление перехода по диагонали"""
        # Возможные пути, куда может пойти шашка (их всего 4)
        board_obj = self.board_obj
        d = self.command_dict
        target_x = d["from"]["x"]
        target_y = UtilClass.char2xint(d["from"]["y"])
        # Возможные клетки, куда можно пойти и которые есть на доске

        # Т.к. использование "коротких" перемещений при атаке просто невозможно
        if d["mode"] == "war":
            allowedfields_list = [
                [target_x - 2, target_y + 2],
                [target_x - 2, target_y - 2],
            ]
        # При тихом ходе возмодны только короткие перемещения
        else:
            allowedfields_list = [
                [target_x - 1, target_y + 1],
                [target_x - 1, target_y - 1],
            ]

        validated_points = [
            e for e in allowedfields_list if board_obj.detect_element(*e)
        ]

        if [d["to"]["x"],
                UtilClass.char2xint(d["to"]["y"])] in validated_points:
            self.results_list.append(True)
        else:
            self.results_list.append(False)
Example #7
0
    def figuremanual_generator(self):
        """Ручная расстановка 6 фигур по полю"""
        format_dict = {"white": "белого", "black": "чёрного"}
        for color in ("white", "black"):
            print("\033[93m*Выставляем шашки {} цвета*\033[0m".format(
                format_dict[color]))
            for i in range(6):

                boolean_flag = True
                while boolean_flag:
                    print(self)
                    coord_input = input(
                        "Введите координаты расположения шашки №{} -> ".format(
                            i + 1))
                    if UtilClass.checkxy_value(coord_input):
                        coord_x = int(coord_input[1]) - 1
                        coord_y = coord_input[0]
                        result = self.boardfigure_setter(
                            color, coord_x, coord_y)
                        if result:
                            print("Успешная постановка шашки на координаты {}".
                                  format(coord_input))
                            boolean_flag = False
                    else:
                        print(
                            "\033[91m[Ошибка]\033[0m Некорретный ввод данных, пример координат: h2"
                        )
Example #8
0
    def boardfigure_setter(self, color, search_x, search_y):
        """
        Поиск координат фигуры и ее постановка
        Возврат True - фигура поставлена
        Возврат False - фигура с координатами не найдена
        """
        x = search_x
        y = UtilClass.char2xint(search_y)
        board = self.board

        if board[x][y].isfree() and board[x][y].color == "black":
            board[x][y].field_reserve(FigureClass(color, x, y))
            self.board = board
            return True

        if not board[x][y].isfree():
            print(
                "\033[91m[Ошибка]\033[0m Клетка с координатами {}{} уже занята"
                .format(search_y, search_x + 1))

        if board[x][y].color == "white":
            print(
                "\033[91m[Ошибка]\033[0m Цвет клетки с координатами {}{} белый"
                .format(search_y, search_x + 1))

        return False
Example #9
0
 def board_generator(self):
     """Создание чистого игрового поля без фигур"""
     board = np.array([])
     for x in np.arange(8):
         for y in np.arange(8):
             field_obj = FieldClass(UtilClass.xint2char(x), y)
             board = np.append(field_obj, board)
     self.board = np.array(board.reshape(8, 8))
Example #10
0
    def color_generator(self):
        """Генератор цвета ячейки на основе ее координат"""
        x = UtilClass.char2xint(self.coord_x)
        y = self.coord_y

        if (x % 2 == 0 and y % 2 == 0) or (y % 2 == 1 and x % 2 == 1):
            color = "black"
        else:
            color = "white"

        self.color = color
Example #11
0
    def diagonal_detector(self):
        """Проверка на осуществление перехода по диагонали"""
        # Возможные пути, куда может пойти шашка (их всего 4)
        board_obj = self.board_obj
        d = self.command_dict
        target_x = d["from"]["x"]
        target_y = UtilClass.char2xint(d["from"]["y"])
        # Возможные клетки, куда можно пойти и которые есть на доске

        # Т.к. использование "коротких" перемещений при атаке просто невозможно
        if d["mode"] == "war":
            allowedfields_list = [
                [target_x + 2, target_y + 2],
                [target_x + 2, target_y - 2],
            ]
        # При тихом ходе возможны только короткие перемещения
        else:
            allowedfields_list = [
                [target_x + 1, target_y + 1],
                [target_x + 1, target_y - 1],
            ]

        validated_points = [
            e for e in allowedfields_list if board_obj.detect_element(*e)
        ]

        if [d["to"]["x"],
                UtilClass.char2xint(d["to"]["y"])] in validated_points:
            self.results_list.append(True)
        else:
            if self.info:
                print(
                    "\033[91m[Ошибка]\033[0m Шашки могут ходить только по диагонали, ход с боем - длинное перемещение, тихий ход - короткое перемещение."
                )
                # TODO Предложение о возможных ходах для фишки при некорректном ходе
                # print("Возможные команды для корректного кода с клетки {}:")
            self.results_list.append(False)
Example #12
0
    def computer_mode(self):
        """
        Осуществление хода компьютера
        - Выбираются координаты ячейки из сформированного словаря
        - Берется объект фигуры, меняются координаты фигуры на обновлённые
        - Осуществляется привязка к новой ячейке фигуры
        - Из старой ячейки освобождается объект фигуры
        
        - Если осуществилась атака, то удаляем фигуру врага из ячейки enemy
        """

        d = self.result_dict
        board = self.board_obj.board

        mode = d["mode"]
        f1 = [d["from"]["x"], UtilClass.char2xint(d["from"]["y"])]
        f2 = [d["to"]["x"], UtilClass.char2xint(d["to"]["y"])]
        x1, y1 = f1
        x2, y2 = f2
        field_from = board[x1][y1]
        field_to = board[x2][y2]

        figure_obj = field_from.figure_obj
        figure_obj.coord_x, figure_obj.coord_y = f2

        # Присваиваем фигуру обновленной ячейке
        field_to.field_reserve(figure_obj)
        # Освобождаем из старой
        field_from.field_free()

        # Если мы кого-то бъём, то удаляем фигуру с той ячейки
        if mode == "war":
            attack_x, attack_y = d["enemy"]["x"], d["enemy"]["y"]
            board[attack_x][attack_y].field_free()

        self.board_obj.board = board
Example #13
0
    def detect_element(self, search_x, search_y):
        """
        Определяем, есть ли элемент с такими координатами на доске
        Это необходимо для того, чтоб не выехать за массив
        """
        if search_x not in range(0, 8) or search_y not in range(0, 8):
            return False

        search_x = UtilClass.xint2char(search_x)
        board = self.board
        for x in np.arange(board.shape[0]):
            for y in np.arange(board.shape[1]):
                if board[x][y].coord_x == search_x and board[x][
                        y].coord_y == search_y:
                    return True
        return False
Example #14
0
    def gameprocess(self):
        """Управляющая логика работы игры"""
        userstepcolor_dict = {"black": 1, "white": 0}
        usercolor_dict = {"black": "Черный", "white": "Белый"}
        user_color = self.user_color
        userstep = userstepcolor_dict[user_color]

        # Номер итерации
        i = 0
        won_color = ""

        print("\033[93m*Игра началась*\033[0m")
        journal = JournalWriterClass()
        while True:

            # Проверяем на окончание игры
            obj = GameOverClass(self.board_obj, user_color)
            if obj.result:
                won_color = obj.won_color
                print("Выиграл цвет: {}".format(usercolor_dict[obj.won_color]))
                break

            # Ходит пользователь
            if i % 2 == userstep:
                print("Ход №{}. Ходит пользователь..".format(i + 1))
                cmd = input("Введите команду -> ")
                result_dict = self.command_parser(cmd)

                # Если нормально прошло фильтрацию
                if result_dict != {}:
                    self.result_dict = result_dict
                    # Проверка на все критерии
                    obj = UserAnalyserClass(result_dict, self.board_obj, True)
                    # Если все хорошо, то осуществлем ход
                    if obj.boolean_result:
                        self.result_dict = obj.command_dict
                        # Пользователь ходит
                        self.user_mode()
                        journal.add_result(obj.command_dict)
                        i += 1
                    else:
                        print("\033[91m[Ошибка]\033[0m Некорректный ход")
                else:
                    print(
                        "\033[91m[Ошибка]\033[0m Некорректный ввод данных. Пример: 'c3:e5' - перемещение с боем, 'c3-b4' - тихое перемещение"
                    )

            # Компьютер ходит
            else:
                print("Ход №{}. Ходит компьютер..".format(i + 1))
                time.sleep(3)
                computergame_obj = ComputerGameClass(self.board_obj,
                                                     user_color)
                d = computergame_obj.result_dict
                print("{} -> {}".format(
                    UtilClass.getfail_coords(d["from"]),
                    UtilClass.getfail_coords(d["to"]),
                ))
                # Если тупиковый ход со стороны компьютера
                if not computergame_obj.result:
                    won_color = user_color
                    print(
                        "\033[91m[ИНФО]\033[0m У компьютера тупиковая ситуация"
                    )
                    print("Выиграл цвет: {}".format(
                        usercolor_dict[user_color]))
                    break

                journal.add_result(d)
                i += 1

            # Вывод доски
            print(self.board_obj)

        # Добавление окончания
        journal.winlose_add(won_color)
        print(journal)
Example #15
0
    def deadlock_detector(self):
        """
        Определение тупиковой ситуации для пользователя
        Использует логику, аналогичную рандомному ходу компьютера
        """
        board_obj = self.board_obj
        board = board_obj.board

        uc = self.user_color
        reverse_uc = "black" if uc == "white" else "white"

        all_d = np.array([])
        myfields_arr = np.array([])
        # Ищем все фигуры пользователя
        for i in np.arange(board.shape[0]):
            for j in np.arange(board.shape[1]):
                if not board[i][j].isfree(
                ) and board[i][j].figure_obj.color == uc:
                    myfields_arr = np.append(myfields_arr, board[i][j])

        # Для каждой шашки формируем возможные новые координаты:
        for field in myfields_arr:

            x, y = field.figure_obj.coord_x, field.figure_obj.coord_y
            y_char = UtilClass.xint2char(y)

            # Возможные короткие шаги
            # [x+1,y-1]
            if board_obj.detect_element(y - 1, x + 1):
                new_y, new_x = UtilClass.xint2char(y - 1), x + 1
                all_d = np.append(
                    all_d,
                    {
                        "from": {
                            "x": x,
                            "y": y_char
                        },
                        "to": {
                            "x": new_x,
                            "y": new_y
                        },
                        "mode": "peace",
                        "user_color": uc,
                    },
                )

            # [x+1,y+1]
            if board_obj.detect_element(y + 1, x + 1):
                new_y, new_x = UtilClass.xint2char(y + 1), x + 1
                all_d = np.append(
                    all_d,
                    {
                        "from": {
                            "x": x,
                            "y": y_char
                        },
                        "to": {
                            "x": new_x,
                            "y": new_y
                        },
                        "mode": "peace",
                        "user_color": uc,
                    },
                )

            # Длинные шаги
            # [x+2,y+2]
            if board_obj.detect_element(y + 2, x + 2):
                new_y, new_x = UtilClass.xint2char(y + 2), x + 2
                all_d = np.append(
                    all_d,
                    {
                        "from": {
                            "x": x,
                            "y": y_char
                        },
                        "to": {
                            "x": new_x,
                            "y": new_y
                        },
                        "mode": "war",
                        "user_color": uc,
                    },
                )

            # [x+2,y-2]
            if board_obj.detect_element(y - 2, x + 2):
                new_y, new_x = UtilClass.xint2char(y - 2), x + 2
                all_d = np.append(
                    all_d,
                    {
                        "from": {
                            "x": x,
                            "y": y_char
                        },
                        "to": {
                            "x": new_x,
                            "y": new_y
                        },
                        "mode": "war",
                        "user_color": uc,
                    },
                )

        # Перебираем все возможные ходы пользователя
        for d in all_d:
            obj = UserAnalyserClass(d, self.board_obj)
            if obj.boolean_result:
                break

        else:
            self.result = True
            self.won_color = reverse_uc
            print("\033[91m[ИНФО]\033[0m У пользователя тупиковая ситуация")
Example #16
0
    def processing(self):
        uc = self.user_color
        # Цвет, за который ходит компьютер
        reverse_uc = "black" if uc == "white" else "white"
        myfields_arr = np.array([])
        all_d = []
        board = self.board_obj.board

        for i in np.arange(board.shape[0]):
            for j in np.arange(board.shape[1]):
                if (not board[i][j].isfree()
                        and board[i][j].figure_obj.color == reverse_uc):
                    myfields_arr = np.append(myfields_arr, board[i][j])

        # Для каждой шашки формируем возможные новые координаты, перемешиваем это и закидываем в ComputerAnalyserClass
        for field in myfields_arr:

            x, y = field.figure_obj.coord_x, field.figure_obj.coord_y
            y_char = UtilClass.xint2char(y)

            # Возможные короткие шаги
            # [x-1,y-1]
            if self.board_obj.detect_element(y - 1, x - 1):
                new_y, new_x = UtilClass.xint2char(y - 1), x - 1
                all_d.append({
                    "from": {
                        "x": x,
                        "y": y_char
                    },
                    "to": {
                        "x": new_x,
                        "y": new_y
                    },
                    "mode": "peace",
                    "user_color": reverse_uc,
                })

            # [x-1,y+1]
            if self.board_obj.detect_element(y + 1, x - 1):
                new_y, new_x = UtilClass.xint2char(y + 1), x - 1
                all_d.append({
                    "from": {
                        "x": x,
                        "y": y_char
                    },
                    "to": {
                        "x": new_x,
                        "y": new_y
                    },
                    "mode": "peace",
                    "user_color": reverse_uc,
                })

            # Длинные шаги
            # [x-2,y+2]
            if self.board_obj.detect_element(y + 2, x - 2):
                new_y, new_x = UtilClass.xint2char(y + 2), x - 2
                all_d.append({
                    "from": {
                        "x": x,
                        "y": y_char
                    },
                    "to": {
                        "x": new_x,
                        "y": new_y
                    },
                    "mode": "war",
                    "user_color": reverse_uc,
                })

            # [x-2,y-2]
            if self.board_obj.detect_element(y - 2, x - 2):
                new_y, new_x = UtilClass.xint2char(y - 2), x - 2
                all_d.append({
                    "from": {
                        "x": x,
                        "y": y_char
                    },
                    "to": {
                        "x": new_x,
                        "y": new_y
                    },
                    "mode": "war",
                    "user_color": reverse_uc,
                })

        random.shuffle(all_d)
        all_d.sort(key=lambda x: x["mode"], reverse=True)

        for d in all_d:
            obj = ComputerAnalyserClass(d, self.board_obj)
            if obj.boolean_result:
                self.result_dict = obj.command_dict
                self.computer_mode()
                break
        else:
            self.result = False