aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvg <vgm+dev@devys.org>2020-05-19 20:30:09 +0200
committervg <vgm+dev@devys.org>2020-05-19 20:30:09 +0200
commitaa15b69dd8fd09e19e78c2c10753100e5e426094 (patch)
tree85aedc9a7f0b8298408e558b2c98e018a8a2ec70
parentc05ab89da60feb3ceb3983cdb07ab9d8a80aaeb5 (diff)
downloadkana_quest_solver-aa15b69dd8fd09e19e78c2c10753100e5e426094.tar.gz
kana_quest_solver-aa15b69dd8fd09e19e78c2c10753100e5e426094.tar.bz2
kana_quest_solver-aa15b69dd8fd09e19e78c2c10753100e5e426094.zip
reduce memory consumption by always using same kanas
-rwxr-xr-xsolver.py56
1 files changed, 44 insertions, 12 deletions
diff --git a/solver.py b/solver.py
index 8498f66..df62f64 100755
--- a/solver.py
+++ b/solver.py
@@ -17,6 +17,7 @@ Options:
import copy
import os
import pickle
+import time
import zlib
import docopt
@@ -28,6 +29,8 @@ class Kana:
'ar_u', 'ar_r', 'ar_d', 'ar_l')
slime_merge_types = ('norm', 'froz', 'ar_u', 'ar_r', 'ar_d', 'ar_l')
+ cache = {}
+
def __init__(self, type_name, kana=None):
self.type_name = type_name
self.kana = kana
@@ -44,6 +47,13 @@ class Kana:
assert kana[0] in 'kstnhmryw'
assert kana[1] in 'aiueo'
+ def create(type_name, kana=None):
+ key = (type_name, kana)
+ if key in Kana.cache:
+ return Kana.cache[key]
+ new_kana = Kana.cache[key] = Kana(type_name, kana)
+ return new_kana
+
def dump(self):
'return a list representing the members of this Kana'
return [self.type_name, self.kana]
@@ -54,7 +64,8 @@ class Kana:
def __eq__(self, other):
return self.type_name == other.type_name and self.kana == other.kana
-kana_void = Kana('void')
+
+kana_void = Kana.create('void')
class KanaGrid:
@@ -95,6 +106,12 @@ class KanaGrid:
}
if kana1.type_name in table_ok:
if kana2.type_name in table_ok[kana1.type_name]:
+
+ # early return for empty norm to empty norm
+ if kana1.type_name == kana2.type_name == 'norm' \
+ and kana1.kana is kana2.kana is None:
+ return False
+
ar_vect_ok = {
'ar_u': ( 0, -1),
'ar_l': (-1, 0),
@@ -117,7 +134,7 @@ class KanaGrid:
if kana.type_name == 'myst':
new_grid = self.copy()
new_grid.action_count += 1
- new_grid.set_kana(pos, Kana('norm', kana.kana))
+ new_grid.set_kana(pos, Kana.create('norm', kana.kana))
return new_grid
elif action_type in ('up', 'right', 'down', 'left'):
pos_map = {
@@ -130,10 +147,13 @@ class KanaGrid:
if kana.type_name == 'slim':
kana2 = self.get_kana(pos_dest)
if kana2.type_name in Kana.slime_merge_types and kana2.kana:
+ # early return for slime merging for same vowel
+ if kana2.kana[1] == kana.kana[0]:
+ return
new_grid = self.copy()
new_grid.action_count += 1
- new_kana1 = Kana('void')
- new_kana2 = Kana(
+ new_kana1 = kana_void
+ new_kana2 = Kana.create(
kana2.type_name,
kana2.kana[0] + kana.kana[0],
)
@@ -196,7 +216,10 @@ class KanaGrid:
#, highest_length_chain # easy to add if needed
def update_score(self):
- self.score, self.myst_count = self.longest_chain()
+ if not self.score:
+ # if self.score == 0 calculate the score as the score is always at
+ # the bare minimum equal to 1.
+ self.score, self.myst_count = self.longest_chain()
def get_hash(self):
data = ''.join((
@@ -221,6 +244,7 @@ class KanaGrid:
elif pos[1] < 0 or pos[1] >= self.height:
return
self.grid[pos[0]+pos[1]*self.width] = kana
+ self.score = 0
def swap_kana(self, pos1, pos2):
kana_dst = self.get_kana(pos2)
@@ -250,12 +274,10 @@ class KanaGrid:
kana_dst = self.get_kana(pos_dst)
def load(input_dict):
- grid = []
- for serialized_kana in input_dict['grid']:
- if serialized_kana[0] == 'void':
- grid.append(kana_void)
- else:
- grid.append(Kana(serialized_kana[0], serialized_kana[1]))
+ grid = [
+ Kana.create(serialized_kana[0], serialized_kana[1])
+ for serialized_kana in input_dict['grid']
+ ]
params = {
'size': input_dict['size'],
'grid': grid,
@@ -425,11 +447,12 @@ def main():
if args['--print']:
return
+ solver_start_time = int(time.time())
mtime = os.path.getmtime
cache_file = '%s.cache' % grid_fn
if os.path.exists(cache_file) and mtime(cache_file) >= mtime(grid_fn):
- print('DEBUG: USING CACHED VERSION')
+ print(f'Using cached version from {cache_file}')
with open(cache_file, 'rb') as stream:
cached_version = pickle.load(stream)
generator = get_solutions_from_cache(cached_version)
@@ -455,6 +478,15 @@ def main():
with open(cache_file, 'wb') as stream:
pickle.dump(cache_generation, stream)
+ solver_stop_time = int(time.time())
+ solver_delta_time = solver_stop_time - solver_start_time
+ hours = solver_delta_time // 3600
+ minutes = (solver_delta_time // 60) % 60
+ seconds = solver_delta_time % 60
+
+ print(f'time taken to calculate: {hours:02d}:{minutes:02d}:{seconds:02d}')
+
+
if __name__ == '__main__':
main()