Parcourir la source

Split out ananas bot

master
Noëlle Anthony il y a 4 ans
Parent
révision
d03d1e9c78
2 fichiers modifiés avec 839 ajouts et 10 suppressions
  1. 837
    0
      metananas.py
  2. 2
    10
      metroidgen.py

+ 837
- 0
metananas.py Voir le fichier

@@ -0,0 +1,837 @@
# Metroid (NES) Random Password Generator
# Author: Noëlle Anthony
# License: MIT
# Date: October 2019
# This uses http://games.technoplaza.net/mpg/password.txt as a basis for its password algorithm

import random, sys
from ananas import PineappleBot, hourly

class MetroidState:
""" Stores the game state
"""
def __init__(self):
# Alphabet is 64 characters - 6 bits per character
self.alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz?-"
# The password has different flags for "item available for pickup" and
# "Samus has the item". I'm keeping them separate, but when the generator
# selects an item as "picked up", that means Samus has it and it's not available.
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
}
# Missile tanks are listed in the order in which they appear in the password,
# NOT in zone order or in any reasonable collection order.
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
}
# Likewise energy tanks are listed in password order.
self.energyTanks = {
1: False,
2: False,
3: False,
4: False,
5: False,
6: False,
7: False,
8: False
}
# This may be left-to-right (Samus approaches from the right). I haven't checked.
self.zebetitesDestroyed = {
1: False,
2: False,
3: False,
4: False,
5: False
}
# I'm not sure why I decided to segregate these by zone, except that that's how
# truepeacein.space does it.
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
}
}
# The next three are self-explanatory.
self.kraidKilled = False
self.ridleyKilled = False
self.motherBrainKilled = False
# The Kraid and Ridley statues rise when Kraid and Ridley are killed, but
# their states are stored separately in the password. It's possible to
# raise them without killing the bosses, granting early access to Tourian.
self.kraidStatue = False
self.ridleyStatue = False
# Is Samus wearing her armor (False) or her swimsuit (True)?
self.swimsuit = False
# 0-255. You can have more missiles than 5*collected tanks (in fact, you
# can only collect 21 tanks - thus 105 missiles - but can have up to 255
# missiles in your inventory).
self.missileCount = 0
# How advanced is the game clock? After 3 hours you don't get the good ending.
self.gameAge = 0
# There are five possible start locations: Brinstar, where you start, and
# at the bottom of the elevator where you enter each subsequent zone.
self.locations = ["Brinstar", "Norfair", "Kraid's Lair", "Ridley's Lair", "Tourian"]
self.startLocation = 0
# Arrays to store the 144 bits that compose the password
self.bitfield = []
self.initializeBitfield()
self.fullbitfield = []

def initializeBitfield(self):
""" Set the first 128 bits of the bitfield to 0.
The remaining 16 bits will be set later.
"""
self.bitfield = []
for _ in range(128):
self.bitfield.append(0)

def toggleItem(self, itm):
""" Mark an item as collected or uncollected.
"""
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):
""" Mark a missile tank as collected or uncollected.
"""
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):
""" Mark an energy tank as collected or uncollected.
"""
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):
""" Mark a Zebetite stem as destroyed or intact.
"""
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):
""" Mark Kraid as killed or alive.
"""
self.kraidKilled = not self.kraidKilled
self.kraidStatue = self.kraidKilled

def toggleKraidStatue(self):
""" Mark Kraid's statue as raised or lowered.
If Kraid is killed but his statue isn't raised, you can't complete the game.
"""
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):
""" Mark Ridley as killed or alive.
"""
self.ridleyKilled = not self.ridleyKilled
self.ridleyStatue = self.ridleyKilled

def toggleRidleyStatue(self):
""" Mark Ridley's statue as raised or lowered.
If Ridley is killed but his statue isn't raised, you can't complete the game.
"""
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):
""" Mark Mother Brain as killed or alive.
If Mother Brain is marked as killed, the self-destruct timer won't go off
when you reach her room.
"""
self.motherBrainKilled = not self.motherBrainKilled

