-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuser_map.py
173 lines (160 loc) · 9.64 KB
/
user_map.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# encoding:utf-8
"""Обработка пользовательской карты"""
from processing_io import show_labirinth
from re import findall
from config import way, height, width
#Блок исключений
class UserExceptions(Exception):
"""Класс для обработки человеческих ошибок"""
def __init__(self):
self.data = None
def set_value(self, value): # Получение входных параметров
self.data = value
def many_io(self): # Блок избыточных точек входа или выход
point = 'выход'
if self.data[0] == '2':
point = 'вход'
print "В вашей карте более одного " + point + "а.Исправьте входные данные" + '\n'
raise Exception
def incorrect_size(self): # Блок неверных размеров лабиринта
size = str(width)
if self.data == 'высоту':
size = str(height)
print "Размеры лабиринта" + " в " + self.data + "больше допустимых " + size + " клеточек" + '\n'
raise Exception
def not_correct_value(self): # Случай когда пользователь использует в лабиринте постороние цифры
print "В карте лабиринта обнаружено число " + self.data + "которое не удволетворяет требованиям программы" + '\n'
raise Exception
def not_equal_len(self): # Строки разной длины
print "В вашей карте имеются строки разной длины.(строка # " + str(self.data) + ")" + '\n'
raise Exception
def create_exception(data):
exception = UserExceptions()
exception.set_value(data)
print # Вставка для того чтобы отделить визуально причину внештатной ситуации
return exception
# Чтение и сборка
def read_out_file(height, width):
# Попытка получить файл на диске
try:
raw_input('''Уважаемый пользователь.ниже написана небольшая инструкция
После ее прочтения и выполнения - нажмите клавишу "Enter"
1.Карта должна лежать в одной папке с исполняемой программой(скриптом)
2.Файл с картой должен иметь имя "field".Без кавычек
3.Файл с картой должен представлять из себя матрицу чисел,в которой могут и долны встречаться числа 0, 1, 2, 3
4.Начало пути отмечается цифрой "2". Окончание - цифрой "3".Проходимые участки - цифрой "0". Непроходимые - цифрой "1"
5.Пример карты лежит в папке с программой и назван "example_field"
6.Если вы все поняли и выполнили - нажмите 'Enter' и добро пожаловать в лабиринт''')
all_file = str(open('field').readlines()) # Читам что нам там подарил пользователь
first_string = all_file[:all_file.find('\\n')] # Первая строка до переноса каретки
total_elements_in_string = len(findall('(\d+)', first_string)) # Получим первую строку и потом из нее узнаем сколько в ней чисел
number_string_in_file = len(open('field').readlines()) # Количество строк в файле
file_check(all_file)
size_maze(total_elements_in_string, number_string_in_file) # Проверка размеров лабиринта
M = total_elements_in_string + 2
N = number_string_in_file + 2
field = building_field(total_elements_in_string, open('field')) # Постройка лабиринта из файла с картой
xfield = convert_type_maze(field, N, M) # Но это полдела.Надо конвертнуть
show_labirinth(N, M, xfield) # Покажем лабиринт
print "Наш лабиринт!"
from time import sleep
sleep(2) # Пауза чтоб рассмотреть
from numpy import argwhere
S = argwhere(xfield == 2)[0] # Получим координаты старта
F = argwhere(xfield == 3)[0] # и финиша.
xfield[S[0]][S[1]] = 0 # Затрем отметку старта(для лучшей визуализации)
from processing_io import promt, final_check,show_way
x = promt('search')
if x == 2: # Вилка на выбор варианта алгоритмы
from BFS import BFS
Bway, Bfield = BFS(field, S, F)
check = final_check(Bfield, F)
if check:
show_way(Bway)
show_labirinth(N, M, Bfield)
elif x == 1:
from DFS import DFS # Подгружаем алгоритм
from sys import setrecursionlimit # Установка рекурсии именно на этом шаге,
setrecursionlimit(height*width) # т.к не факт что пользователь выберет этот путь
DFS(S[0], S[1], field, S, F, way)
check = final_check(field, F)
if check:
show_way(way)
show_labirinth(N, M, field)
except IOError:
print "Проблемы с доступом к файлу.Проверьте наличие файла согласно инструкции или создайте его если такового не имеется" + '\n'
except IndexError:
print "Возможно вы не указали точку начала или окончания пути"
except:
print "Кажется что то пошло не так.Проверьте входные данные и попробуйте снова.Если ошибка будет повторяться-обратитесь к разработчику"
def convert_type_maze(field, N, M):
"""Получим лабиринт из вложеных списков.
Превратим его в лабиринт-массив из NumPy"""
from numpy import zeros
second_field = zeros((N, M), dtype=int)
y = 0
while y < N:
second_field[y] = field[y]
y += 1
return second_field
def building_field(total_elements_in_string, input_value):
"""Займемся сборкой игрового поля из того что нам подарил пользователь"""
from re import sub
field = []# Новый список туда будем складывать все строки
string_field = []
# И сразу же построим верхнюю стенку
for x in xrange(total_elements_in_string + 2):
string_field.append(-1)
field.append(string_field)
i = 1
while i <= len(open('field').readlines()):
string_content = input_value.readline().strip()
if string_content != '':# Немного движений дабы преобразовать непустую строку в список
string_content = sub('1', '-1', string_content)# чтобы модифицировать единички в (-1)стенки
string_content = findall('(-*\d+)', string_content)# Число цифр в строке.
if len(string_content) != total_elements_in_string:# Контролируем дабы не было лабиринта со строками разного уровня
exception = create_exception(i)
exception.not_equal_len()
# А потом все добавить в список который будет строкой-частью поля
# И плюсом два элемента стенки по бокам
del string_field[:]
string_field.append(-1)
for x in string_content:
string_field.append(int(x))
string_field.append(-1)
field.append(string_field[:])
i += 1
# Как только выйдем из цикла-добавим нижнюю стенку.
del string_field[:]
for x in xrange(total_elements_in_string + 2):
string_field.append(-1)
field.append(string_field)
return field
# Проверки
def file_check(all_file):
"""проверка наличия постороних цифр"""
all_numbers_in_files = findall('(-*\d+)', all_file)
for x in all_numbers_in_files:
if x != '0' and x != '1' and x != '2' and x != '3':
exception = create_exception(x)
exception.not_correct_value()
two = []
three = []
for x in all_numbers_in_files:
if x == '2':
two.append(x)
elif x == '3':
three.append(x)
if len(two) > 1:
exception = create_exception(two)
exception.many_io()
elif len(three) > 1:
exception = create_exception(three)
exception.many_io()
def size_maze(total_elements_in_string, number_string_in_file):
if total_elements_in_string > width:
exception = create_exception('ширину')
exception.incorrect_size()
elif number_string_in_file > height:
exception = create_exception('высоту')
exception.incorrect_size()