Created
December 25, 2020 15:55
-
-
Save mousetail/7947d60ad75af60facb5241d2a2e88cd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Multiset(): | |
def __init__(self, name): | |
self.name = name | |
self.fixed_items = {} | |
self.nrof_items = 0 | |
def add(self, item): | |
self.fixed_items[item] = self.fixed_items.get(item, 0)+1 | |
self.nrof_items+=1 | |
def remove(self, item): | |
if self.fixed_items.get(item, 0) > 0: | |
self.fixed_items[item] -= 1 | |
self.nrof_items-=1 | |
return True | |
return False | |
#def transfer(self, other): | |
# pass | |
class SetSystem(): | |
def __init__(self, set_names=[]): | |
self.sets = {name: Multiset(name) for name in set_names} | |
self.variables = {} | |
self.variable_numbers = {} | |
self.logfile = open("setsystem_log.py", "w") | |
def add(self, name, value): | |
self.logfile.write(f"t.add({repr(name)}, {repr(value)})\n") | |
if name not in self.sets: | |
self.sets[name] = Multiset(name) | |
self.sets[name].add(value) | |
#if not value in variables: | |
# variables[value]=[] | |
#variables[value].append(name) | |
def remove(self, group, resource): | |
self.logfile.write(f"t.remove({repr(group)}, {repr(resource)})\n") | |
if not self.sets[group].remove(resource): | |
self.sets[group].nrof_items-=1 | |
if group in self.variables[resource]: | |
#print("number in vnums", self.variable_numbers[resource], "in res", self.variables[resource][group]) | |
self.variable_numbers[resource]-=1 | |
if (self.variable_numbers[resource]<0): | |
print("Huge problem: ",self.variable_numbers[resource],"floating variables") | |
self.logfile.write(f"# error with negative floating variables, variable: {resource} amount: {self.variable_numbers[resource]}\n") | |
self.variables[resource][group]-=1 | |
if self.variables[resource][group]==0: | |
del self.variables[resource][group] | |
else: | |
raise ValueError("trying to remove a item from a set that can't possibly contain it") | |
self.consolidate() | |
def transfer(self, name1, name2): | |
self.logfile.write(f"t.transfer({repr(name1)}, {repr(name2)})\n") | |
if name2 not in self.sets: | |
self.sets[name2]=Multiset(name2) | |
possible_values = set() | |
for key, value in self.sets[name1].fixed_items.items(): | |
if value!=0: | |
self.sets[name1].fixed_items[key]-=1 | |
self.variable_numbers[key]=self.variable_numbers.get(value, 0)+1 | |
possible_values.add(key) | |
for resource, value_map in self.variables.items(): | |
if value_map.get(name1,0)>0: | |
self.variables[resource][name2]=self.variables[resource].get(name2,0)+1 | |
self.sets[name1].nrof_items-=1 | |
self.sets[name2].nrof_items+=1 | |
for value in possible_values: | |
if value not in self.variables: | |
self.variables[value]={} | |
if name1 not in self.variables[value]: | |
self.variables[value][name1]=0 | |
if name2 not in self.variables[value]: | |
self.variables[value][name2]=0 | |
self.variables[value][name2]+=1 | |
self.variables[value][name1]+=1 | |
self.consolidate() | |
#for | |
def consolidate(self): | |
#print() | |
#self.print_system() | |
self.consolidate_setwise() | |
#print() | |
#self.print_system() | |
#self.consolidate_itemwise() | |
print() | |
self.logfile.flush() | |
def consolidate_itemwise(self): | |
for resource, amount in self.variable_numbers.items(): | |
t = self.variables[resource] | |
total_slots = sum(value for value in t.values()) | |
holes = total_slots - amount | |
#print(self.variables[resource]) | |
#print("resource", resource, "holes", holes, "total_slots", total_slots, "amount", amount) | |
for group, max_amount in t.items(): | |
if max_amount>holes: | |
diff = max_amount-holes | |
#print("diff: ", diff) | |
self.sets[group].fixed_items[resource]=self.sets[group].fixed_items.get(resource, 0)+diff | |
self.variables[resource][group]-=diff | |
self.variable_numbers[resource]-=diff | |
if (self.variable_numbers[resource]<0): | |
print("Huge problem: ",self.variable_numbers[resource],"floating variables") | |
self.logfile.write(f"# error with negative floating variables, variable: {resource} amount: {self.variable_numbers[resource]}\n") | |
def consolidate_setwise(self): | |
for key, s in self.sets.items(): | |
guarenteed_length = sum(i[1] for i in s.fixed_items.items()) | |
delta_length = s.nrof_items - guarenteed_length | |
optional_length = sum(var[key] for val, var in self.variables.items() if var.get(key,0)>0) | |
#print(key, optional_length, delta_length) | |
if delta_length < 0: | |
print("things are even more broken") | |
self.logfile.write(f"#broken from here (delta_length={delta_length} key={key})\n") | |
self.broken = True | |
if delta_length > optional_length: | |
print("Everything is broken: ", delta_length, optional_length) | |
print() | |
print() | |
return | |
if delta_length == optional_length and delta_length!=0: | |
dt = [(val, var[key]) for val, var in self.variables.items() if var[key]>0] | |
for val, amount in dt: | |
self.sets[key].fixed_items[val]=self.sets[key].fixed_items.get(val, 0)+amount | |
self.variables[val][key]-=amount | |
self.variable_numbers[val]-=amount | |
elif optional_length>0: | |
for resource, amount_map in self.variables.items(): | |
if amount_map.get(key,0)>0: | |
self.variables[resource][key]=min(self.variables[resource][key], delta_length, self.variable_numbers[resource]) | |
def print_system(self): | |
for key, s in self.sets.items(): | |
print(str(key) + " #"+str(s.nrof_items)+"") | |
print("\t"+"\t".join(str(num)+":"+str(value) for num, value in s.fixed_items.items() if value!=0)) | |
length = sum(i[1] for i in s.fixed_items.items()) | |
if length<s.nrof_items: | |
print("\t+",s.nrof_items - length,"of"," or ".join(str(var) for var, val in self.variables.items() if val.get(key, 0)>0)) | |
print("total loose variables: ", ",".join(f"{key}:{value}" for key, value in self.variable_numbers.items())) | |
#for variable | |
if __name__=="__main__": | |
t = SetSystem() | |
CASE = 6 | |
if CASE==1: | |
t.add('red', 'wheat') | |
t.add('red', 'sheap') | |
t.add('red', 'sheap') | |
#t.print_system() | |
t.transfer('red','green') | |
t.remove('green', 'wheat') | |
elif CASE==2: | |
t.add('red', 'wheat') | |
t.add('red', 'sheap') | |
t.transfer('red', 'green') | |
t.transfer('red', 'blue') | |
t.remove('blue', 'sheap') | |
elif CASE==3: | |
for i in range(5): | |
t.add('red', 'wheat') | |
t.add('red', 'brick') | |
t.add('green', 'wheat') | |
t.transfer('red', 'green') | |
t.remove('green', 'wheat') | |
t.transfer('green', 'blue') | |
elif CASE==4: | |
t.add('red', 'sheep') | |
for i in range(10): | |
t.add('red', 'brick') | |
t.add('green', 'brick') | |
t.add('blue', 'brick') | |
t.transfer('red', 'green') | |
t.transfer('green', 'blue') | |
for i in range(9): | |
t.remove('red', 'brick') | |
t.remove('green', 'brick') | |
t.remove('blue', 'brick') | |
elif CASE==5: | |
t.add(5, 4) | |
t.add(5, 3) | |
t.add(1, 4) | |
t.add(1, 1) | |
t.add(1, 4) | |
t.add(2, 5) | |
t.add(2, 4) | |
t.add(2, 5) | |
t.add(3, 1) | |
t.add(3, 2) | |
t.add(3, 2) | |
t.add(1, 2) | |
t.add(3, 3) | |
t.add(2, 3) | |
t.remove(3, 1) | |
t.remove(3, 2) | |
t.add(2, 5) | |
t.add(2, 3) | |
t.add(5, 3) | |
t.remove(1, 1) | |
t.remove(1, 2) | |
t.add(5, 3) | |
t.remove(3, 3) | |
t.add(2, 3) | |
t.remove(5, 3) | |
t.remove(2, 3) | |
t.remove(2, 4) | |
t.remove(2, 5) | |
t.add(1, 2) | |
t.add(3, 3) | |
t.add(2, 3) | |
t.add(1, 2) | |
t.add(3, 3) | |
t.add(2, 3) | |
t.transfer(1, 2) | |
t.add(5, 3) | |
t.add(1, 1) | |
t.add(3, 1) | |
t.add(2, 4) | |
t.add(2, 5) | |
t.add(1, 5) | |
t.add(2, 4) | |
t.remove(1, 4) | |
t.add(1, 3) | |
t.remove(2, 3) | |
t.remove(1, 1) | |
t.remove(1, 2) | |
t.remove(1, 3) | |
t.remove(1, 4) | |
t.add(5, 1) | |
t.add(5, 1) | |
t.remove(2, 4) | |
t.remove(2, 4) | |
t.remove(2, 5) | |
t.remove(2, 5) | |
t.remove(2, 5) | |
t.add(2, 4) | |
t.add(1, 4) | |
t.add(2, 4) | |
t.add(2, 4) | |
t.add(1, 5) | |
t.add(2, 5) | |
t.add(1, 5) | |
t.add(3, 5) | |
t.remove(1, 5) | |
t.add(1, 3) | |
t.remove(3, 3) | |
t.remove(2, 3) | |
t.remove(2, 3) | |
t.remove(2, 4) | |
t.remove(2, 5) | |
t.add(5, 1) | |
t.remove(3, 1) | |
t.add(2, 1) | |
t.add(2, 1) | |
t.remove(5, 1) | |
t.remove(5, 1) | |
t.add(5, 2) | |
t.remove(2, 2) | |
t.remove(5, 1) | |
t.remove(5, 2) | |
t.add(5, 4) | |
t.add(3, 4) | |
t.add(3, 2) | |
t.add(5, 2) | |
t.add(3, 1) | |
t.remove(2, 1) | |
t.add(2, 2) | |
t.remove(3, 2) | |
t.remove(2, 1) | |
t.remove(2, 2) | |
t.add(1, 2) | |
t.add(3, 3) | |
t.add(2, 3) | |
t.add(2, 3) | |
t.remove(3, 1) | |
t.remove(3, 2) | |
t.remove(3, 3) | |
t.remove(3, 4) | |
t.transfer(2, 1) | |
t.add(1, 2) | |
t.remove(5, 4) | |
t.remove(5, 4) | |
t.add(5, 1) | |
t.remove(5, 1) | |
t.remove(5, 2) | |
t.add(2, 5) | |
t.add(2, 3) | |
t.add(2, 3) | |
t.add(5, 3) | |
t.remove(1, 3) | |
t.remove(1, 4) | |
t.remove(1, 5) | |
t.add(2, 4) | |
t.add(1, 4) | |
t.remove(2, 3) | |
t.remove(2, 4) | |
t.remove(2, 5) | |
t.add(5, 3) | |
t.add(1, 1) | |
t.add(3, 1) | |
t.add(2, 4) | |
t.add(1, 4) | |
t.remove(1, 1) | |
t.remove(1, 2) | |
t.add(5, 2) | |
t.remove(1, 2) | |
t.add(1, 3) | |
t.remove(5, 3) | |
t.add(5, 3) | |
t.add(1, 1) | |
t.add(3, 1) | |
t.add(1, 3) | |
t.remove(5, 3) | |
t.add(5, 4) | |
t.remove(1, 4) | |
t.add(1, 3) | |
t.add(1, 3) | |
t.remove(5, 3) | |
t.remove(5, 3) | |
t.add(5, 1) | |
t.remove(1, 1) | |
t.remove(5, 1) | |
t.remove(5, 2) | |
t.remove(5, 3) | |
t.remove(5, 4) | |
t.add(1, 4) | |
t.add(3, 2) | |
t.add(2, 1) | |
t.add(2, 2) | |
t.remove(2, 1) | |
t.remove(2, 2) | |
t.remove(2, 3) | |
t.remove(2, 4) | |
t.add(1, 2) | |
t.remove(3, 1) | |
t.remove(3, 2) | |
t.add(1, 2) | |
t.remove(1, 3) | |
t.remove(1, 4) | |
t.remove(1, 5) | |
t.remove(1, 3) | |
t.remove(1, 3) | |
t.remove(1, 3) | |
t.add(1, 1) | |
t.remove(1, 1) | |
t.remove(1, 2) | |
t.add(5, 1) | |
t.add(1, 1) | |
t.add(3, 1) | |
#t.transfer(1, 2) | |
#t.transfer(2, 3) | |
#t.transfer(2, 1) | |
#t.add(1, 2) | |
#t.transfer(1, 2) | |
#t.add(3, 2) | |
#t.remove(2, 2) | |
#t.add(2, 5) | |
#t.remove(3, 5) | |
#t.add(1, 2) | |
#t.add(3, 3) | |
#t.add(2, 3) | |
#t.add(2, 3) | |
#t.remove(3, 1) | |
#t.remove(3, 2) | |
#t.add(3, 5) | |
#t.remove(1, 1) | |
elif CASE==6: | |
t.add(1,4) | |
t.add(1,3) | |
t.transfer(1,2) | |
#t.add(5,1) | |
#t.add(5,3) | |
t.add(1, 4) | |
t.add(1, 1) | |
t.add(1, 2) | |
t.add(2, 4) | |
t.add(2, 3) | |
t.add(2, 3) | |
#t.add(3, 1) | |
#t.add(3, 1) | |
#t.add(3, 3) | |
#t.add(3, 5) | |
print("final transfer") | |
t.print_system() | |
t.transfer(1,2) | |
#t.transfer('red','green') | |
t.print_system() | |
t.logfile.close() |
@fdharamshi I purposefully didn't want to share the code that actually let you cheat. It also wouldn't work anymore because Colonist has updated a lot since. However, it should be fairly easy to rebuild. Basically it just assigned a wrapper around the WebSocket
class so that it would also forward all messages to the flask server. Some basic trial and error should allow you to figure out what the messages mean.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Would you be able to share the greasemonkey script and the python code for the server as well?
I have a different approach to this and want to give it a shot!