def toggleDoor(self, area, door):
""" Mark a given red/yellow door as opened or locked.
"""
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):
""" Determine whether or not Samus is wearing her armor.
"""
self.swimsuit = not self.swimsuit

def newLocation(self, loc):
""" Set a new starting location (0-4).
"""
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):
""" List which items have been collected.
Under this generator's rules, if Samus doesn't have an item,
it's available to be picked up.
"""
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):
""" List which missile tanks have been collected.
"""
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):
""" List which energy tanks have been collected.
"""
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):
""" List which Zebetite stems have been destroyed.
"""
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):
""" List which bosses have been killed.
"""
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):
""" List which statues have been raised.
"""
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):
""" Show whether Samus is in her swimsuit or not.
'inBailey' refers to an old (false) explanation of the JUSTIN BAILEY
password, in which a 'bailey' was English slang for a bathing suit,
so with that password, Samus was "Just In Bailey" - i.e. in her swimsuit.
"""
if self.swimsuit:
return "Yes"
else:
return "No"

def openedDoors(self):
""" List which red/yellow doors have been unlocked.
"""
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):
""" Return the bitfield in an easily-readable format.
"""
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):
""" Output the game state as a newline-delimited string.
"""
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)
pw = "Password: {}".format(self.password)
return "\n".join([ic, mt, et, zb, kb, rs, sw, sl, dr, ms, pw])

def randomize(self):
""" The randomizer!
"""
# 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
# Samus has a 1/3 chance of spawning in her swimsuit.
# There's no technical reason for this, just a personal choice.
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):
""" Create the 144-bit field from the game state
that will generate the password.
"""
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

# 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.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, let's randomize
if random.randint(0,1) == 1:
self.bitfield[88] = 1
if random.randint(0,1) == 1:
self.bitfield[89] = 1
if random.randint(0,1) == 1:
self.bitfield[90] = 1
if random.randint(0,1) == 1:
self.bitfield[91] = 1
if random.randint(0,1) == 1:
self.bitfield[92] = 1
if random.randint(0,1) == 1:
self.bitfield[93] = 1
if random.randint(0,1) == 1:
self.bitfield[94] = 1
if random.randint(0,1) == 1:
self.bitfield[95] = 1
if random.randint(0,1) == 1:
self.bitfield[96] = 1
if random.randint(0,1) == 1:
self.bitfield[97] = 1
if random.randint(0,1) == 1:
self.bitfield[98] = 1
if random.randint(0,1) == 1:
self.bitfield[99] = 1
if random.randint(0,1) == 1:
self.bitfield[100] = 1
if random.randint(0,1) == 1:
self.bitfield[101] = 1
if random.randint(0,1) == 1:
self.bitfield[102] = 1
if random.randint(0,1) == 1:
self.bitfield[103] = 1
if random.randint(0,1) == 1:
self.bitfield[104] = 1
if random.randint(0,1) == 1:
self.bitfield[105] = 1
if random.randint(0,1) == 1:
self.bitfield[106] = 1
if random.randint(0,1) == 1:
self.bitfield[107] = 1
if random.randint(0,1) == 1:
self.bitfield[108] = 1
if random.randint(0,1) == 1:
self.bitfield[109] = 1
if random.randint(0,1) == 1:
self.bitfield[110] = 1
if random.randint(0,1) == 1:
self.bitfield[111] = 1
if random.randint(0,1) == 1:
self.bitfield[112] = 1
if random.randint(0,1) == 1:
self.bitfield[113] = 1
if random.randint(0,1) == 1:
self.bitfield[114] = 1
if random.randint(0,1) == 1:
self.bitfield[115] = 1
if random.randint(0,1) == 1:
self.bitfield[116] = 1
if random.randint(0,1) == 1:
self.bitfield[117] = 1
if random.randint(0,1) == 1:
self.bitfield[118] = 1
if random.randint(0,1) == 1:
self.bitfield[119] = 1

# 120-123 are unknown

