Skip to content
Snippets Groups Projects
Commit a8f3eb0d authored by Taddeüs Kroes's avatar Taddeüs Kroes
Browse files

Refactor group updates

parent 47fcb032
No related branches found
No related tags found
No related merge requests found
...@@ -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):
""" """
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment