Страницы

Поиск по вопросам

воскресенье, 9 февраля 2020 г.

Python 3.6 - парсинг файла и заполнение массива

#python #python_3x #парсер #динамические_массивы


Добрый день! Пишу 2D игру на Python 3.6 и возникла проблема создания массива.
Python я начал изучать совсем недавно. Смысл такой - функция должна парсить файл
карты и заполнять массив. Структура карты простая, в зависимости от символа другая
функция загружает спрайт, например '=' - это кирпичная стена, но все это должно считываться
из массива, который я пока не понял, как делать. Пример файла карты:

LevelsCount:2
LevelName:Name
LevelNum:1
LevelType:Green
{
==d=====================
=0000000000000000000000=
=0000000000000000000000=
=0000000000000000000000=
=0000000000000000000000=
=0000000000000000000000=
=0001111122211111000000=
=0000000000000000000000=
========================
}


Уровень из файла карты должен считываться в трехмерный (?) массив от "{" до "}",
причем выборочно, если укажу '1' в параметр функции, то считываться только LevelNum:1.
Каждая строка является новым элементом массива и каждый символ является элементом массива,
чтобы при доступе получить, к примеру: 

==d=====================


blocks[0][0] - '=' или blocks[0][2] - 'd', где [0] это номер строки, а [2] - номер
символа в строке.
Вот функция, которую я не могу написать правильно:

def parse_levelpack(chapt, lvl):
    lvl_file = open('pack/levels/Chapter' + str(chapt) + '.mapf', 'r')
    y_block = -1
    x_block = -1
    global levelCount
    line = lvl_file.readline()
    while line:
        line = line.replace('\n', '')
        line = lvl_file.readline()
        if line.find('{') > -1:
            y_block = y_block + 1
            x_block = -1
            blocks_array[y_block].append([])
            lvl_file.readline()
            if not line == '}':
                lvl_file.readline()
                x_block = x_block + 1
                blocks_array[x_block].append([])
                blocks_array[y_block][x_block].append(line[x_block])
    lvl_file.close()


chapt - часть, добавляется к имени файла, lvl - чтобы из файла карты выбрать нужный
уровень, например, LevelNum:1.
    


Ответы

Ответ 1



Парсер простой, поэтому думаю автор сам его допилит, а я покажу пример парсера локаций: def fill_blocks(text_or_list): blocks = [] if type(text_or_list) == str: line_list = text_or_list.splitlines() else: line_list = text_or_list for line in line_list: line = line.strip() if not line: continue row = [x for x in line] blocks.append(row) return blocks def get_text_level_blocks(text): text_level_blocks = [] start_block = False blocks_text = None for line in text.splitlines(): line = line.strip() if not line: continue if line == '{': start_block = True blocks_text = [] continue elif line == '}': start_block = False text_level_blocks.append(blocks_text) continue # Если не кирпич elif not line.startswith('='): continue # Дальше ищем символ стартового блока if not start_block: continue blocks_text.append(line) return text_level_blocks if __name__ == '__main__': text = """\ ==d===================== =0000000000000000000000= =0000000000000000000000= =0000000000000000000000= =0000000000000000000000========= =000000000000000000000000000000= =0001111122211111000000========= =0000000000000000000000= ======================== """ blocks = fill_blocks(text) print(''.join(blocks[0])) print(blocks[0][0]) print() many_level_text = """\ { ==d===================== =0000000000000000000000= =0000000000000000000000= =0000000000000000000000= =0000000000000000000000========= =000000000000000000000000000000= =0001111122211111000000========= =0000000000000000000000= ======================== } ... { ==d===================== =0000000000000000000000= =0000000000000000000000= =0000000000000000000000= =0000000000000000000000= =0000000000000000000000= =0001111122211111000000= =0000000000000000000000= ======================== } """ text_level_blocks = get_text_level_blocks(many_level_text) print(len(text_level_blocks)) level_block = text_level_blocks[0] blocks = fill_blocks(level_block) print(''.join(blocks[0])) print(blocks[0][0]) print() all_levels_block = [] for level_block in text_level_blocks: blocks = fill_blocks(level_block) all_levels_block.append(blocks) print(''.join(all_levels_block[0][4])) print(''.join(all_levels_block[1][4])) print(all_levels_block[0][0][2]) print(all_levels_block[1][0][2]) Консоль: ==d===================== = 2 ==d===================== = =0000000000000000000000========= =0000000000000000000000= d d

Ответ 2



Чтобы найти все {} блоки в файле, можно регулярное выражение использовать: import re from pathlib import Path blocks = re.findall("(?s){(.*)}", Path('chart.mapf').read_text()) Чтобы превратить каждый блок в двухмерный список: blocks3D = [block.strip().splitlines() for block in blocks] Для проверки: blocks3D[0][-3][9] это символ расположенный в первом блоке, на третьей с конца строчке, на десятой позиции ('2'). В этом случае строчки типом str представлены — неизменяемы. Если хочется по одному символу изменять, можно матрицу создать со списками вместо строк: blocks3D = [list(map(list, block.strip().splitlines())) for block in blocks]

Комментариев нет:

Отправить комментарий