Commit a8f3eb0d authored by Taddeüs Kroes's avatar Taddeüs Kroes

Refactor group updates

parent 47fcb032
...@@ -122,67 +122,65 @@ class State: ...@@ -122,67 +122,65 @@ class State:
assert row < s.nrows assert row < s.nrows
i = row * COLUMNS + s.exa i = row * COLUMNS + s.exa
if not s.locked(i): if not s.locked(i):
s.held = s.blocks[i]
s.blocks[i] = NOBLOCK
s.colskip[s.exa] += 1 s.colskip[s.exa] += 1
s.ungroup(i) s.held = s.remove(i)
elif move == DROP: elif move == DROP:
if s.held != NOBLOCK: if s.held != NOBLOCK:
row = s.colskip[s.exa] row = s.colskip[s.exa]
assert row > 0 assert row > 0
i = (row - 1) * COLUMNS + s.exa i = (row - 1) * COLUMNS + s.exa
s.blocks[i] = s.held
s.held = NOBLOCK
s.colskip[s.exa] -= 1 s.colskip[s.exa] -= 1
s.regroup(i) s.place(i, s.held)
s.held = NOBLOCK
elif move == SWAP: elif move == SWAP:
assert not s.colbusy(s.exa) assert not s.colbusy(s.exa)
row = s.colskip[s.exa] row = s.colskip[s.exa]
i = row * COLUMNS + s.exa i = row * COLUMNS + s.exa
j = i + COLUMNS j = i + COLUMNS
if j < len(s.blocks) and not s.locked(i) and not s.locked(j): if j < len(s.blocks) and not s.locked(i) and not s.locked(j):
bi = s.blocks[i] bi = s.blocks[i]
bj = s.blocks[j] bj = s.blocks[j]
assert bi != NOBLOCK
assert bj != NOBLOCK
if bi != bj: if bi != bj:
s.blocks[i] = NOBLOCK s.blocks[i] = NOBLOCK
s.blocks[j] = NOBLOCK s.blocks[j] = NOBLOCK
s.ungroup(i) visited = set()
s.ungroup(j) s.ungroup(i, visited)
s.blocks[j] = bi s.ungroup(j, visited)
s.regroup(j) s.place(j, bi)
s.blocks[i] = bj s.place(i, bj)
s.regroup(i)
return s return s
def ungroup(self, i): def remove(self, i):
block = self.blocks[i]
assert block != NOBLOCK
self.blocks[i] = NOBLOCK
self.ungroup(i, set())
return block
def ungroup(self, i, visited):
assert self.blocks[i] == NOBLOCK assert self.blocks[i] == NOBLOCK
visited = set()
oldid = self.groups[i] oldid = self.groups[i]
for nb in neighbors(i, self.blocks): for nb in neighbors(i, self.blocks):
if self.groups[nb] == oldid: if self.groups[nb] == oldid:
newgroup = self.scan_group(nb, visited) self.create_group(nb, visited)
if newgroup:
self.maxgroup = newid = self.maxgroup + 1
for j in newgroup:
self.groups[j] = newid
self.groupsizes[j] = len(newgroup)
self.groups[i] = 0 self.groups[i] = 0
self.groupsizes[i] = 0 self.groupsizes[i] = 0
def regroup(self, i): def place(self, i, block):
assert self.blocks[i] != NOBLOCK assert block != NOBLOCK
self.maxgroup = newid = self.maxgroup + 1 assert self.blocks[i] == NOBLOCK
newgroup = self.scan_group(i, set()) self.blocks[i] = block
for j in newgroup: self.create_group(i, set())
self.groups[j] = newid
self.groupsizes[j] = len(newgroup)
def scan_group(self, start, visited): def create_group(self, start, visited):
def scan(i): def scan(i):
if i not in visited: if i not in visited:
yield i yield i
...@@ -192,7 +190,12 @@ class State: ...@@ -192,7 +190,12 @@ class State:
yield from scan(nb) yield from scan(nb)
block = self.blocks[start] block = self.blocks[start]
return tuple(scan(start)) group = tuple(scan(start))
if group:
self.maxgroup = newid = self.maxgroup + 1
for j in group:
self.groups[j] = newid
self.groupsizes[j] = len(group)
def fragmentation(self): def fragmentation(self):
""" """
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment