123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713 |
- # This uses http://games.technoplaza.net/mpg/password.txt as a basis for its password algorithm
-
- import random
-
- class MetroidState:
- def __init__(self):
- self.alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz?-"
- self.itemsCollected = {
- "Maru Mari": False,
- "Bombs": False,
- "Long Beam": False,
- "Ice Beam": False,
- "Wave Beam": False,
- "High Jump Boots": False,
- "Varia": False,
- "Screw Attack": False
- }
- self.samusHas = {
- "Maru Mari": False,
- "Bombs": False,
- "Long Beam": False,
- "Ice Beam": False,
- "Wave Beam": False,
- "High Jump Boots": False,
- "Varia": False,
- "Screw Attack": False
- }
- self.missileTanks = {
- 1: False,
- 2: False,
- 3: False,
- 4: False,
- 5: False,
- 6: False,
- 7: False,
- 8: False,
- 9: False,
- 10: False,
- 11: False,
- 12: False,
- 13: False,
- 14: False,
- 15: False,
- 16: False,
- 17: False,
- 18: False,
- 19: False,
- 20: False,
- 21: False
- }
- self.energyTanks = {
- 1: False,
- 2: False,
- 3: False,
- 4: False,
- 5: False,
- 6: False,
- 7: False,
- 8: False
- }
- self.zebetitesDestroyed = {
- 1: False,
- 2: False,
- 3: False,
- 4: False,
- 5: False
- }
- self.doors = {
- "Brinstar": {
- 1: False,
- 2: False,
- 3: False,
- 4: False,
- 5: False
- }, "Norfair": {
- 1: False,
- 2: False,
- 3: False,
- 4: False
- }, "Kraid": {
- 1: False,
- 2: False,
- 3: False,
- 4: False,
- 5: False
- }, "Ridley": {
- 1: False,
- 2: False
- }, "Tourian": {
- 1: False,
- 2: False,
- 3: False
- }
- }
- self.kraidKilled = False
- self.ridleyKilled = False
- self.motherBrainKilled = False
- self.kraidStatue = False
- self.ridleyStatue = False
- self.swimsuit = False
- self.missileCount = 0
- self.gameAge = 0
- self.locations = ["Brinstar", "Norfair", "Kraid's Lair", "Ridley's Lair", "Tourian"]
- self.startLocation = 0
- self.bitfield = []
-
- def initializeBitfield(self):
- self.bitfield = []
- for _ in range(128):
- self.bitfield.append(0)
-
- def toggleItem(self, itm):
- if itm in self.itemsCollected.keys():
- self.itemsCollected[itm] = not self.itemsCollected[itm]
- self.samusHas[itm] = not self.samusHas[itm]
- else:
- print("Couldn't find item: {}".format(str(itm)))
-
- def toggleMissileTank(self, num):
- try:
- num = int(num)
- except:
- print("{} is not a number".format(num))
- return
- if num in self.missileTanks.keys():
- self.missileTanks[num] = not self.missileTanks[num]
- else:
- print("Couldn't find missile tank: {}".format(num))
-
- def toggleEnergyTank(self, num):
- try:
- num = int(num)
- except:
- print("{} is not a number".format(num))
- return
- if num in self.energyTanks.keys():
- self.energyTanks[num] = not self.energyTanks[num]
- else:
- print("Couldn't find energy tank: {}".format(num))
-
- def toggleZebetite(self, num):
- try:
- num = int(num)
- except:
- print("{} is not a number".format(num))
- return
- if num in self.zebetitesDestroyed.keys():
- self.zebetitesDestroyed[num] = not self.zebetitesDestroyed[num]
- else:
- print("Couldn't find Zebetite: {}".format(num))
-
- def toggleKraid(self):
- self.kraidKilled = not self.kraidKilled
- self.kraidStatue = self.kraidKilled
-
- def toggleKraidStatue(self):
- self.kraidStatue = not self.kraidStatue
- if self.kraidKilled and not self.kraidStatue:
- print("WARNING: Kraid has been killed but his statue has not been raised.")
-
- def toggleRidley(self):
- self.ridleyKilled = not self.ridleyKilled
- self.ridleyStatue = self.ridleyKilled
-
- def toggleRidleyStatue(self):
- self.ridleyStatue = not self.ridleyStatue
- if self.ridleyKilled and not self.ridleyStatue:
- print("WARNING: Ridley has been killed but his statue has not been raised.")
-
- def toggleMotherBrain(self):
- self.motherBrainKilled = not self.motherBrainKilled
-
- def toggleDoor(self, area, door):
- try:
- area = str(area)
- door = int(door)
- except:
- print("Area must be string, door must be a positive integer")
- return
- if area in self.doors.keys() and int(door) in self.doors[area].keys():
- self.doors[area][door] = not self.doors[area][door]
- else:
- print("Couldn't find door {} in area {}".format(door, area))
-
- def toggleSwimsuit(self):
- self.swimsuit = not self.swimsuit
-
- def newLocation(self, loc):
- try:
- loc = str(loc)
- except:
- print("Location must be a string")
- return
- if loc in self.locations:
- self.startLocation = self.locations.index(loc)
- else:
- print("Couldn't find location: {}".format(loc))
-
- def collectedItems(self):
- o = []
- for k,v in self.itemsCollected.items():
- if v == True:
- o.append(k)
- if len(o) == 0:
- return "None"
- else:
- return ", ".join(o)
-
- def collectedMissiles(self):
- o = []
- for k, v in self.missileTanks.items():
- if v == True:
- o.append(k)
- if len(o) == 0:
- return "None"
- else:
- return ", ".join([str(b) for b in o])
-
- def collectedEtanks(self):
- o = []
- for k, v in self.energyTanks.items():
- if v == True:
- o.append(k)
- if len(o) == 0:
- return "None"
- else:
- return ", ".join([str(b) for b in o])
-
- def killedZebetites(self):
- o = []
- for k, v in self.zebetitesDestroyed.items():
- if v == True:
- o.append(k)
- if len(o) == 0:
- return "None"
- else:
- return ", ".join([str(b) for b in o])
-
- def killedBosses(self):
- o = []
- if self.kraidKilled:
- o.append("Kraid")
- if self.ridleyKilled:
- o.append("Ridley")
- if self.motherBrainKilled:
- o.append("Mother Brain")
- if len(o) == 0:
- return "None"
- else:
- return ", ".join(o)
-
- def raisedStatues(self):
- o = []
- if self.kraidStatue:
- o.append("Kraid")
- if self.ridleyStatue:
- o.append("Ridley")
- if len(o) == 0:
- return "None"
- else:
- return ", ".join(o)
-
- def inBailey(self):
- if self.swimsuit:
- return "Yes"
- else:
- return "No"
-
- def openedDoors(self):
- d = {"Brinstar": 0, "Norfair": 0, "Kraid": 0, "Ridley": 0, "Tourian": 0}
- o = []
- for k,v in self.doors["Brinstar"].items():
- if v == True:
- d["Brinstar"] = d["Brinstar"] + 1
- for k,v in self.doors["Norfair"].items():
- if v == True:
- d["Norfair"] = d["Norfair"] + 1
- for k,v in self.doors["Kraid"].items():
- if v == True:
- d["Kraid"] = d["Kraid"] + 1
- for k,v in self.doors["Ridley"].items():
- if v == True:
- d["Ridley"] = d["Ridley"] + 1
- for k,v in self.doors["Tourian"].items():
- if v == True:
- d["Tourian"] = d["Tourian"] + 1
- for k, v in d.items():
- o.append("{} {}".format(k, v))
- return ", ".join(o)
-
- def getBits(self):
- o = []
- word = []
- for i in range(128):
- word.append(str(self.bitfield[i]))
- if len(word) == 8:
- o.append("".join(word))
- word = []
- o1 = " ".join(o[:8])
- o2 = " ".join(o[8:])
- return o1 + "\n" + o2
-
- def toString(self):
- ic = "Items Collected: {}".format(self.collectedItems())
- mt = "Missile Tanks Collected: {}".format(self.collectedMissiles())
- et = "Energy Tanks Collected: {}".format(self.collectedEtanks())
- zb = "Zebetites Killed: {}".format(self.killedZebetites())
- kb = "Bosses Killed: {}".format(self.killedBosses())
- rs = "Statues Raised: {}".format(self.raisedStatues())
- sw = "Swimsuit?: {}".format(self.inBailey())
- sl = "Start Location: {}".format(self.locations[self.startLocation])
- dr = "Unlocked Doors: {}".format(self.openedDoors())
- ms = "Missiles: {}".format(self.missileCount)
- bf = "Bitfield:\n{}".format(self.getBits())
- return "\n".join([ic, mt, et, zb, kb, rs, sw, sl, dr, ms, bf])
-
- def randomize(self):
- # Items
- if random.randint(0,1) == 1:
- self.toggleItem("Maru Mari")
- if random.randint(0,1) == 1:
- self.toggleItem("Bombs")
- if random.randint(0,1) == 1:
- self.toggleItem("Varia")
- if random.randint(0,1) == 1:
- self.toggleItem("High Jump Boots")
- if random.randint(0,1) == 1:
- self.toggleItem("Screw Attack")
- if random.randint(0,1) == 1:
- self.toggleItem("Long Beam")
- beam = random.randint(0,2)
- if beam == 1:
- self.toggleItem("Ice Beam")
- elif beam == 2:
- self.toggleItem("Wave Beam")
- # Missile Tanks
- for i in range(21):
- if random.randint(0,1) == 1:
- self.toggleMissileTank(i+1)
- # Energy Tanks
- for i in range(8):
- if random.randint(0,1) == 1:
- self.toggleEnergyTank(i+1)
- # Zebetites
- for i in range(5):
- if random.randint(0,1) == 1:
- self.toggleZebetite(i+1)
- # Bosses killed
- if random.randint(0,1) == 1:
- self.toggleKraid()
- if random.randint(0,1) == 1:
- self.toggleRidley()
- if random.randint(0,1) == 1:
- self.toggleMotherBrain()
- # Statues raised
- if not self.kraidKilled and random.randint(0,1) == 1:
- self.toggleKraidStatue()
- if not self.ridleyKilled and random.randint(0,1) == 1:
- self.toggleRidleyStatue()
- # Doors
- # Brinstar 5, Norfair 4, Kraid 5, Ridley 2, Tourian 3
- for i in range(5):
- if random.randint(0,1) == 1:
- self.doors["Brinstar"][i+1] = True
- for i in range(4):
- if random.randint(0,1) == 1:
- self.doors["Norfair"][i+1] = True
- for i in range(5):
- if random.randint(0,1) == 1:
- self.doors["Kraid"][i+1] = True
- for i in range(2):
- if random.randint(0,1) == 1:
- self.doors["Ridley"][i+1] = True
- for i in range(3):
- if random.randint(0,1) == 1:
- self.doors["Tourian"][i+1] = True
- # Swimsuit
- if random.randint(0,2) == 2:
- self.toggleSwimsuit()
- # Start Location
- self.startLocation = random.randint(0,4)
- self.missileCount = random.randint(0,255)
-
- def createBitfield(self):
- self.initializeBitfield()
- # Doing this in order, which is dumb and tedious but accurate.
- if self.itemsCollected["Maru Mari"]:
- self.bitfield[0] = 1
- if self.missileTanks[1]:
- self.bitfield[1] = 1
- if self.doors["Brinstar"][1]:
- self.bitfield[2] = 1
- if self.doors["Brinstar"][2]:
- self.bitfield[3] = 1
- if self.energyTanks[1]:
- self.bitfield[4] = 1
- if self.doors["Brinstar"][3]:
- self.bitfield[5] = 1
- if self.itemsCollected["Bombs"]:
- self.bitfield[6] = 1
- if self.doors["Brinstar"][4]:
- self.bitfield[7] = 1
- if self.missileTanks[2]:
- self.bitfield[8] = 1
- if self.energyTanks[2]:
- self.bitfield[9] = 1
- if self.doors["Brinstar"][5]:
- self.bitfield[10] = 1
- if self.itemsCollected["Varia"]:
- self.bitfield[11] = 1
- if self.energyTanks[3]:
- self.bitfield[12] = 1
- if self.missileTanks[3]:
- self.bitfield[13] = 1
- if self.missileTanks[4]:
- self.bitfield[14] = 1
- if self.doors["Norfair"][1]:
- self.bitfield[15] = 1
- if self.missileTanks[5]:
- self.bitfield[16] = 1
- if self.missileTanks[6]:
- self.bitfield[17] = 1
- if self.missileTanks[7]:
- self.bitfield[18] = 1
- if self.missileTanks[8]:
- self.bitfield[19] = 1
- if self.missileTanks[9]:
- self.bitfield[20] = 1
- if self.missileTanks[10]:
- self.bitfield[21] = 1
- if self.missileTanks[11]:
- self.bitfield[22] = 1
- if self.doors["Norfair"][2]:
- self.bitfield[23] = 1
- if self.itemsCollected["High Jump Boots"]:
- self.bitfield[24] = 1
- if self.doors["Norfair"][3]:
- self.bitfield[25] = 1
- if self.itemsCollected["Screw Attack"]:
- self.bitfield[26] = 1
- if self.missileTanks[12]:
- self.bitfield[27] = 1
- if self.missileTanks[13]:
- self.bitfield[28] = 1
- if self.doors["Norfair"][4]:
- self.bitfield[29] = 1
- if self.energyTanks[4]:
- self.bitfield[30] = 1
- if self.missileTanks[14]:
- self.bitfield[31] = 1
- if self.doors["Kraid"][1]:
- self.bitfield[32] = 1
- if self.missileTanks[15]:
- self.bitfield[33] = 1
- if self.missileTanks[16]:
- self.bitfield[34] = 1
- if self.doors["Kraid"][2]:
- self.bitfield[35] = 1
- if self.energyTanks[5]:
- self.bitfield[36] = 1
- if self.doors["Kraid"][3]:
- self.bitfield[37] = 1
- if self.doors["Kraid"][4]:
- self.bitfield[38] = 1
- if self.missileTanks[17]:
- self.bitfield[39] = 1
- if self.missileTanks[18]:
- self.bitfield[40] = 1
- if self.doors["Kraid"][5]:
- self.bitfield[41] = 1
- if self.energyTanks[6]:
- self.bitfield[42] = 1
- if self.missileTanks[19]:
- self.bitfield[43] = 1
- if self.doors["Ridley"][1]:
- self.bitfield[44] = 1
- if self.energyTanks[7]:
- self.bitfield[45] = 1
- if self.missileTanks[20]:
- self.bitfield[46] = 1
- if self.doors["Ridley"][2]:
- self.bitfield[47] = 1
- if self.energyTanks[8]:
- self.bitfield[48] = 1
- if self.missileTanks[21]:
- self.bitfield[49] = 1
- if self.doors["Tourian"][1]:
- self.bitfield[50] = 1
- if self.doors["Tourian"][2]:
- self.bitfield[51] = 1
- if self.doors["Tourian"][3]:
- self.bitfield[52] = 1
- if self.zebetitesDestroyed[1]:
- self.bitfield[53] = 1
- if self.zebetitesDestroyed[2]:
- self.bitfield[54] = 1
- if self.zebetitesDestroyed[3]:
- self.bitfield[55] = 1
- if self.zebetitesDestroyed[4]:
- self.bitfield[56] = 1
- if self.zebetitesDestroyed[5]:
- self.bitfield[57] = 1
- if self.motherBrainKilled:
- self.bitfield[58] = 1
- # 59-63 unknown
- # if self.:
- # self.bitfield[59] = 1
- # if self.:
- # self.bitfield[60] = 1
- # if self.:
- # self.bitfield[61] = 1
- # if self.:
- # self.bitfield[62] = 1
- # if self.:
- # self.bitfield[63] = 1
- # not 64, 65, or 66 = Brinstar
- # 64 = Norfair
- # 65 and not 66 = Kraid's Lair
- # 66 and not 65 = Ridley's Lair
- # 65 and 66 = Tourian
- if self.startLocation == 1:
- self.bitfield[64] = 1
- if self.startLocation == 2 or self.startLocation == 4:
- self.bitfield[65] = 1
- if self.startLocation == 3 or self.startLocation == 4:
- self.bitfield[66] = 1
- # 67 is the reset bit, I want all passwords to be valid
- # if self.:
- # self.bitfield[67] = 1
- # 68-70 are unknown
- # if self.:
- # self.bitfield[68] = 1
- # if self.:
- # self.bitfield[69] = 1
- # if self.:
- # self.bitfield[70] = 1
- if self.swimsuit:
- self.bitfield[71] = 1
- if self.samusHas["Bombs"]:
- self.bitfield[72] = 1
- if self.samusHas["High Jump Boots"]:
- self.bitfield[73] = 1
- if self.samusHas["Long Beam"]:
- self.bitfield[74] = 1
- if self.samusHas["Screw Attack"]:
- self.bitfield[75] = 1
- if self.samusHas["Maru Mari"]:
- self.bitfield[76] = 1
- if self.samusHas["Varia"]:
- self.bitfield[77] = 1
- if self.samusHas["Wave Beam"]:
- self.bitfield[78] = 1
- if self.samusHas["Ice Beam"]:
- self.bitfield[79] = 1
- # Missile count
- # +2^n from 0 to 7
- binMissiles = bin(self.missileCount).replace('0b','')[::-1]
- while len(binMissiles) < 8:
- binMissiles += "0"
- if int(binMissiles[0]) == 1:
- self.bitfield[80] = 1
- if int(binMissiles[1]) == 1:
- self.bitfield[81] = 1
- if int(binMissiles[2]) == 1:
- self.bitfield[82] = 1
- if int(binMissiles[3]) == 1:
- self.bitfield[83] = 1
- if int(binMissiles[4]) == 1:
- self.bitfield[84] = 1
- if int(binMissiles[5]) == 1:
- self.bitfield[85] = 1
- if int(binMissiles[6]) == 1:
- self.bitfield[86] = 1
- if int(binMissiles[7]) == 1:
- self.bitfield[87] = 1
- # 88-119 are game age, leaving at 0
- # if self.:
- # self.bitfield[88] = 1
- # if self.:
- # self.bitfield[89] = 1
- # if self.:
- # self.bitfield[90] = 1
- # if self.:
- # self.bitfield[91] = 1
- # if self.:
- # self.bitfield[92] = 1
- # if self.:
- # self.bitfield[93] = 1
- # if self.:
- # self.bitfield[94] = 1
- # if self.:
- # self.bitfield[95] = 1
- # if self.:
- # self.bitfield[96] = 1
- # if self.:
- # self.bitfield[97] = 1
- # if self.:
- # self.bitfield[98] = 1
- # if self.:
- # self.bitfield[99] = 1
- # if self.:
- # self.bitfield[100] = 1
- # if self.:
- # self.bitfield[101] = 1
- # if self.:
- # self.bitfield[102] = 1
- # if self.:
- # self.bitfield[103] = 1
- # if self.:
- # self.bitfield[104] = 1
- # if self.:
- # self.bitfield[105] = 1
- # if self.:
- # self.bitfield[106] = 1
- # if self.:
- # self.bitfield[107] = 1
- # if self.:
- # self.bitfield[108] = 1
- # if self.:
- # self.bitfield[109] = 1
- # if self.:
- # self.bitfield[110] = 1
- # if self.:
- # self.bitfield[111] = 1
- # if self.:
- # self.bitfield[112] = 1
- # if self.:
- # self.bitfield[113] = 1
- # if self.:
- # self.bitfield[114] = 1
- # if self.:
- # self.bitfield[115] = 1
- # if self.:
- # self.bitfield[116] = 1
- # if self.:
- # self.bitfield[117] = 1
- # if self.:
- # self.bitfield[118] = 1
- # if self.:
- # self.bitfield[119] = 1
- # 120-123 are unknown
- # if self.:
- # self.bitfield[120] = 1
- # if self.:
- # self.bitfield[121] = 1
- # if self.:
- # self.bitfield[122] = 1
- # if self.:
- # self.bitfield[123] = 1
- if self.ridleyKilled:
- self.bitfield[124] = 1
- if self.ridleyStatue:
- self.bitfield[125] = 1
- if self.kraidKilled:
- self.bitfield[126] = 1
- if self.kraidStatue:
- self.bitfield[127] = 1
-
- def generatePassword(self):
- # not gonna do the bit-shifting yet
- # shiftbit = random.randint(0,7)
- bitfield = self.bitfield
- # for _ in range(shiftbit):
- # [bitfield[127]] + bitfield[:127]
- # binShift = bin(shiftbit).replace('0b','')
- # while len(binShift) < 8:
- # binShift = "0" + binShift
- # for bit in binShift:
- # bitfield.append(int(bit))
- bitfield = bitfield + [0,0,0,0,0,0,0,0]
- # checking = []
- # for i in range(16):
- # checking.append(int("".join([str(x) for x in bitfield[i:i+8]]), 2))
- decChecksum = sum(bitfield)
- binChecksum = bin(decChecksum).replace('0b','')
- checksum = binChecksum[-8:]
- while len(checksum) < 8:
- checksum = checksum + "0"
- print(checksum)
- for bit in checksum:
- bitfield.append(int(bit))
- print("Full Bitfield: {}".format("".join([str(x) for x in bitfield])))
- print(len(bitfield))
- letters = []
- letter = []
- for bit in bitfield:
- letter.append(str(bit))
- if len(letter) == 6:
- print(letter)
- letters.append(self.alphabet[int("".join(letter),2)])
- letter = []
- print(letters)
- words = []
- word = []
- print(letters)
- print(len(letters))
- for lt in letters:
- word.append(lt)
- if len(word) == 6:
- words.append("".join(word))
- word = []
- words.append("".join(word))
- return " ".join(words)
-
- def main():
- gs = MetroidState()
- gs.randomize()
- gs.createBitfield()
- print(gs.toString())
- print(gs.generatePassword())
-
- if __name__ == "__main__":
- main()
|