|
|
@@ -81,6 +81,8 @@ class State:
|
|
|
return 0
|
|
|
|
|
|
def holes(self):
|
|
|
+ #return self.imbalance()
|
|
|
+
|
|
|
start_row = self.empty_rows()
|
|
|
score = 0
|
|
|
for col in range(COLUMNS):
|
|
|
@@ -217,7 +219,7 @@ class State:
|
|
|
if block != NOBLOCK:
|
|
|
colors.setdefault(block, []).append(i)
|
|
|
|
|
|
- return sum(dist(i, j)
|
|
|
+ return sum(dist(i, j) ** 2
|
|
|
for blocks in colors.values()
|
|
|
for i, j in combinations(blocks, 2))
|
|
|
|
|
|
@@ -232,15 +234,26 @@ class State:
|
|
|
|
|
|
return -points
|
|
|
|
|
|
+ def imbalance(self):
|
|
|
+ colsizes = tuple(self.nrows - skip
|
|
|
+ for col, skip in enumerate(self.colskip))
|
|
|
+ #if not self.colbusy(col))
|
|
|
+ mean = sum(colsizes) / len(colsizes)
|
|
|
+ return sum((size - mean) ** 2 for size in colsizes)
|
|
|
+
|
|
|
def gen_moves(self):
|
|
|
- yield self
|
|
|
+ if self.held == NOBLOCK:
|
|
|
+ yield self
|
|
|
|
|
|
- for src in self.gen_shift(not self.colbusy(self.exa)):
|
|
|
- yield from src.gen_stationary()
|
|
|
+ for src in self.gen_shift(True):
|
|
|
+ yield from src.gen_stationary()
|
|
|
|
|
|
- for get in src.gen_get():
|
|
|
- for dst in get.gen_shift(False):
|
|
|
- yield from dst.gen_put()
|
|
|
+ for get in src.gen_get():
|
|
|
+ for dst in get.gen_shift(False):
|
|
|
+ yield from dst.gen_put()
|
|
|
+ else:
|
|
|
+ for dst in self.gen_shift(True):
|
|
|
+ yield from dst.gen_put()
|
|
|
|
|
|
def gen_shift(self, allow_noshift):
|
|
|
if allow_noshift:
|
|
|
@@ -303,21 +316,11 @@ class State:
|
|
|
if avail >= 2:
|
|
|
yield swap.move(GRAB, SWAP, DROP)
|
|
|
|
|
|
- def force(self, *moves):
|
|
|
- state = self.move(*moves)
|
|
|
- state.score = ()
|
|
|
- return state
|
|
|
-
|
|
|
def solve(self):
|
|
|
assert self.exa is not None
|
|
|
|
|
|
- if self.held != NOBLOCK:
|
|
|
- return self.force(DROP)
|
|
|
-
|
|
|
pool = deque(self.gen_moves())
|
|
|
-
|
|
|
- if len(pool) == 0:
|
|
|
- return self.force()
|
|
|
+ assert len(pool) > 0
|
|
|
|
|
|
best_score = ()
|
|
|
|
|
|
@@ -333,6 +336,7 @@ class State:
|
|
|
|
|
|
for i in range(len(pool)):
|
|
|
state = pool.popleft()
|
|
|
+ assert state.held == NOBLOCK
|
|
|
if state.score == best:
|
|
|
pool.append(state)
|
|
|
|
|
|
@@ -387,6 +391,7 @@ class State:
|
|
|
def loops(self, prev):
|
|
|
return self.moves and \
|
|
|
self.exa == prev.exa and \
|
|
|
+ self.held == prev.held and \
|
|
|
self.moves == prev.moves and \
|
|
|
self.score == prev.score
|
|
|
|