# I have no idea why these are at the end. I wonder if Kraid and
# Ridley were relatively late additions to the game? (Or maybe
# they were just implemented late in the game's development.)
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):
""" Generate the password from the bitfield.
This is a five-step process.
1) Reverse the order of each 8-bit byte to make it little-endian.
2) Cycle the entire bitfield 0-7 bits to the right.
Append the number of shifts in binary to the end - again, little-endian.
3) Create the checksum by turning each byte into a decimal number,
summing them, converting the sum *back* to binary, and taking the lowest
8 bits of that binary sum and adding it - BIG-ENDIAN - to the end.
4) Separate the bitstream into ***6-bit*** chunks and create a decimal
number from each chunk (0-63).
5) Associate each decimal number with a letter from the Metroid Alphabet
(listed at the top of __init__()).
I'm not doing step 2 yet, which is equivalent to shifting 0 places
and making the shift byte 00000000.
"""
# not gonna do the bit-shifting yet
bitfield = self.bitfield
bitfield = bitfield + [0,0,0,0,0,0,0,0] # add the zero shift byte
self.fullbitfield = "".join([str(x) for x in bitfield])
newBitfield = []
for i in range(17):
j = i * 8
k = j + 8
word = self.fullbitfield[j:k][::-1] # I thought [j:k:-1] should work but it doesn't
newBitfield.append(word)
decChecksum = sum([int(x, 2) for x in newBitfield])
bitfield = "".join(newBitfield)
binChecksum = bin(decChecksum).replace('0b','')
checksum = binChecksum[-8:]
while len(checksum) < 8:
checksum = "0" + checksum
for bit in checksum:
bitfield += bit

letters = []
letter = []
for bit in bitfield:
letter.append(bit)
if len(letter) == 6:
letters.append(self.alphabet[int("".join(letter),2)])
letter = []
words = []
word = []
for lt in letters:
word.append(lt)
if len(word) == 6:
words.append("".join(word))
word = []
words.append("".join(word))
self.password = " ".join(words)
return self.password

def decodePassword(self, pwd):
""" Sanity checking! This function decodes an input password back into a bitfield,
so that you can check that it was properly encoded.
Q: Why doesn't this display the game state?
A: I trust that https://www.truepeacein.space properly encodes the game state.
So when I create a game state with the randomizer, I can recreate that
game state at TPIS and use the password generates as its input, to check
against my randomized game password. In other words, this is a testing
function, and in the intended use case I'll know what the input bitfield is
and be able to check against it.
"""
densePwd = pwd.replace(" ","")
numPwd = []
for chr in densePwd:
numPwd.append(self.alphabet.index(chr))
bitPwd = [bin(x).replace("0b","") for x in numPwd]
longBitPwd = []
for word in bitPwd:
longword = word
while len(longword) < 6:
longword = "0" + longword
longBitPwd.append(longword)
newBitfield = "".join(longBitPwd)
csm = sum([int(x) for x in newBitfield[:136]])
print(csm)
for i in range(len(newBitfield)):
print(newBitfield[i], end="")
if i%8 == 7:
print(" ", end="")
if i%64 == 63:
print()

class MetroidPoster(PineappleBot):

@hourly(minute=35)
def postPassword(self):
gs = MetroidState()
gs.initializeBitfield()
gs.randomize()
gs.createBitfield()
gs.generatePassword()
post_text = gs.toString()
self.mastodon.status_post(post_text, visibility = "unlisted", spoiler_text = "Metroid password: {}".format(gs.password))
print("Metroidgen scheduled: posted {}".format(gs.password))

+ 2
- 10
metroidgen.py Voir le fichier

@@ -7,7 +7,7 @@
import random, sys
from ananas import PineappleBot, hourly

class MetroidState(PineappleBot):
class MetroidState:
""" Stores the game state
"""
def __init__(self):
@@ -823,15 +823,7 @@ class MetroidState(PineappleBot):
if i%64 == 63:
print()

@hourly(minute=35)
def postPassword(self):
self.initializeBitfield()
self.randomize()
self.createBitfield()
self.generatePassword()
post_text = self.toString()
self.mastodon.status_post(post_text, visibility = "unlisted", spoiler_text = "Metroid password: {}".format(self.password))
print("Metroidgen scheduled: posted {}".format(self.password))


def main():
gs = MetroidState()

Chargement…
Annuler
Enregistrer