A save state/password generator for the original Metroid.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

metroidgen.py 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  1. # This uses http://games.technoplaza.net/mpg/password.txt as a basis for its password algorithm
  2. import random, sys
  3. class MetroidState:
  4. def __init__(self):
  5. self.alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz?-"
  6. self.itemsCollected = {
  7. "Maru Mari": False,
  8. "Bombs": False,
  9. "Long Beam": False,
  10. "Ice Beam": False,
  11. "Wave Beam": False,
  12. "High Jump Boots": False,
  13. "Varia": False,
  14. "Screw Attack": False
  15. }
  16. self.samusHas = {
  17. "Maru Mari": False,
  18. "Bombs": False,
  19. "Long Beam": False,
  20. "Ice Beam": False,
  21. "Wave Beam": False,
  22. "High Jump Boots": False,
  23. "Varia": False,
  24. "Screw Attack": False
  25. }
  26. self.missileTanks = {
  27. 1: False,
  28. 2: False,
  29. 3: False,
  30. 4: False,
  31. 5: False,
  32. 6: False,
  33. 7: False,
  34. 8: False,
  35. 9: False,
  36. 10: False,
  37. 11: False,
  38. 12: False,
  39. 13: False,
  40. 14: False,
  41. 15: False,
  42. 16: False,
  43. 17: False,
  44. 18: False,
  45. 19: False,
  46. 20: False,
  47. 21: False
  48. }
  49. self.energyTanks = {
  50. 1: False,
  51. 2: False,
  52. 3: False,
  53. 4: False,
  54. 5: False,
  55. 6: False,
  56. 7: False,
  57. 8: False
  58. }
  59. self.zebetitesDestroyed = {
  60. 1: False,
  61. 2: False,
  62. 3: False,
  63. 4: False,
  64. 5: False
  65. }
  66. self.doors = {
  67. "Brinstar": {
  68. 1: False,
  69. 2: False,
  70. 3: False,
  71. 4: False,
  72. 5: False
  73. }, "Norfair": {
  74. 1: False,
  75. 2: False,
  76. 3: False,
  77. 4: False
  78. }, "Kraid": {
  79. 1: False,
  80. 2: False,
  81. 3: False,
  82. 4: False,
  83. 5: False
  84. }, "Ridley": {
  85. 1: False,
  86. 2: False
  87. }, "Tourian": {
  88. 1: False,
  89. 2: False,
  90. 3: False
  91. }
  92. }
  93. self.kraidKilled = False
  94. self.ridleyKilled = False
  95. self.motherBrainKilled = False
  96. self.kraidStatue = False
  97. self.ridleyStatue = False
  98. self.swimsuit = False
  99. self.missileCount = 0
  100. self.gameAge = 0
  101. self.locations = ["Brinstar", "Norfair", "Kraid's Lair", "Ridley's Lair", "Tourian"]
  102. self.startLocation = 0
  103. self.bitfield = []
  104. self.initializeBitfield()
  105. self.fullbitfield = []
  106. def initializeBitfield(self):
  107. self.bitfield = []
  108. for _ in range(128):
  109. self.bitfield.append(0)
  110. def toggleItem(self, itm):
  111. if itm in self.itemsCollected.keys():
  112. self.itemsCollected[itm] = not self.itemsCollected[itm]
  113. self.samusHas[itm] = not self.samusHas[itm]
  114. else:
  115. print("Couldn't find item: {}".format(str(itm)))
  116. def toggleMissileTank(self, num):
  117. try:
  118. num = int(num)
  119. except:
  120. print("{} is not a number".format(num))
  121. return
  122. if num in self.missileTanks.keys():
  123. self.missileTanks[num] = not self.missileTanks[num]
  124. else:
  125. print("Couldn't find missile tank: {}".format(num))
  126. def toggleEnergyTank(self, num):
  127. try:
  128. num = int(num)
  129. except:
  130. print("{} is not a number".format(num))
  131. return
  132. if num in self.energyTanks.keys():
  133. self.energyTanks[num] = not self.energyTanks[num]
  134. else:
  135. print("Couldn't find energy tank: {}".format(num))
  136. def toggleZebetite(self, num):
  137. try:
  138. num = int(num)
  139. except:
  140. print("{} is not a number".format(num))
  141. return
  142. if num in self.zebetitesDestroyed.keys():
  143. self.zebetitesDestroyed[num] = not self.zebetitesDestroyed[num]
  144. else:
  145. print("Couldn't find Zebetite: {}".format(num))
  146. def toggleKraid(self):
  147. self.kraidKilled = not self.kraidKilled
  148. self.kraidStatue = self.kraidKilled
  149. def toggleKraidStatue(self):
  150. self.kraidStatue = not self.kraidStatue
  151. if self.kraidKilled and not self.kraidStatue:
  152. print("WARNING: Kraid has been killed but his statue has not been raised.")
  153. def toggleRidley(self):
  154. self.ridleyKilled = not self.ridleyKilled
  155. self.ridleyStatue = self.ridleyKilled
  156. def toggleRidleyStatue(self):
  157. self.ridleyStatue = not self.ridleyStatue
  158. if self.ridleyKilled and not self.ridleyStatue:
  159. print("WARNING: Ridley has been killed but his statue has not been raised.")
  160. def toggleMotherBrain(self):
  161. self.motherBrainKilled = not self.motherBrainKilled
  162. def toggleDoor(self, area, door):
  163. try:
  164. area = str(area)
  165. door = int(door)
  166. except:
  167. print("Area must be string, door must be a positive integer")
  168. return
  169. if area in self.doors.keys() and int(door) in self.doors[area].keys():
  170. self.doors[area][door] = not self.doors[area][door]
  171. else:
  172. print("Couldn't find door {} in area {}".format(door, area))
  173. def toggleSwimsuit(self):
  174. self.swimsuit = not self.swimsuit
  175. def newLocation(self, loc):
  176. try:
  177. loc = str(loc)
  178. except:
  179. print("Location must be a string")
  180. return
  181. if loc in self.locations:
  182. self.startLocation = self.locations.index(loc)
  183. else:
  184. print("Couldn't find location: {}".format(loc))
  185. def collectedItems(self):
  186. o = []
  187. for k,v in self.itemsCollected.items():
  188. if v == True:
  189. o.append(k)
  190. if len(o) == 0:
  191. return "None"
  192. else:
  193. return ", ".join(o)
  194. def collectedMissiles(self):
  195. o = []
  196. for k, v in self.missileTanks.items():
  197. if v == True:
  198. o.append(k)
  199. if len(o) == 0:
  200. return "None"
  201. else:
  202. return ", ".join([str(b) for b in o])
  203. def collectedEtanks(self):
  204. o = []
  205. for k, v in self.energyTanks.items():
  206. if v == True:
  207. o.append(k)
  208. if len(o) == 0:
  209. return "None"
  210. else:
  211. return ", ".join([str(b) for b in o])
  212. def killedZebetites(self):
  213. o = []
  214. for k, v in self.zebetitesDestroyed.items():
  215. if v == True:
  216. o.append(k)
  217. if len(o) == 0:
  218. return "None"
  219. else:
  220. return ", ".join([str(b) for b in o])
  221. def killedBosses(self):
  222. o = []
  223. if self.kraidKilled:
  224. o.append("Kraid")
  225. if self.ridleyKilled:
  226. o.append("Ridley")
  227. if self.motherBrainKilled:
  228. o.append("Mother Brain")
  229. if len(o) == 0:
  230. return "None"
  231. else:
  232. return ", ".join(o)
  233. def raisedStatues(self):
  234. o = []
  235. if self.kraidStatue:
  236. o.append("Kraid")
  237. if self.ridleyStatue:
  238. o.append("Ridley")
  239. if len(o) == 0:
  240. return "None"
  241. else:
  242. return ", ".join(o)
  243. def inBailey(self):
  244. if self.swimsuit:
  245. return "Yes"
  246. else:
  247. return "No"
  248. def openedDoors(self):
  249. d = {"Brinstar": 0, "Norfair": 0, "Kraid": 0, "Ridley": 0, "Tourian": 0}
  250. o = []
  251. for k,v in self.doors["Brinstar"].items():
  252. if v == True:
  253. d["Brinstar"] = d["Brinstar"] + 1
  254. for k,v in self.doors["Norfair"].items():
  255. if v == True:
  256. d["Norfair"] = d["Norfair"] + 1
  257. for k,v in self.doors["Kraid"].items():
  258. if v == True:
  259. d["Kraid"] = d["Kraid"] + 1
  260. for k,v in self.doors["Ridley"].items():
  261. if v == True:
  262. d["Ridley"] = d["Ridley"] + 1
  263. for k,v in self.doors["Tourian"].items():
  264. if v == True:
  265. d["Tourian"] = d["Tourian"] + 1
  266. for k, v in d.items():
  267. o.append("{} {}".format(k, v))
  268. return ", ".join(o)
  269. def getBits(self):
  270. o = []
  271. word = []
  272. for i in range(128):
  273. word.append(str(self.bitfield[i]))
  274. if len(word) == 8:
  275. o.append("".join(word))
  276. word = []
  277. o1 = " ".join(o[:8])
  278. o2 = " ".join(o[8:])
  279. return o1 + "\n" + o2
  280. def toString(self):
  281. ic = "Items Collected: {}".format(self.collectedItems())
  282. mt = "Missile Tanks Collected: {}".format(self.collectedMissiles())
  283. et = "Energy Tanks Collected: {}".format(self.collectedEtanks())
  284. zb = "Zebetites Killed: {}".format(self.killedZebetites())
  285. kb = "Bosses Killed: {}".format(self.killedBosses())
  286. rs = "Statues Raised: {}".format(self.raisedStatues())
  287. sw = "Swimsuit?: {}".format(self.inBailey())
  288. sl = "Start Location: {}".format(self.locations[self.startLocation])
  289. dr = "Unlocked Doors: {}".format(self.openedDoors())
  290. ms = "Missiles: {}".format(self.missileCount)
  291. pw = "Password: {}".format(self.password)
  292. # bf = "Bitfield:\n{}".format(self.getBits())
  293. return "\n".join([ic, mt, et, zb, kb, rs, sw, sl, dr, ms, pw])
  294. def randomize(self):
  295. # Items
  296. if random.randint(0,1) == 1:
  297. self.toggleItem("Maru Mari")
  298. if random.randint(0,1) == 1:
  299. self.toggleItem("Bombs")
  300. if random.randint(0,1) == 1:
  301. self.toggleItem("Varia")
  302. if random.randint(0,1) == 1:
  303. self.toggleItem("High Jump Boots")
  304. if random.randint(0,1) == 1:
  305. self.toggleItem("Screw Attack")
  306. if random.randint(0,1) == 1:
  307. self.toggleItem("Long Beam")
  308. beam = random.randint(0,2)
  309. if beam == 1:
  310. self.toggleItem("Ice Beam")
  311. elif beam == 2:
  312. self.toggleItem("Wave Beam")
  313. # Missile Tanks
  314. for i in range(21):
  315. if random.randint(0,1) == 1:
  316. self.toggleMissileTank(i+1)
  317. # Energy Tanks
  318. for i in range(8):
  319. if random.randint(0,1) == 1:
  320. self.toggleEnergyTank(i+1)
  321. # Zebetites
  322. for i in range(5):
  323. if random.randint(0,1) == 1:
  324. self.toggleZebetite(i+1)
  325. # Bosses killed
  326. if random.randint(0,1) == 1:
  327. self.toggleKraid()
  328. if random.randint(0,1) == 1:
  329. self.toggleRidley()
  330. if random.randint(0,1) == 1:
  331. self.toggleMotherBrain()
  332. # Statues raised
  333. if not self.kraidKilled and random.randint(0,1) == 1:
  334. self.toggleKraidStatue()
  335. if not self.ridleyKilled and random.randint(0,1) == 1:
  336. self.toggleRidleyStatue()
  337. # Doors
  338. # Brinstar 5, Norfair 4, Kraid 5, Ridley 2, Tourian 3
  339. for i in range(5):
  340. if random.randint(0,1) == 1:
  341. self.doors["Brinstar"][i+1] = True
  342. for i in range(4):
  343. if random.randint(0,1) == 1:
  344. self.doors["Norfair"][i+1] = True
  345. for i in range(5):
  346. if random.randint(0,1) == 1:
  347. self.doors["Kraid"][i+1] = True
  348. for i in range(2):
  349. if random.randint(0,1) == 1:
  350. self.doors["Ridley"][i+1] = True
  351. for i in range(3):
  352. if random.randint(0,1) == 1:
  353. self.doors["Tourian"][i+1] = True
  354. # Swimsuit
  355. if random.randint(0,2) == 2:
  356. self.toggleSwimsuit()
  357. # Start Location
  358. self.startLocation = random.randint(0,4)
  359. self.missileCount = random.randint(0,255)
  360. def createBitfield(self):
  361. self.initializeBitfield()
  362. # Doing this in order, which is dumb and tedious but accurate.
  363. if self.itemsCollected["Maru Mari"]:
  364. self.bitfield[0] = 1
  365. if self.missileTanks[1]:
  366. self.bitfield[1] = 1
  367. if self.doors["Brinstar"][1]:
  368. self.bitfield[2] = 1
  369. if self.doors["Brinstar"][2]:
  370. self.bitfield[3] = 1
  371. if self.energyTanks[1]:
  372. self.bitfield[4] = 1
  373. if self.doors["Brinstar"][3]:
  374. self.bitfield[5] = 1
  375. if self.itemsCollected["Bombs"]:
  376. self.bitfield[6] = 1
  377. if self.doors["Brinstar"][4]:
  378. self.bitfield[7] = 1
  379. if self.missileTanks[2]:
  380. self.bitfield[8] = 1
  381. if self.energyTanks[2]:
  382. self.bitfield[9] = 1
  383. if self.doors["Brinstar"][5]:
  384. self.bitfield[10] = 1
  385. if self.itemsCollected["Varia"]:
  386. self.bitfield[11] = 1
  387. if self.energyTanks[3]:
  388. self.bitfield[12] = 1
  389. if self.missileTanks[3]:
  390. self.bitfield[13] = 1
  391. if self.missileTanks[4]:
  392. self.bitfield[14] = 1
  393. if self.doors["Norfair"][1]:
  394. self.bitfield[15] = 1
  395. if self.missileTanks[5]:
  396. self.bitfield[16] = 1
  397. if self.missileTanks[6]:
  398. self.bitfield[17] = 1
  399. if self.missileTanks[7]:
  400. self.bitfield[18] = 1
  401. if self.missileTanks[8]:
  402. self.bitfield[19] = 1
  403. if self.missileTanks[9]:
  404. self.bitfield[20] = 1
  405. if self.missileTanks[10]:
  406. self.bitfield[21] = 1
  407. if self.missileTanks[11]:
  408. self.bitfield[22] = 1
  409. if self.doors["Norfair"][2]:
  410. self.bitfield[23] = 1
  411. if self.itemsCollected["High Jump Boots"]:
  412. self.bitfield[24] = 1
  413. if self.doors["Norfair"][3]:
  414. self.bitfield[25] = 1
  415. if self.itemsCollected["Screw Attack"]:
  416. self.bitfield[26] = 1
  417. if self.missileTanks[12]:
  418. self.bitfield[27] = 1
  419. if self.missileTanks[13]:
  420. self.bitfield[28] = 1
  421. if self.doors["Norfair"][4]:
  422. self.bitfield[29] = 1
  423. if self.energyTanks[4]:
  424. self.bitfield[30] = 1
  425. if self.missileTanks[14]:
  426. self.bitfield[31] = 1
  427. if self.doors["Kraid"][1]:
  428. self.bitfield[32] = 1
  429. if self.missileTanks[15]:
  430. self.bitfield[33] = 1
  431. if self.missileTanks[16]:
  432. self.bitfield[34] = 1
  433. if self.doors["Kraid"][2]:
  434. self.bitfield[35] = 1
  435. if self.energyTanks[5]:
  436. self.bitfield[36] = 1
  437. if self.doors["Kraid"][3]:
  438. self.bitfield[37] = 1
  439. if self.doors["Kraid"][4]:
  440. self.bitfield[38] = 1
  441. if self.missileTanks[17]:
  442. self.bitfield[39] = 1
  443. if self.missileTanks[18]:
  444. self.bitfield[40] = 1
  445. if self.doors["Kraid"][5]:
  446. self.bitfield[41] = 1
  447. if self.energyTanks[6]:
  448. self.bitfield[42] = 1
  449. if self.missileTanks[19]:
  450. self.bitfield[43] = 1
  451. if self.doors["Ridley"][1]:
  452. self.bitfield[44] = 1
  453. if self.energyTanks[7]:
  454. self.bitfield[45] = 1
  455. if self.missileTanks[20]:
  456. self.bitfield[46] = 1
  457. if self.doors["Ridley"][2]:
  458. self.bitfield[47] = 1
  459. if self.energyTanks[8]:
  460. self.bitfield[48] = 1
  461. if self.missileTanks[21]:
  462. self.bitfield[49] = 1
  463. if self.doors["Tourian"][1]:
  464. self.bitfield[50] = 1
  465. if self.doors["Tourian"][2]:
  466. self.bitfield[51] = 1
  467. if self.doors["Tourian"][3]:
  468. self.bitfield[52] = 1
  469. if self.zebetitesDestroyed[1]:
  470. self.bitfield[53] = 1
  471. if self.zebetitesDestroyed[2]:
  472. self.bitfield[54] = 1
  473. if self.zebetitesDestroyed[3]:
  474. self.bitfield[55] = 1
  475. if self.zebetitesDestroyed[4]:
  476. self.bitfield[56] = 1
  477. if self.zebetitesDestroyed[5]:
  478. self.bitfield[57] = 1
  479. if self.motherBrainKilled:
  480. self.bitfield[58] = 1
  481. # 59-63 unknown
  482. # if self.:
  483. # self.bitfield[59] = 1
  484. # if self.:
  485. # self.bitfield[60] = 1
  486. # if self.:
  487. # self.bitfield[61] = 1
  488. # if self.:
  489. # self.bitfield[62] = 1
  490. # if self.:
  491. # self.bitfield[63] = 1
  492. # not 64, 65, or 66 = Brinstar
  493. # 64 = Norfair
  494. # 65 and not 66 = Kraid's Lair
  495. # 66 and not 65 = Ridley's Lair
  496. # 65 and 66 = Tourian
  497. if self.startLocation == 1:
  498. self.bitfield[64] = 1
  499. if self.startLocation == 2 or self.startLocation == 4:
  500. self.bitfield[65] = 1
  501. if self.startLocation == 3 or self.startLocation == 4:
  502. self.bitfield[66] = 1
  503. # 67 is the reset bit, I want all passwords to be valid
  504. # if self.:
  505. # self.bitfield[67] = 1
  506. # 68-70 are unknown
  507. # if self.:
  508. # self.bitfield[68] = 1
  509. # if self.:
  510. # self.bitfield[69] = 1
  511. # if self.:
  512. # self.bitfield[70] = 1
  513. if self.swimsuit:
  514. self.bitfield[71] = 1
  515. if self.samusHas["Bombs"]:
  516. self.bitfield[72] = 1
  517. if self.samusHas["High Jump Boots"]:
  518. self.bitfield[73] = 1
  519. if self.samusHas["Long Beam"]:
  520. self.bitfield[74] = 1
  521. if self.samusHas["Screw Attack"]:
  522. self.bitfield[75] = 1
  523. if self.samusHas["Maru Mari"]:
  524. self.bitfield[76] = 1
  525. if self.samusHas["Varia"]:
  526. self.bitfield[77] = 1
  527. if self.samusHas["Wave Beam"]:
  528. self.bitfield[78] = 1
  529. if self.samusHas["Ice Beam"]:
  530. self.bitfield[79] = 1
  531. # Missile count
  532. # +2^n from 0 to 7
  533. binMissiles = bin(self.missileCount).replace('0b','')[::-1]
  534. while len(binMissiles) < 8:
  535. binMissiles += "0"
  536. if int(binMissiles[0]) == 1:
  537. self.bitfield[80] = 1
  538. if int(binMissiles[1]) == 1:
  539. self.bitfield[81] = 1
  540. if int(binMissiles[2]) == 1:
  541. self.bitfield[82] = 1
  542. if int(binMissiles[3]) == 1:
  543. self.bitfield[83] = 1
  544. if int(binMissiles[4]) == 1:
  545. self.bitfield[84] = 1
  546. if int(binMissiles[5]) == 1:
  547. self.bitfield[85] = 1
  548. if int(binMissiles[6]) == 1:
  549. self.bitfield[86] = 1
  550. if int(binMissiles[7]) == 1:
  551. self.bitfield[87] = 1
  552. # 88-119 are game age, leaving at 0
  553. # if self.:
  554. # self.bitfield[88] = 1
  555. # if self.:
  556. # self.bitfield[89] = 1
  557. # if self.:
  558. # self.bitfield[90] = 1
  559. # if self.:
  560. # self.bitfield[91] = 1
  561. # if self.:
  562. # self.bitfield[92] = 1
  563. # if self.:
  564. # self.bitfield[93] = 1
  565. # if self.:
  566. # self.bitfield[94] = 1
  567. # if self.:
  568. # self.bitfield[95] = 1
  569. # if self.:
  570. # self.bitfield[96] = 1
  571. # if self.:
  572. # self.bitfield[97] = 1
  573. # if self.:
  574. # self.bitfield[98] = 1
  575. # if self.:
  576. # self.bitfield[99] = 1
  577. # if self.:
  578. # self.bitfield[100] = 1
  579. # if self.:
  580. # self.bitfield[101] = 1
  581. # if self.:
  582. # self.bitfield[102] = 1
  583. # if self.:
  584. # self.bitfield[103] = 1
  585. # if self.:
  586. # self.bitfield[104] = 1
  587. # if self.:
  588. # self.bitfield[105] = 1
  589. # if self.:
  590. # self.bitfield[106] = 1
  591. # if self.:
  592. # self.bitfield[107] = 1
  593. # if self.:
  594. # self.bitfield[108] = 1
  595. # if self.:
  596. # self.bitfield[109] = 1
  597. # if self.:
  598. # self.bitfield[110] = 1
  599. # if self.:
  600. # self.bitfield[111] = 1
  601. # if self.:
  602. # self.bitfield[112] = 1
  603. # if self.:
  604. # self.bitfield[113] = 1
  605. # if self.:
  606. # self.bitfield[114] = 1
  607. # if self.:
  608. # self.bitfield[115] = 1
  609. # if self.:
  610. # self.bitfield[116] = 1
  611. # if self.:
  612. # self.bitfield[117] = 1
  613. # if self.:
  614. # self.bitfield[118] = 1
  615. # if self.:
  616. # self.bitfield[119] = 1
  617. # 120-123 are unknown
  618. # if self.:
  619. # self.bitfield[120] = 1
  620. # if self.:
  621. # self.bitfield[121] = 1
  622. # if self.:
  623. # self.bitfield[122] = 1
  624. # if self.:
  625. # self.bitfield[123] = 1
  626. if self.ridleyKilled:
  627. self.bitfield[124] = 1
  628. if self.ridleyStatue:
  629. self.bitfield[125] = 1
  630. if self.kraidKilled:
  631. self.bitfield[126] = 1
  632. if self.kraidStatue:
  633. self.bitfield[127] = 1
  634. def generatePassword(self):
  635. # not gonna do the bit-shifting yet
  636. # shiftbit = random.randint(0,7)
  637. bitfield = self.bitfield
  638. # for _ in range(shiftbit):
  639. # [bitfield[127]] + bitfield[:127]
  640. # binShift = bin(shiftbit).replace('0b','')
  641. # while len(binShift) < 8:
  642. # binShift = "0" + binShift
  643. # for bit in binShift:
  644. # bitfield.append(int(bit))
  645. bitfield = bitfield + [0,0,0,0,0,0,0,0]
  646. # checking = []
  647. # for i in range(16):
  648. # checking.append(int("".join([str(x) for x in bitfield[i:i+8]]), 2))
  649. # print("Full Bitfield: {}".format("".join([str(x) for x in bitfield])))
  650. self.fullbitfield = "".join([str(x) for x in bitfield])
  651. newBitfield = []
  652. for i in range(17):
  653. j = i * 8
  654. k = j + 8
  655. word = self.fullbitfield[j:k][::-1]
  656. newBitfield.append(word)
  657. decChecksum = sum([int(x, 2) for x in newBitfield])
  658. bitfield = "".join(newBitfield)
  659. binChecksum = bin(decChecksum).replace('0b','')
  660. checksum = binChecksum[-8:]
  661. while len(checksum) < 8:
  662. checksum = "0" + checksum
  663. # print(checksum)
  664. for bit in checksum:
  665. bitfield += bit
  666. # print("Real Bitfield: {}".format(bitfield))
  667. letters = []
  668. letter = []
  669. for bit in bitfield:
  670. letter.append(bit)
  671. if len(letter) == 6:
  672. letters.append(self.alphabet[int("".join(letter),2)])
  673. letter = []
  674. words = []
  675. word = []
  676. for lt in letters:
  677. word.append(lt)
  678. if len(word) == 6:
  679. words.append("".join(word))
  680. word = []
  681. words.append("".join(word))
  682. self.password = " ".join(words)
  683. return self.password
  684. def decodePassword(self, pwd):
  685. densePwd = pwd.replace(" ","")
  686. numPwd = []
  687. for chr in densePwd:
  688. numPwd.append(self.alphabet.index(chr))
  689. bitPwd = [bin(x).replace("0b","") for x in numPwd]
  690. longBitPwd = []
  691. for word in bitPwd:
  692. longword = word
  693. while len(longword) < 6:
  694. longword = "0" + longword
  695. longBitPwd.append(longword)
  696. # print(self.fullbitfield)
  697. newBitfield = "".join(longBitPwd)
  698. # print(newBitfield)
  699. # print(newBitfield == self.fullbitfield)
  700. # print(len(newBitfield[:136]))
  701. # print(newBitfield[:136])
  702. csm = sum([int(x) for x in newBitfield[:136]])
  703. print(csm)
  704. # print(bin(csm).replace("0b",""))
  705. for i in range(len(newBitfield)):
  706. print(newBitfield[i], end="")
  707. if i%8 == 7:
  708. print(" ", end="")
  709. if i%64 == 63:
  710. print()
  711. def main():
  712. gs = MetroidState()
  713. gs.randomize()
  714. gs.createBitfield()
  715. pwd = gs.generatePassword()
  716. print(gs.toString())
  717. # print(pwd)
  718. # gs.decodePassword(pwd)
  719. if __name__ == "__main__":
  720. if len(sys.argv) == 2:
  721. gs = MetroidState()
  722. gs.decodePassword(sys.argv[1])
  723. else:
  724. main()