Skip to content

Instantly share code, notes, and snippets.

@DUznanski
Created July 13, 2018 17:26
Show Gist options
  • Save DUznanski/d777f145f5ede28ebc0a266c5e19ee2e to your computer and use it in GitHub Desktop.
Save DUznanski/d777f145f5ede28ebc0a266c5e19ee2e to your computer and use it in GitHub Desktop.
Magic the Gathering faction list generator
def check_faction_set_validity(factions):
# count the number of on bits in each position for our list of faction IDs. If they're all the same, then the faction list is valid.
return factions and len({sum((faction >> k) & 1 for faction in factions) for k in range(5)}) == 1
def faction_string(faction):
return ''.join('WUBRG'[i] for i in range(5) if (faction >> i) & 1)
def faction_list_string(factions):
return ','.join(faction_string(faction) for faction in factions)
def faction_set(faction_group_id):
return {i for i,k in enumerate(reversed(bin(faction_group_id)[2:])) if k == '1'}
def check_validity(faction_group_id):
return check_faction_set_validity(faction_set(faction_group_id))
def number_from_bitset(bits):
return sum(1 << k for k in bits)
alternates = []
for shift in range(5):
alternate_list = []
reversed_alternate_list = []
for faction_group_id in range(32):
bits = '{:05b}'.format(faction_group_id)
shifted_bits = bits[shift:] + bits[:shift]
new_number = int(shifted_bits,2)
new_reversed = int(''.join(reversed(shifted_bits)),2)
alternate_list.append(new_number)
reversed_alternate_list.append(new_reversed)
alternates.append(alternate_list)
alternates.append(reversed_alternate_list)
print('\n'.join(' '.join(str(k) for k in alternate) for alternate in alternates))
primitive_groups = set()
faction_itinerary = [0]
for next_faction_id in range(32):
print(next_faction_id, len(faction_itinerary))
next_faction = 1 << next_faction_id
factions_to_test = [group + next_faction for group in faction_itinerary]
for faction_group_id in factions_to_test:
if any(faction_group_id & primitive == primitive for primitive in primitive_groups):
pass
elif check_validity(faction_group_id):
primitive_groups.add(faction_group_id)
else:
faction_itinerary.append(faction_group_id)
canonical_primitive_groups = set()
for primitive_group in primitive_groups:
group_elements = faction_set(primitive_group)
canonical_group = min(number_from_bitset(alternate[k] for k in group_elements) for alternate in alternates)
print(primitive_group, canonical_group)
canonical_primitive_groups.add(canonical_group)
print(canonical_primitive_groups)
for cpg in canonical_primitive_groups:
print(hex(cpg), faction_list_string(faction_set(cpg)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment