def test2(): print('----World Tests----') w1 = World(3, 4) print(w1) assert w1.__str__() == '....\n....\n....\n' w1.set_cell(0, 0, True) w1.set_cell(0, 3, True) w1.set_cell(2, 0, True) w1.set_cell(2, 3, True) print(w1) assert w1.__str__() == 'X..X\n....\nX..X\n' assert w1._World__rows == 3 assert w1._World__columns == 4
def test4(): print('----Next Generation Tests----') w1 = World(3, 4) print(w1) w1.set_cell(0, 1, True) w1.set_cell(1, 1, True) w1.set_cell(2, 1, True) print(w1) assert w1.__str__() == '.X..\n.X..\n.X..\n' w1.next_generation() print(w1) assert w1.__str__() == '....\nXXX.\n....\n' w1.next_generation() print(w1) assert w1.__str__() == '.X..\n.X..\n.X..\n' w1.next_generation() print(w1) assert w1.__str__() == '....\nXXX.\n....\n'
class Life(object): def __init__(self): self.__world = World(34, 69) self.__fillrate = 25 self.__delay = 0.5 self.__generation = 0 self.random() self.__lastWorld = '' self.__secondWorld = '' def main(self): """ Main event loop for store. :return: None """ command = 'help' parameter = None while command != 'quit': if command == 'help': self.help('help.txt', 'Press <return> to continue.') print(self.__world, end="") print(self.status() + '\n' + self.menu(), end=' ') elif command == 'next generation': self.next_generation(parameter) elif command == 'run simulation': self.run_simulation(parameter) elif command == 'skip generations': self.skip_generations(parameter) elif command == 'random world': self.random() elif command == 'change fillrate': self.change_fillrate(parameter) elif command == 'change delay': self.change_delay(parameter) elif command == 'change size': self.change_size(parameter) elif command == 'change display': self.change_display(parameter) elif command == 'customize-world': print( '[F]illrate [D]elay [S]ize d[I]splay sa[V]e to disk load [W]orld c[u]stom display li[B]rary' ) elif command == 'save world': self.save(parameter, './worlds/') elif command == 'open world': self.open(parameter, './worlds/') elif command == 'custom-cells': self.user_display() self.change_display(parameter) elif command == 'geometry': self.set_geometry() elif command == 'library': self.from_library(parameter, './library/') elif command == 'change rules': self.change_rule(parameter) command, parameter = self.get_command() print('goodbye') def menu(self): """ returns a string containing the menu. :return: Menu string """ return '[N]ext [R]un s[K]ip n[E]w [H]elp [Q]uit [C]ustom [G]eometry Ch[A]nge Rules ' def get_command(self): """ Get a valid command from the user. :return: command, parameter """ commands = { 'n': 'next generation', 'r': 'run simulation', 'k': 'skip generations', 'e': 'random world', 'f': 'change fillrate', 'd': 'change delay', 's': 'change size', 'i': 'change display', 'h': 'help', '?': 'help', 'q': 'quit', 'c': 'customize-world', 'v': 'save world', 'w': 'open world', 'u': 'custom-cells', 'g': 'geometry', 'b': 'library', 'a': 'change rules' } validCommands = commands.keys() userInput = '&' parameter = None while userInput[0].lower() not in validCommands: userInput = input() if userInput == '': userInput = 'n' parameter = 1 command = commands[userInput[0].lower()] if len(userInput) > 1: parameter = userInput[1:].strip() return command, parameter def status(self): """ Returns a string representing the status of the world. :return: string """ geometry = self.__world.get_currentGeo() #ruleSet = Rule.__current rows = self.__world.get_rows() columns = self.__world.get_columns() percentAlive = (self.__world.get_living_cell_count() / (rows * columns)) * 100 speed = self.__delay generation = self.__generation string = 'Status: ' string += f'size:[{rows}x{columns}] ' string += f'alive: {percentAlive:0.0f}% ' string += f'speed: 1 gen every {speed} seconds ' string += f'generation: {generation} ' string += f'geometry: {geometry} ' #string += f'ruleSet: {ruleSet} ' return string def help(self, filename, prompt=None): """ Displays instructions. :param filename: The string of helping instructions. :param prompt: :return: None """ with open(filename, 'r') as file: help = file.read() print(help, end='') if prompt: input('\n' + prompt) def next_generation(self, parameter): """ Displays the next generation of the world. :param parameter: :return: None """ self.__world.next_generation() self.__generation += 1 print(self.__world, end='') print() print('You have now gone 1 gen forward.') print() print(self.status() + '\n' + self.menu(), end=' ') def run_simulation(self, parameter): """ Displays the next generation of the world. :param parameter: :return: None """ if toolbox.is_integer(parameter) and int(parameter) > 0: generations = int(parameter) else: prompt = 'How many generations would you like to simulate?' generations = toolbox.get_integer_between(1, 10000, prompt) for generation in range(generations): self.__world.next_generation() if self.__world.is_stable() == True: "It is stable now." break else: pass #self.__world.__lastWorld = self.__world.__secondWorld string = self.__world.__str__() string += self.status() string += f'left: {generations - generation}' print(string) time.sleep(self.__delay) print() print(f'You have now been through {generations} generations. ') print() print(self.menu(), end=' ') self.__generation += generations def skip_generations(self, parameter): """ Displays the next generation of the world. :param parameter: :return: None """ if toolbox.is_integer(parameter) and int(parameter) > 0: generations = int(parameter) else: prompt = 'How many generations would you like to skip?' generations = toolbox.get_integer_between(1, 10000, prompt) print(f'Skipping {generations} generations.', end='') for generation in range(generations): self.__world.next_generation(self.__world) if self.__world.is_stable() == True: "It is stable now." break else: pass if generation % 100 == 0: print('.', end='') print(' done!') self.__generation += generations time.sleep(2) string = self.__world.__str__() string += self.status() print(string) print() print(f'You now have skipped forward {generations} generations.') print() print(self.menu(), end=' ') def change_fillrate(self, parameter): """ Change the fillrate for the simulation. :param parameter: :return: None """ if toolbox.is_number(parameter) and 0 <= float(parameter) <= 100: fillrate = float(parameter) else: prompt = 'What percent of cells should be alive?' fillrate = toolbox.get_integer_between(0, 100, prompt) self.__fillrate = fillrate self.random() print(f'The percent of alive cells is now {fillrate} percent.') def change_delay(self, parameter): """ Change the delay betwen generations of the simulation. :param parameter: :return: None """ if toolbox.is_number(parameter): delay = float(parameter) else: prompt = 'Seconds of delay between generations?' delay = toolbox.get_number(prompt) self.__delay = delay print( f'Your speed of running the simulation is now 1 gen every {delay} seconds.' ) def change_display(self, parameter): """ Change the live and dead characters for the cells. :param parameter: :return: None """ if toolbox.is_integer(parameter) and \ 1 <= int(parameter) <= len(Cell.displaySets.keys()): setNumber = int(parameter) else: print('**************************************') for number, set in enumerate(Cell.displaySets): liveChar = Cell.displaySets[set]['liveChar'] deadChar = Cell.displaySets[set]['deadChar'] print( f'{number + 1}: living cells: {liveChar} dead cells: {deadChar}' ) print('**************************************') prompt = 'What character set would you like to use?' setNumber = toolbox.get_integer_between(1, number + 1, prompt) setString = list(Cell.displaySets.keys())[setNumber - 1] Cell.set_display(setString) print(self.__world, end='') print() print( f'Your living cell is now {liveChar} and a dead cell is {deadChar}.' ) print() print(self.status() + '\n' + self.menu(), end=' ') def user_display(self): living = toolbox.get_string( 'What would you like your living cell to be?') dead = toolbox.get_string('What would you like your dead cell to be?') Cell.set_display_user_values(living, dead) print() print( f"You now have a choice of a '{living}' as a living cell and a dead cell as '{dead}'." ) print() def random(self): """ Create a random world :return: None """ self.__world.randomize(self.__fillrate) print(self.__world, end='') print() print(' You just created a brand new random world.') print() self.__generation = 0 print(self.status() + '\n' + self.menu(), end=' ') def change_size(self, parameter): """ changes the size of the current grid world. :param parameter: :return: None """ if parameter: rows, columns = parameter.split('x', 2) if toolbox.is_integer(rows) and toolbox.is_integer(columns): rows = int(rows) columns = int(columns) else: prompt = 'How many rows of cells?' rows = toolbox.get_integer_between(1, 40, prompt) prompt = 'How many cells in each row?' columns = toolbox.get_integer_between(1, 120, prompt) self.__world = World(rows, columns) self.random() print(self.__world, end='') self.__generation = 0 print() print(f'Your world size is now {rows} by {columns}.') print() print(self.status() + '\n' + self.menu(), end=' ') def save(self, filename, myPath='./'): """ Save the current generation of the current world as a text file. :param filename: name of the file, may be None at this point. :param myPath: Where the file should be saved. :return: None """ replace = False Cell.set_display('basic') if filename == None: filename = toolbox.get_string( 'What do you want to call the file? ') # # Make sure the file has the correct file extension. # if filename[-5:] != '.life': filename = filename + '.life' allFiles = os.listdir(myPath) if filename in allFiles: replace = toolbox.get_boolean( 'There is already a file with this name. Would like to replace it?' ) if replace == True: # # if the path doesn't already exist, create it. # if not os.path.isdir(myPath): os.mkdir(myPath) # # Add on the correct path for saving files if the user didn't # include it in the filename. # if filename[0:len(myPath)] != myPath: filename = myPath + filename self.__world.save(filename) print() print('You now saved this world.') print() else: print("Okay I won't save it.") print(self.__world, end='') print() print(self.status() + '\n' + self.menu(), end=' ') def open(self, filename, myPath='./'): """ open a text file and use it to populate a new world. :param filename: name of the file, may be None at this point. :param myPath: Where the file is located. :return: None """ Cell.set_display('basic') if filename == None: filename = toolbox.get_string('Which file do you want to open?') # # Check for and add the correct file extension. # if filename[-5:] != '.life': filename = filename + '.life' allFiles = os.listdir(myPath) if filename not in allFiles: print('404: File not found...') for filenames in allFiles: print(filenames) print('Try one of these next time.') print() else: # # Add on the correct path for saving files if the user didn't # include it in the filename. # if filename[0:len(myPath)] != myPath: filename = myPath + filename self.__world = World.from_file(filename) print(self.__world, end='') print() print(f'You now opened {filename} world.') print() print(self.status() + '\n' + self.menu(), end=' ') def set_geometry(self): userGeo = toolbox.get_integer_between( 1, 2, """ Choose 1 or 2: 1. Basic Geometry 2. Donut Geometry""") self.__world.set_geometry(userGeo) print(self.__world, end='') print(self.status() + '\n' + self.menu(), end=' ') def from_library(self, filename, myPath='./'): Cell.set_display('basic') files = [] number = 1 print('**************************************') for file in os.listdir(myPath): print(f'{number}: {file}') files.append(file) number += 1 print('**************************************') prompt = 'Which file would you like to open? ' fileNumber = toolbox.get_integer_between(1, number - 1, prompt) filename = files[fileNumber - 1] print(filename) # # Check for and add the correct file extension. # if filename[-5:] != '.life': filename = filename + '.life' allFiles = os.listdir(myPath) if filename not in allFiles: print('404: File not found...') for filenames in allFiles: print(filenames) print('Try one of these next time.') print() else: # # Add on the correct path for saving files if the user didn't # include it in the filename. # if filename[0:len(myPath)] != myPath: filename = myPath + filename self.__world = World.from_file(filename) print(self.__world, end='') print() print(f'You now opened {filename} world.') print() print(self.status() + '\n' + self.menu(), end=' ') def change_rule(self, parameter): """ Change the number of neighbors a cell needs to live or die. :param parameter: :return: None """ if toolbox.is_integer(parameter) and \ 1 <= int(parameter) <= len(Rule.ruleSets.keys()): setNumber = int(parameter) else: print('**************************************') for number, set in enumerate(Rule.ruleSets): neighbor1 = Rule.ruleSets[set]['neighbor1'] neighbor2 = Rule.ruleSets[set]['neighbor2'] neighbor3 = Rule.ruleSets[set]['neighbor3'] print( f'{number + 1}: neighbor1: {neighbor1} neighbor2: {neighbor2} neighbor3: {neighbor3}' ) print('**************************************') prompt = 'What rule set would you like to use?' setNumber = toolbox.get_integer_between(1, number + 1, prompt) setString = list(Rule.ruleSets.keys())[setNumber - 1] Rule.set_rule(setString) print(self.__world, end='') print() print( f'Your rule set is now neighbor1:{neighbor1}, neighbor2:{neighbor2}, neighbor3:{neighbor3}.' ) print() print(self.status() + '\n' + self.menu(), end=' ')
class Life(object): def __init__(self): self.__world = World(34, 66) self.__fillrate = 25 self.__delay = 0.5 self.random() def main(self): """Main event loop for store.""" command = 'help' parameter = None while command != 'quit': if command == 'help': self.help('help.txt', 'Press <return> to continue.') print(self.__world, end="") print(self.status() + '\n' + self.menu(), end=' ') elif command == 'next generation': self.next_generation(parameter) elif command == 'run simulation': self.run_simulation(parameter) elif command == 'skip generations': self.skip_generations(parameter) elif command == 'random world': self.random() elif command == 'change fillrate': self.change_fillrate(parameter) elif command == 'change delay': self.change_delay(parameter) elif command == 'change size': self.change_size(parameter) elif command == 'change display': self.change_display(parameter) elif command == 'long l world': self.long_l_world() elif command == 'acorn world': self.acorn_world() command, parameter = self.get_command() print('goodbye') def menu(self): """returns a string containing the menu.""" return '[N]ext [R]un s[K]ip n[E]w [F]illrate [D]elay [S]ize d[I]splay [L]ong l [A]corn [H]elp [Q]uit' def get_command(self): """Get a valid command from the user.""" commands = { 'n': 'next generation', 'r': 'run simulation', 'k': 'skip generations', 'e': 'random world', 'f': 'change fillrate', 'd': 'change delay', 's': 'change size', 'i': 'change display', 'l': 'long l world', 'a': 'acorn world', 'h': 'help', '?': 'help', 'q': 'quit' } validCommands = commands.keys() userInput = '&' parameter = None while userInput[0].lower() not in validCommands: userInput = input() if userInput == '': userInput = 'n' parameter = 1 command = commands[userInput[0].lower()] if len(userInput) > 1: parameter = userInput[1:].strip() return command, parameter def status(self): """Returns a string representing the status of the world.""" rows = self.__world.get_rows() columns = self.__world.get_columns() percentAlive = (self.__world.get_living_cell_count() / (rows * columns)) * 100 string = 'Status: ' string += f'size:[{rows}x{columns}] ' string += f'alive: {percentAlive:0.0f}% ' return string def help(self, filename, prompt=None): """Displays instructions.""" with open(filename, 'r') as file: help = file.read() print(help, end='') if prompt: input('\n' + prompt) def next_generation(self, parameter): """Displays the next generation of the world""" self.__world.next_generation() print(self.__world, end='') print(self.status() + '\n' + self.menu(), end=' ') def run_simulation(self, parameter): """Displays the next generation of the world""" if toolbox.is_integer(parameter) and int(parameter) > 0: generations = int(parameter) else: prompt = 'How many generations would you like to simulate?' generations = toolbox.get_integer_between(1, 10000, prompt) for generation in range(generations): self.__world.next_generation() string = self.__world.__str__() string += self.status() string += f'left: {generations - generation}' print(string) time.sleep(self.__delay) print(self.menu(), end=' ') def skip_generations(self, parameter): """Displays the next generation of the world""" if toolbox.is_integer(parameter) and int(parameter) > 0: generations = int(parameter) else: prompt = 'How many generations would you like to skip?' generations = toolbox.get_integer_between(1, 10000, prompt) print(f'Skipping {generations} generations.', end='') for generation in range(generations): self.__world.next_generation() if generation % 100 == 0: print('.', end='') print(' done!') time.sleep(2) string = self.__world.__str__() string += self.status() print(string) print(self.menu(), end=' ') def change_fillrate(self, parameter): """Change the fillrate for the simulation.""" if toolbox.is_number(parameter) and 0 <= float(parameter) <= 100: fillrate = float(parameter) else: prompt = 'What percent of cells should be alive?' fillrate = toolbox.get_integer_between(0, 100, prompt) self.__fillrate = fillrate self.random() def change_delay(self, parameter): """Change the delay betwen generations of the simulation.""" if toolbox.is_number(parameter): delay = float(parameter) else: prompt = 'Seconds of delay between generations?' delay = toolbox.get_number(prompt) self.__delay = delay def change_display(self, parameter): """Change the live and dead characters for the cells.""" if toolbox.is_integer(parameter) and \ 1 <= int(parameter) <= len(Cell.displaySets.keys()): setNumber = int(parameter) else: print('**************************************') for number, set in enumerate(Cell.displaySets): liveChar = Cell.displaySets[set]['liveChar'] deadChar = Cell.displaySets[set]['deadChar'] print( f'{number+1}: living cells: {liveChar} dead cells: {deadChar}' ) print('**************************************') prompt = 'What character set would you like to use?' setNumber = toolbox.get_integer_between(1, number + 1, prompt) setString = list(Cell.displaySets.keys())[setNumber - 1] Cell.set_display(setString) print(self.__world, end='') print(self.status() + '\n' + self.menu(), end=' ') def random(self): """Create a random world""" self.__world.randomize(self.__fillrate) print(self.__world, end='') print(self.status() + '\n' + self.menu(), end=' ') def change_size(self, parameter): if parameter: rows, columns = parameter.split('x', 2) if toolbox.is_integer(rows) and toolbox.is_integer(columns): rows = int(rows) columns = int(columns) else: prompt = 'How many rows of cells?' rows = toolbox.get_integer_between(1, 40, prompt) prompt = 'How many cells in each row?' columns = toolbox.get_integer_between(1, 120, prompt) self.__world = World(rows, columns) self.random() def long_l_world(self): """Create a blank world and put this pattern in the middle: .... .x.. .x.. .x.. .xx. .... """ rows = self.__world.get_rows() columns = self.__world.get_columns() self.__world = World(rows, columns) middleRow = int(rows / 2) middleColumn = int(columns / 2) self.__world.set_cell(middleRow - 2, middleColumn, True) self.__world.set_cell(middleRow - 1, middleColumn, True) self.__world.set_cell(middleRow - 0, middleColumn, True) self.__world.set_cell(middleRow + 1, middleColumn, True) self.__world.set_cell(middleRow + 1, middleColumn + 1, True) print(self.__world, end='') print(self.status() + '\n' + self.menu(), end=' ') def acorn_world(self): """Create a blank world and put this pattern in the middle: ......... ..x...... ....x.... .xx..xxx. ......... """ rows = self.__world.get_rows() columns = self.__world.get_columns() self.__world = World(rows, columns) middleRow = int(rows / 2) middleColumn = int(columns / 2) self.__world.set_cell(middleRow - 1, middleColumn - 2, True) self.__world.set_cell(middleRow - 0, middleColumn - 0, True) self.__world.set_cell(middleRow + 1, middleColumn - 3, True) self.__world.set_cell(middleRow + 1, middleColumn - 2, True) self.__world.set_cell(middleRow + 1, middleColumn + 1, True) self.__world.set_cell(middleRow + 1, middleColumn + 2, True) self.__world.set_cell(middleRow + 1, middleColumn + 3, True) print(self.__world, end='') print(self.status() + '\n' + self.menu(), end=' ')
class Life(object): speeds = [10, 7, 5, 3, 2, 1.5, 1, 0.75, 0.5, 0.25, 0.15, 0] def __init__(self): self.__world = World(34, 66) self.__fillrate = 25 self.__speed = 5 self.__delay = Life.speeds[self.__speed] self.__menu = 'main' self.random() def main(self): """ Main event loop for store. :return: choice """ command = 'help' parameter = None while command != 'quit': if command == 'help': self.help('help3.txt', 'Press <return> to continue. ') elif command == 'more menu': self.__menu = 'more' elif command == 'back to main menu': self.__menu = 'main' elif command == 'run simulation': self.run_simulation(parameter) elif command == 'skip generations': self.skip_generations(parameter) elif command == 'random world': self.random() elif command == 'save world': self.save(parameter, './worlds/') elif command == 'open world': self.open(parameter, './worlds/') elif command == 'change fillrate': self.change_fillrate(parameter) elif command == 'change speed': self.change_speed(parameter) elif command == 'change size': self.change_size(parameter) elif command == 'change graphics': self.change_graphics(parameter) elif command == 'geometry': self.set_geometry() elif command == 'library': self.from_library(parameter, './library/') self.display() command, parameter = self.get_command() print('See ya, thanks for playing!') def menu(self): """ returns a string containing the menu. :return: string containing the menu """ return '[R]un s[K]ip [N]ew [S]ave [O]pen [M]ore [H]elp [L]ibrary [Q]uit' def menu_more(self): """ returns a string containing the menu. :return: string containing the menu """ return 's[P]eed [D]elay s[I]ze [G]raphics g[E]ometry [H]elp [B]ack' def get_command(self): """ Get a valid command from the user. :return: command """ commands = { 'r': 'run simulation', 'k': 'skip generations', 'n': 'random world', 's': 'save world', 'o': 'open world', 'f': 'change fillrate', 'p': 'change speed', 'i': 'change size', 'g': 'change graphics', 'e': 'geometry', 'l': 'library', 'm': 'more menu', 'b': 'back to main menu', 'h': 'help', '?': 'help', 'q': 'quit' } validCommands = commands.keys() userInput = '&' parameter = None while userInput[0].lower() not in validCommands: userInput = input('Command: ') if userInput == '': userInput = 'r' parameter = 1 command = commands[userInput[0].lower()] if len(userInput) > 1: parameter = userInput[1:].strip() return command, parameter def status(self): """ Returns a string representing the status of the world. :return: string showing the status """ rows = self.__world.get_rows() columns = self.__world.get_columns() percentAlive = (self.__world.get_living_cell_count() / (rows * columns)) * 100 string = 'Status: ' string += f'gen: {self.__world.get_generation()} ' string += f'speed: {self.__speed} ' string += f'size:[{rows}x{columns}] ' string += f'alive: {percentAlive:0.0f}% ' return string def help(self, filename, prompt=None): """ Displays instructions. :param filename: help3.txt :param prompt: :return: None """ with open(filename, 'r') as file: help = file.read() print(help, end='') if prompt: input('\n' + prompt) def next_generation(self, parameter): """ Displays the next generation of the world :param parameter: parameter :return: """ self.__world.next_generation() self.display() def run_simulation(self, generations): """ Displays the next generation of the world :param generations: :return: next generation """ if toolbox.is_integer(generations) and int(generations) > 0: generations = int(generations) else: prompt = 'How many generations do you want to do?' generations = toolbox.get_integer_between(1, 10000, prompt) for generation in range(generations): self.__world.next_generation() if self.__world.is_stable() == True: break string = self.__world.__str__() string += self.status() string += f'left: {generations - generation}' print(string) time.sleep(self.__delay) print(self.menu()) def skip_generations(self, generations): """ Displays the next generation of the world :param generations: :return: next generation """ if toolbox.is_integer(generations) and int(generations) > 0: generations = int(generations) else: prompt = 'How many generations do you wanna skip?' generations = toolbox.get_integer_between(1, 10000, prompt) print(f'Skipping {generations} generations.', end='') while True: for generation in range(generations): self.__world.next_generation() self.__world.is_stable(self.__world) if generation % 100 == 0: print('.', end='') print(' done!') time.sleep(2) self.display() def change_fillrate(self, fillrate): """ Change the fillrate for the simulation. :param fillrate: :return: fillrate """ if toolbox.is_number(fillrate) and 0 <= float(fillrate) <= 100: fillrate = float(fillrate) else: prompt = 'What percent of cells do you want to be alive?' fillrate = toolbox.get_integer_between(0, 100, prompt) self.__fillrate = fillrate self.random() def change_speed(self, speed): """ Change the delay betwen generations of the simulation. :param speed: :return: speed """ if toolbox.is_number(speed): speed = int(speed) else: prompt = 'How fast should the generations update?' speed = toolbox.get_integer_between(0, 11, prompt) self.__delay = Life.speeds[speed] def change_graphics(self, whichCharacters): """ Change the live and dead characters for the cells. :param whichCharacters: :return: whichCharacters """ if toolbox.is_integer(whichCharacters) and \ 1 <= int(whichCharacters) <= len(Cell.displaySets.keys()): whichCharacters = int(whichCharacters) else: print('**************************************') for number, set in enumerate(Cell.displaySets): liveChar = Cell.displaySets[set]['liveChar'] deadChar = Cell.displaySets[set]['deadChar'] print( f'{number+1}: living cells: {liveChar} dead cells: {deadChar}' ) print(f'{number + 2}: pick your own characters') print('**************************************') prompt = 'What character do you want to use?' whichCharacters = toolbox.get_integer_between( 1, number + 2, prompt) if whichCharacters == number + 2: alive = toolbox.get_string( 'Which character should represent alive cells?') dead = toolbox.get_string( 'Which character should represent dead cells?') Cell.set_display_user_values(alive, dead) setString = list(Cell.displaySets.keys())[whichCharacters - 1] Cell.set_display(setString) self.display() def set_geometry(self): userGeo = toolbox.get_integer_between( 1, 2, """ Choose 1 or 2: 1. bowl 2. torus""") self.__world.set_geometry(userGeo) print(self.__world, end='') print(self.status() + '\n' + self.menu(), end='') def random(self): """ Create a random world :return: world """ self.__world.randomize(self.__fillrate) self.display() def save(self, filename, myPath='./'): """ Save the current generation of the current world as a text file. :param filename: name of the file, may be None at this point. :param myPath: Where the file should be saved. :return: None """ if filename == None: filename = toolbox.get_string('What do you wanna call the file? ') # # Make sure the file has the correct file extension. # if filename[-5:] != '.life': filename = filename + '.life' # # if the path doesn't already exist, create it. # if not os.path.isdir(myPath): os.mkdir(myPath) # # Add on the correct path for saving files if the user didn't # include it in the filename. # if filename[0:len(myPath)] != myPath: filename = myPath + filename self.__world.save(filename) def open(self, filename, myPath='./'): """ open a text file and use it to populate a new world. :param filename: name of the file, may be None at this point. :param myPath: Where the file is located. :return: None """ if filename == None: filename = toolbox.get_string('Which file do you wanna open?') # # Check for and add the correct file extension. # if filename[-5:] != '.life': filename = filename + '.life' allFiles = os.listdir(myPath) if filename not in allFiles: print( '404: File not found...thanks for breaking the program, idiot.' ) else: # # Add on the correct path for saving files if the user didn't # include it in the filename. # if filename[0:len(myPath)] != myPath: filename = myPath + filename self.__world = World.from_file(filename) def change_size(self, parameter): if parameter and ('x' in parameter): rows, columns = parameter.split('x', 2) if toolbox.is_integer(rows) and toolbox.is_integer(columns): rows = int(rows) columns = int(columns) else: prompt = 'How many rows of cells?' rows = toolbox.get_integer_between(1, 40, prompt) prompt = 'How many cells in each row?' columns = toolbox.get_integer_between(1, 120, prompt) self.__world = World(rows, columns) self.random() def display(self): """ Prints the world, status bar and menu :return: None """ if self.__menu == 'main': print(self.__world, self.status() + '\n' + self.menu()) elif self.__menu == 'more': print(self.__world, self.status() + '\n' + self.menu_more()) def long_l_world(self): """Create a blank world and put this pattern in the middle: .... .x.. .x.. .x.. .xx. .... """ rows = self.__world.get_rows() columns = self.__world.get_columns() self.__world = World(rows, columns) middleRow = int(rows / 2) middleColumn = int(columns / 2) self.__world.set_cell(middleRow - 2, middleColumn, True) self.__world.set_cell(middleRow - 1, middleColumn, True) self.__world.set_cell(middleRow - 0, middleColumn, True) self.__world.set_cell(middleRow + 1, middleColumn, True) self.__world.set_cell(middleRow + 1, middleColumn + 1, True) self.display() def acorn_world(self): """Create a blank world and put this pattern in the middle: ......... ..x...... ....x.... .xx..xxx. ......... """ rows = self.__world.get_rows() columns = self.__world.get_columns() self.__world = World(rows, columns) middleRow = int(rows / 2) middleColumn = int(columns / 2) self.__world.set_cell(middleRow - 1, middleColumn - 2, True) self.__world.set_cell(middleRow - 0, middleColumn - 0, True) self.__world.set_cell(middleRow + 1, middleColumn - 3, True) self.__world.set_cell(middleRow + 1, middleColumn - 2, True) self.__world.set_cell(middleRow + 1, middleColumn + 1, True) self.__world.set_cell(middleRow + 1, middleColumn + 2, True) self.__world.set_cell(middleRow + 1, middleColumn + 3, True) self.display() def from_library(self, filename, myPath='./'): allFiles = os.listdir(myPath) if filename not in allFiles: for file in allFiles: print(file) if filename == None: filename = toolbox.get_string('Which world do you wanna use?') if filename[-5:] != '.life': filename = filename + '.life' else: if filename[0:len(myPath)] != myPath: filename = myPath + filename self.__world = World.from_file(filename)
class Life(object): speeds = [10, 7, 5, 3, 2, 1.5, 1, 0.75, 0.5, 0.25, 0.15, 0] def __init__(self): self.__world = World_Torus(17, 33) self.__fillrate = 25 self.__speed = 5 self.__delay = Life.speeds[self.__speed] self.__menu = 'main' self.__worldType = World_Torus self.random() self.__feedback = '' self.__lastWorld = '' def main(self): """Main event loop for Conway's game of life.""" command = 'help' parameter = None while command != 'quit': if command == 'help': if self.__menu == 'main': self.help('help.txt', 'Press <return> to continue.') elif self.__menu == 'more': self.help('help2.txt', 'Press <return> to continue.') if command == 'more menu': self.__menu = 'more' if command == 'back to main menu': self.__menu = 'main' elif command == 'run simulation': self.__feedback = '(Running....)' self.run_simulation(parameter) elif command == 'skip generations': self.skip_generations(parameter) elif command == 'random world': self.random() elif command == 'save world': self.save(parameter, './worlds/') elif command == 'open world': self.open(parameter, './worlds/') elif command == 'change fillrate': self.change_fillrate(parameter) elif command == 'change speed': self.change_speed(parameter) elif command == 'change size': self.change_size(parameter) elif command == 'change graphics': self.change_graphics(parameter) elif command == 'long l world': self.long_l_world() elif command == 'acorn world': self.acorn_world() self.display() command, parameter = self.get_command() print('goodbye') def menu(self): """returns a string containing the menu.""" return '[R]un s[K]ip [N]ew [S]ave [O]pen [M]ore [H]elp [Q]uit' def menu_more(self): """returns a string containing the menu.""" return 's[P]eed [D]elay s[I]ze [G]raphics [L]ong l [A]corn [H]elp [B]ack' def get_command(self): """Get a valid command from the user.""" commands = {'r': 'run simulation', 'k': 'skip generations', 'n': 'random world', 's': 'save world', 'o': 'open world', 'f': 'change fillrate', 'p': 'change speed', 'i': 'change size', 'g': 'change graphics', 'l': 'long l world', 'a': 'acorn world', 'm': 'more menu', 'b': 'back to main menu', 'h': 'help', '?': 'help', 'q': 'quit'} validCommands = commands.keys() userInput = '&' parameter = None while userInput[0].lower() not in validCommands: userInput = input('Command: ') if userInput == '': userInput = 'r' parameter = 1 command = commands[userInput[0].lower()] if len(userInput) > 1: parameter = userInput[1:].strip() return command, parameter def status(self): """Returns a string representing the status of the world.""" rows = self.__world.get_rows() columns = self.__world.get_columns() percentAlive = (self.__world.get_living_cell_count() / (rows * columns)) * 100 string = 'Status: ' # string += f'gen:{self.__generations} ' string += f'speed: {self.__delay} sec. ' string += f'size:[{rows}x{columns}] ' string += f'alive: {percentAlive:0.0f}% ' return string def help(self, filename, prompt=None): """Displays instructions.""" with open(filename, 'r') as file: help = file.read() print(help, end='') if prompt: input('\n' + prompt) def next_generation(self, parameter): """Displays the next generation of the world""" self.__world.next_generation() self.display() def run_simulation(self, generations): """Displays the next generation of the world""" if toolbox.is_integer(generations) and int(generations) > 0: generations = int(generations) else: prompt = 'How many generations would you like to simulate?' generations = toolbox.get_integer_between(1, 10000, prompt) for generation in range(generations): if self.__world.stop_simulation(): print('simulation is steady') break else: self.__world.next_generation() string = self.__world.__str__() string += self.status() string += f'left: {generations - generation}' print(string) # self.__generations += 1 time.sleep(self.__delay) print(self.menu()) def skip_generations(self, generations): """Displays the next generation of the world""" if toolbox.is_integer(generations) and int(generations) > 0: generations = int(generations) else: prompt = 'How many generations would you like to skip?' generations = toolbox.get_integer_between(1, 10000, prompt) print(f'Skipping {generations} generations.', end='') for generation in range(generations): self.__world.next_generation() if generation % 100 == 0: print('.', end='') print(' done!') self.__generations = generations time.sleep(2) self.display() def change_fillrate(self, fillrate): """Change the fillrate for the simulation.""" if toolbox.is_number(fillrate) and 0 <= float(fillrate) <= 100: fillrate = float(fillrate) else: prompt = 'What percent of cells should be alive?' fillrate = toolbox.get_integer_between(0, 100, prompt) self.__fillrate = fillrate self.random() def change_speed(self, speed): """Change the delay betwen generations of the simulation.""" if toolbox.is_number(speed): speed = int(speed) else: prompt = 'How fast should the generations update?' speed = toolbox.get_integer_between(0, 11, prompt) self.__delay = Life.speeds[speed] def change_graphics(self, whichCharacters): """Change the live and dead characters for the cells.""" if toolbox.is_integer(whichCharacters) and \ 1 <= int(whichCharacters) <= len(Cell.displaySets.keys()): whichCharacters = int(whichCharacters) else: print('**************************************') for number, set in enumerate(Cell.displaySets): liveChar = Cell.displaySets[set]['liveChar'] deadChar = Cell.displaySets[set]['deadChar'] print(f'{number + 1}: living cells: {liveChar} dead cells: {deadChar}') print(f'{number + 2}: pick your own characters') print('**************************************') prompt = 'What character set would you like to use?' whichCharacters = toolbox.get_integer_between(1, number + 2, prompt) if whichCharacters == number + 2: alive = toolbox.get_string('Which character should represent alive cells?') dead = toolbox.get_string('Which character should represent dead cells?') Cell.set_display_user_values(alive, dead) setString = list(Cell.displaySets.keys())[whichCharacters - 1] Cell.set_display(setString) self.display() def change_rules(self, parameter): """ Print possible display changes for the user. :param parameter: :return: none """ if toolbox.is_integer(parameter) and \ 1 <= int(parameter) <= len(Rules.ruleSets.keys()): setNumber = int(parameter) else: print('**************************************') for number, ruleSet in enumerate(Rules.ruleSets): bornNum = Rules.ruleSets[ruleSet]['bornNum'] surviveNum = Rules.ruleSets[ruleSet]['surviveNum'] print(f'{number+1}: Born Number: {bornNum} Survive Number: {surviveNum}') print(f'{number+2}: Choose your own characters! ') print('**************************************') prompt = 'What character set would you like to use?' setNumber = toolbox.get_integer_between(1, number + 2, prompt) numberOfSets = number + 2 if setNumber == numberOfSets: setString = 'choice' else: setString = list(rules.Rules.ruleSets.keys())[setNumber - 1] rules.Rules.set_rules(setString) print(self.__lastWorld, end='') def random(self): """Create a random world""" self.__world.randomize(self.__fillrate) self.display() def save(self, filename, myPath='./'): """ Save the current generation of the current world as a text file. :param filename: name of the file, may be None at this point. :param myPath: Where the file should be saved. :return: None """ if filename == None: filename = toolbox.get_string('What do you want to call the file? ') # # Make sure the file has the correct file extension. # if filename[-5:] != '.life': filename = filename + '.life' # # if the path doesn't already exist, create it. # if not os.path.isdir(myPath): os.mkdir(myPath) # # Add on the correct path for saving files if the user didn't # include it in the filename. # if filename[0:len(myPath)] != myPath: filename = myPath + filename self.__world.save(filename) def open(self, filename, myPath='./worlds'): """ open a text file and use it to populate a new world. :param filename: name of the file, may be None at this point. :param myPath: Where the file is located. :return: None """ if filename == None: filename = toolbox.get_string('Which file do you want to open?') # # Check for and add the correct file extension. # if filename[-5:] != '.life': filename = filename + '.life' allFiles = os.listdir(myPath) if filename not in allFiles: print('404: File not found...') else: # # Add on the correct path for saving files if the user didn't # include it in the filename. # if filename[0:len(myPath)] != myPath: filename = myPath + filename self.__world = self.__worldType.from_file(filename, self.__worldType) print(self.__world) def change_size(self, parameter): if parameter and ('x' in parameter): rows, columns = parameter.split('x', 2) if toolbox.is_integer(rows) and toolbox.is_integer(columns): rows = int(rows) columns = int(columns) else: prompt = 'How many rows of cells?' rows = toolbox.get_integer_between(1, 40, prompt) prompt = 'How many cells in each row?' columns = toolbox.get_integer_between(1, 120, prompt) self.__world = self.__worldType(rows, columns) self.random() def display(self): """ Prints the world, status bar and menu :return: None """ if self.__menu == 'main': print(self.__world, self.status() + '\n' + self.menu()) elif self.__menu == 'more': print(self.__world, self.status() + '\n' + self.menu_more()) def long_l_world(self): """Create a blank world and put this pattern in the middle: .... .x.. .x.. .x.. .xx. .... """ rows = self.__world.get_rows() columns = self.__world.get_columns() self.__world = self.__worldType(rows, columns) middleRow = int(rows / 2) middleColumn = int(columns / 2) self.__world.set_cell(middleRow - 2, middleColumn, True) self.__world.set_cell(middleRow - 1, middleColumn, True) self.__world.set_cell(middleRow - 0, middleColumn, True) self.__world.set_cell(middleRow + 1, middleColumn, True) self.__world.set_cell(middleRow + 1, middleColumn + 1, True) self.display() def acorn_world(self): """Create a blank world and put this pattern in the middle: ......... ..x...... ....x.... .xx..xxx. ......... """ rows = self.__world.get_rows() columns = self.__world.get_columns() self.__world = World(rows, columns) middleRow = int(rows / 2) middleColumn = int(columns / 2) self.__world.set_cell(middleRow - 1, middleColumn - 2, True) self.__world.set_cell(middleRow - 0, middleColumn - 0, True) self.__world.set_cell(middleRow + 1, middleColumn - 3, True) self.__world.set_cell(middleRow + 1, middleColumn - 2, True) self.__world.set_cell(middleRow + 1, middleColumn + 1, True) self.__world.set_cell(middleRow + 1, middleColumn + 2, True) self.__world.set_cell(middleRow + 1, middleColumn + 3, True) self.display() def change_geometry(self): string = '1. Flat World' string += '/n2. Torus World' print(string) choice = toolbox.get_integer_between(1, 2, 'Which geometry type would you like?: ') if choice == 1: self.__worldType = World else: self.__worldType = World_Torus