forked from cosmicr/startrek1971
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathMapSparse.py
237 lines (212 loc) · 7.3 KB
/
MapSparse.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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
import random
import PyTrek.TrekStrings as TrekStrings
import PyTrek.Glyphs as Glyphs
class SparseMap:
'''
Minimalist mapping.
On-demand 'sparse-array' expansion to full-Area views.
'''
class Region():
'''
Regional meta for a collection of Area maps.
'''
def __init__(self):
self.name = ""
class Area():
'''
A minimalist collection of Area-plotted Glyphs.
Area numbers are 1's based.
Area plotting is 0's based.
Area names are Trekian.
'''
class Piece:
'''
Sparse data management for an increasingly minimalist world.
'''
def __init__(self, xpos, ypos, glyph=Glyphs.SPACE):
self.xpos = xpos
self.ypos = ypos
self.glyph = glyph
def __init__(self):
'''
Create an empty AREA.
'''
self.name = ""
self.number = -1
self._pieces = []
def is_null(self):
'''
See if this AREA has anything important.
'''
dum = SparseMap.Area()
return dum.name == self.name and \
dum.number == self.number and \
len(dum.objs) == len(self._pieces)
def is_empty(self):
''' Checks to see if the Area has anything ...'''
return len(self._pieces) == True
def item_count(self)->int:
''' The number of pieces / items in the randint ...'''
return len(self._pieces)
def remove(self, xpos, ypos):
''' Remove an item from the Area. '''
for ss, obj in enumerate(self._pieces):
if obj.xpos == xpos and obj.ypos == ypos:
self._pieces.remove(obj)
return
def get_map(self)->list:
'''
Generate a map of this randint. Map is full
of Glyphs.SPACE on error.
'''
results = [[Glyphs.SPACE for _ in range(8)] for _ in range(8)]
for obj in self._pieces:
results[obj.ypos][obj.xpos] = obj.glyph # ASSURED
return results
def __str__(self):
result = ''
for line in self.get_map():
result += ''.join(line)
result += '\n'
return result
def range_ok(self, xpos, ypos):
''' Verify that coordinates are plottable. '''
if xpos < 0 or ypos < 0 or \
xpos > 7 or ypos > 7:
return False
return True
def query(self, glyph):
'''
Clone each Piece for a glyph into a new
collection. Changes to the results WILL NOT
affect the glyph in the AREA.
'''
results = []
for p in self._pieces:
if p.glyph == glyph:
results.append(SparseMap.Area.clone(p))
return results
def count_glyphs(self, glyph):
'''
Tally the number of glyphs that we have in the Area.
'''
count = 0
for p in self._pieces:
if p.glyph == glyph:
count += 1
return count
def plot_glyph(self, xpos, ypos, glyph):
'''
Sync (update or add) a glyph to the sparse array.
Return coordinate occupied, else None on error.
'''
if self.range_ok(xpos, ypos) is False:
return None
for p in self._pieces:
if p.xpos is xpos and p.ypos is ypos:
p.glyph = glyph
return xpos, ypos
self._pieces.append(SparseMap.Area.Piece(xpos, ypos, glyph))
return xpos, ypos
def place_glyph(self, glyph, dest=None):
''' Place / randomly place a glyph into the Map. '''
area = self.get_map()
if not dest:
while True:
xpos = random.randint(0,7)
ypos = random.randint(0,7)
if area[xpos][ypos] == Glyphs.SPACE:
self.plot_glyph(xpos, ypos, glyph)
return xpos, ypos
else:
self.plot_glyph(dest.xpos, dest.ypos, glyph)
return dest.xpos, dest.ypos
@staticmethod
def clone(piece):
''' Copy a piece. '''
return SparseMap.Area.Piece(piece.xpos, piece.ypos, piece.glyph)
def __init__(self):
'''
Create the uninitialized REGION. Use .init() to
populate same with AREAs.
'''
self.initalized = False
self._map = [[[y,x] for y in range(8)] for x in range(8)]
def init(self, reset=False):
'''
Fill a newly-created map with a set of randomly-named AREAs.
'''
if not reset and self.initalized:
return
for xx, row in enumerate(self._map):
lrs = SparseMap.Region()
for yy, col in enumerate(row):
self._map[xx][yy] = [lrs, SparseMap.Area()]
self.name_areas()
self.initalized = True
def get_area(self, which):
'''
Get an AREA from the map.
Area identifiers are 1's based.
Returns False on under / over flows.
'''
if which < 1:
return False
if which >= 65:
return False
which -= 1 # ASSURED
fid = which / 8
ypos = 0
xpos = int(fid)
if not fid.is_integer():
ypos = which %8
return self._map[xpos][ypos][1]
def data(self):
''' Enumerate thru every [Region, Area] in the Map '''
for row in self._map:
for col in row:
yield col
def areas(self):
''' Enumerare thru every Area on the Map '''
for row in self._map:
for col in row:
yield col[1]
def name_areas(self):
'''
Assign / re-assign 'Trekian names.
'''
names = list(TrekStrings.AREA_NAMES)
for num, area in enumerate(self.areas(),1):
index = random.randrange(0, len(names))
area.name = names[index]
area.number = num
del names[index]
def get_sector_names(self):
'''
Return a list of [secor numbers, sector_name] pairs.
'''
results = []
temp = []
for ss, col in enumerate(self.areas(),1):
temp.append([col.number,col.name])
if ss % 8 == 0:
results.append(temp)
temp = []
results.append(temp)
return results
def plot(self, ones_based, xpos, ypos, glyph):
'''
Add an item to a MAP using the 1's based AREA identifier.
Coordinates here are ZERO based.
'''
for area in self.areas():
if area.number == ones_based:
area.plot_glyph(xpos, ypos, glyph)
return True
return False
def plot_ones_based(self, ones_based, xpos, ypos, glyph):
'''
Add an item to a MAP using the 1's based AREA identifier.
Coordinates here are ONES based.
'''
return self.plot(ones_based, xpos -1, ypos -1, glyph)