diff --git a/LaddersV1.py b/LaddersV1.py new file mode 100755 index 0000000..726f3f5 --- /dev/null +++ b/LaddersV1.py @@ -0,0 +1,186 @@ +import random +from Player import Player + + +class LaddersV1(): + + def dice(self): + diced = random.randint(1, 6) + print(f'{diced} was diced') + return diced + + def move(self, player, steps, field): + # Алгоритм действий такой: + + # сначала увеличиваем позицию игрока на кол-во шагов. + player.position += steps + + if player.position >= len(field): + player.position = len(field) - 1 + + # Затем проверяем, нет ли особых действий на клетке, на которую попал игрок. + cell = field[player.position] + if cell > 0: + # Если есть, то либо перемещаем игрока на новую позицию, либо выставляем свойство skip. + if cell == player.position: + # Пропусти следующий ход! + player.skip = True + else: + player.position = cell + + def draw(self, field, players): + for i in range(0, len(field), 10): + sub = field[i:i+10] + line = '' + + for j in range(len(sub)): + e = sub[j] + pos = i + j + + player_found = False + + for player_index in range(len(players)): + pl = players[player_index] + if pl.position == pos: + line += pl.color[:2] + player_found = True + break + + if not player_found: + if 0 <= e < 10: + line += ' ' + str(e) + else: + line += str(e) + + line += ' ' + print(line) + + def game_loop(self, auto, field): + random.seed() + + exit_game = False + stop_game = False + winner = None + result = 0 + + # Инициализируем список игроков + players = [Player("red"), Player("green"), Player("blue"), Player("yellow")] + + if not auto: + # Изначально вывести пустое поле без игроков + self.draw(field, players) + + # Игровой цикл (бесконечный) + while True: + + # Если дана команда выйти из игры + if exit_game: + if not auto: + # Рисуем поле + self.draw(field, players) + + # Вывод информации + print("Игра прервана") + + # Сохранить результат + result = -1 + break + + # Если у игры выявлен победитель + if winner is not None: + if not auto: + # Нарисовать поле + self.draw(field, players) + + # Вывести победителя + print((f'{winner.color} is winner')) + print(f'moves of winner are {winner.dices}') + + # Сохранить результат + result = len(winner.dices) + + break + + # Если выходим по причине зацикливания + if stop_game: + if not auto: + # Рисуем поле + self.draw(field, players) + + # Вывод информации + print("Игра прервана по причине зацикливания") + + # Сохранить результат + result = -1 + break + + # Выполняет действия для каждого игрока + for p in players: + + # Если игрок должен пропустить ход + if p.skip: + + if not auto: + # Вывести на экран информацию о том, что он пропускает ход + print(f'{p.color} skips') + + # Не пропускать СЛЕДУЮЩИЙ ход + p.skip = False + + # Если ход пропускать не надо + else: + if not auto: + # Выводит текст на экран и ждет ввода + inp = input(f'{p.color} to move') + else: + inp = '' + + # Обработка ввода + # Если пользователь ввел exit или quit + if inp == 'exit' or inp == 'quit': + # Даем команду выйти из игры + exit_game = True + + # Прервать цикл обработки игроков + break + + # Бросаем кубик с возможностью повторить + repeat = True + while repeat: + # Бросает кубик один раз + diced = self.dice() + + # Двигаем игрока на кол-во шагов с кубика + # Возвращает True, если нужно повторить ход + repeat = self.move(p, diced, field) + + # Сохраняем значение кубика + p.dices.append(diced) + + # Eсли игрок попал в последнюю клетку + if p.position == len(field) - 1: + # Установить победителя (таким образом дать команду выйти из игры) + winner = p + + # Прервать цикл обработки игроков + break + + # Проверяем "зацикливание" + if len(p.dices) >= 1000: + # Даем команду прервать игру + stop_game = True + + # Прервать цикл обработки игроков + break + + if not auto: + # Пустая строка + print() + + # Рисует поле + self.draw(field, players) + + # Возвращаем кол-во бросков + return result + + diff --git a/LaddersV2.py b/LaddersV2.py new file mode 100755 index 0000000..f3d1549 --- /dev/null +++ b/LaddersV2.py @@ -0,0 +1,8 @@ +import random +from LaddersV1 import LaddersV1 + + +class LaddersV2(LaddersV1): + + def dice(self): + return random.randint(1, 3) diff --git a/LaddersV3.py b/LaddersV3.py new file mode 100755 index 0000000..51b903e --- /dev/null +++ b/LaddersV3.py @@ -0,0 +1,9 @@ +from LaddersV1 import LaddersV1 + + +class LaddersV3(LaddersV1): + + def move(self, player, steps, field): + super().move(player, steps, field) + + player.skip = False diff --git a/LaddersV4.py b/LaddersV4.py new file mode 100755 index 0000000..3d2b55f --- /dev/null +++ b/LaddersV4.py @@ -0,0 +1,16 @@ +from LaddersV1 import LaddersV1 + + +class LaddersV4(LaddersV1): + + def move(self, player, steps, field): + super().move(player, steps, field) + + # Возвращаем True если значение поля отрицательное + return field[player.position] < 0 + + + + + + diff --git a/LaddersV5.py b/LaddersV5.py new file mode 100755 index 0000000..1562b7d --- /dev/null +++ b/LaddersV5.py @@ -0,0 +1,25 @@ +from LaddersV1 import LaddersV1 + + +class LaddersV5(LaddersV1): + + def move(self, player, steps, field): + # считаем сколько клеток осталось до конца + r = len(field) - 1 - player.position + + super().move(player,steps, field) + + # если количество клеток, которые игроку надо пройти, больше чем клеток до конца + if steps > r: + # двигаем игрока назад от конца поля + # на количество клеток в виде разнице оставшихся клеток до конца и клеток которые надо пройти + player.position = len(field) - 1 - (steps - r) + + # Возвращаем True если значение поля отрицательное + return field[player.position] < 0 + + + + + + diff --git a/Player.py b/Player.py new file mode 100755 index 0000000..cb23d20 --- /dev/null +++ b/Player.py @@ -0,0 +1,7 @@ +class Player: + + def __init__(self, color): + self.color = color + self.position = -1 + self.skip = False + self.dices = [] diff --git a/files.py b/files.py new file mode 100755 index 0000000..85514e4 --- /dev/null +++ b/files.py @@ -0,0 +1,33 @@ +import os + + +def list_levels(): + files = os.listdir(path='.') + result = [] + for file in files: + if file.lower().endswith('.txt'): + result.append(file) + + return result + + +def load(file): + # 1. Загрузить весь файл в строку + f = open(file, 'r') + s = f.read() + + # 2. Заменить все пробелы и переводы строки на "ничего" + s = s.replace(' ', '') + s = s.replace('\n', '') + + # 3. Из полученной строки создать массив, используя разделитель "," + a = s.split(',') + + # a - массив строк, в которых хранятся числа + b = [] + for x in a: + b.append(int(x)) + # b - массив чисел из а + + f.close() + return b \ No newline at end of file diff --git a/level1.txt b/level1.txt new file mode 100755 index 0000000..83200ef --- /dev/null +++ b/level1.txt @@ -0,0 +1,10 @@ +0, 0, 2, 3, 4, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 1, 0 \ No newline at end of file diff --git a/level2.txt b/level2.txt new file mode 100755 index 0000000..5474b09 --- /dev/null +++ b/level2.txt @@ -0,0 +1,10 @@ +0, 0, 2, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 4, 0, 0, 0, +0, 7, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 6, 0, 0, 0, 0, 3, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 5, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 1, 0 \ No newline at end of file diff --git a/level3.txt b/level3.txt new file mode 100755 index 0000000..670fcde --- /dev/null +++ b/level3.txt @@ -0,0 +1,10 @@ +6, 0, 2, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 5, 0, 0, 0, 0, 0, 0, +7, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 1, 1, 1, 1, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 3, 1, 0 \ No newline at end of file diff --git a/level4.txt b/level4.txt new file mode 100755 index 0000000..e6920de --- /dev/null +++ b/level4.txt @@ -0,0 +1,10 @@ +0, 0, -1, -1, -1, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 9, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 9, 0, 8, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 3, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 4, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 5, 6, 7, 1, 0 \ No newline at end of file diff --git a/level5.txt b/level5.txt new file mode 100755 index 0000000..47da729 --- /dev/null +++ b/level5.txt @@ -0,0 +1,10 @@ +0, 0, 2, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 9, 0, 9, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 3, 0, 0, 4, 0, 5, 0, 6, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 9, 9, 0, 8, 0, 7, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 9, 0, 0, 9, 9, 9, 1, 0 \ No newline at end of file diff --git a/main.py b/main.py new file mode 100755 index 0000000..095f91d --- /dev/null +++ b/main.py @@ -0,0 +1,136 @@ +from run import run +from files import list_levels +from files import load + + +def level_menu(levels): + for i in range(1, len(levels) + 1): + print(f'{i}. Level {i}') + print(f'{len(levels) + 1}. Назад') + + +def level_menu_loop(levels): + while True: + level_menu(levels) + inp = input() + if inp.isnumeric(): + op = int(inp) + if 1 <= op <= len(levels) + 1: + if op <= len(levels): + # Выбор уровня + return levels[op - 1] + else: + # Выход из меню + return None + + else: + print('Выберите номер из меню!') + else: + print('Вводите только цифры!') + + +# Добавляем подменю для выбора версии игры +def game_versions_menu(): + ## 1 ## + max_version = 6 + for i in range(1, max_version): + print(f'{i}. Version {i}') + + print(f'{max_version}. Назад') + + +def game_version_loop(): + ## 2 ## + while True: + game_versions_menu() + inp = input() + if inp.isnumeric(): + op = int(inp) + if 1 <= op <= 6: + ## 3 ## + if op <= 5: + return op + else: + # Выход из меню + return 0 + else: + print('Выберите номер из меню!') + else: + print('Вводите только цифры!') + + +def main_menu(): + print('1. Выбор уровня') + print('2. Выбор кол-ва запусков') + print('3. Выбор версии игры') ## 4 ## + print('4. Запуск') + print('5. Выход') + + +def main_menu_loop(): + levels = list_levels() + level = '' + runs = 1 + version = 0 ## 5.1 ## + + while True: + print(f'Выбранный уровень: {level}') + print(f'Кол-во запусков: {runs}') + print(f'Выбранная версия правил: {version}') + + print() + + # Вывод меню на экран + main_menu() + # Ввод от пользователя + inp = input() + + # Валидация ввода пользователя + if inp.isnumeric(): + op = int(inp) + if 1 <= op <= 5: + # Ввод пользователя валидирован, выполняем действие + if op == 1: + # Выбор уровня + ret = level_menu_loop(levels) + + if ret is not None: + level = ret + + elif op == 2: + # Ввод кол-во запусков + inp2 = input('Введите кол-во запусков: ') + if inp2.isnumeric(): + runs = int(inp2) + else: + print('Вводите только цифры!') + + ## 5.2 ## + elif op == 3: + # Выбор версии игры + ret = game_version_loop() + + if ret > 0: + version = ret + + elif op == 4: + # Запуск + if level in levels: + if version > 0: + run(load(level), runs, version) ## 7 ## + else: + print('Для начала выберите версию!') ## 8 ## + else: + print('Для начала выберите уровень!') + + else: + # Завершение программы + break + + else: + print('Выберите номер из меню!') + else: + print('Вводите только цифры!') + + +main_menu_loop() diff --git a/run.py b/run.py new file mode 100755 index 0000000..da0c4ba --- /dev/null +++ b/run.py @@ -0,0 +1,31 @@ +from LaddersV1 import LaddersV1 +from LaddersV2 import LaddersV2 +from LaddersV3 import LaddersV3 +from LaddersV4 import LaddersV4 + + +def run(level, runs, version): + if version == 1: + game = LaddersV1() + if version == 2: + game = LaddersV2() + if version == 3: + game = LaddersV3() + if version == 4: + game = LaddersV4() + + # Ручной или авто режим + auto = False + + # Если больше одного запуска + if runs > 1: + # Автоматически включаем авто режим + auto = True + + results = [] + + for i in range(runs): + results.append(game.game_loop(auto, level)) + + print(f'Average: {sum(results)/runs}') + print() \ No newline at end of file