def main(): opts = get_commandline_options() world = generate_world(opts) report
ID: 3744767 • Letter: D
Question
def main():
opts = get_commandline_options()
world = generate_world(opts)
report_options(opts)
blit(world, patterns.glider, 20, 20)
run_simulation(opts, world)
if __name__ == '__main__':
main()
def run_simulation(opts, world):
"""
Accepts: opts -- a populated command line options class instance
world -- a 2D world pixel buffer generated by generate_world()
Returns: (Nothing)
Description: This function generates the plot that we will use as a
rendering surfance. 'Living' cells (represented as 1s in
the 2D world matrix) will be rendered as black pixels and
'dead' cells (represetned as 0s) will be rendered as
white pixels. The method FuncAnimation() accepts 4
parameters: the figure, the frame update function, a
tuple containing arguments to pass to the update function,
and the frame update interval (in milliseconds). Once the
show() method is called to display the plot, the frame
update function will be called every 'interval'
milliseconds to update the plot image (img).
"""
if not world:
print ("The 'world' was never created. Exiting")
sys.exit()
fig = plt.figure()
img = plt.imshow(world, interpolation='none', cmap='Greys', vmax=1, vmin=0)
ani = animation.FuncAnimation(fig,
update_frame,
fargs=(opts, world, img),
interval=opts.framedelay)
plt.show()
Task 3: Implementing the Update Rule Once the world has been generated and you have added a pattern or two using the blitter, you are ready to start the simulation this is done by calling run.simulation) run simulation (opts, vorld) This function creates a figure using matplotlib and plots each pixel in the world grid using the imshow function. Subsequently, FuncAnimation) is called fig ing ani pit. figure() plt, imshow(world, interpolation«,none, cmaP",Greys, vmax-1, vmin-o) = animation FuncAnimation(fig, undate-frama fargs-(opts, world, ing), interval-opts.framedelay) pltO The fourth argument supplied to FuncAnimation () specifies how frequently the plot should be automatically updated (in milliseconds. As you can see, this is set on the command line using the framedelay option (See Section 3 and get.commandline.options) in gameoflife.py). The second argument supplied to FuncAnimation) specifies the function that is called for each frame update. The third argument allows you to pass function parameters to the update function in the form of a tuple. In this case we are passing the opts, world, and img parameters to the update.frame ) function. This means that all you need to do to implement the update rule is implement the function update.frame() i def update frame (frame num, opts, orld, img): Accepts: frame num(automatically passed in) current frame number a populated command line options instance world -the 2D world p12el buffer img the plot image img. set array (world) new world 0 for row in world newworld. append (rou:) I YOUR CODE GOES HERE # Copy the contents of the new-world gnto the uorld # (i.e. make the future the present) worldl:] nw world: return img, Here, world contains the current world state, and nev.world will be used to hold the solution to applying If you look at the definition of the update function update.frame), you will notice that it accepts 4 parameters instead of 3. This is because the frame number is automatically passed in as the first argument when the update function is called. Any arguments passed in as a tuple through the third argument of FuncAnination) are passed in after the frame number argumentExplanation / Answer
#!/usr/bin/python
import patterns
import sys
import argparse
import random
from matplotlib import pyplot as plt
from matplotlib import animation
def generate_world(opts):
"""
Accepts: opts -- parsed command line options
Returns: world -- a list of lists that forms a 2D pixel buffer
Description: This function generates a 2D pixel buffer with dimensions
opts.cols x opts.rows (in pixels). The initial contents
of the generated world is determined by the value provided
by opts.world_type: either 'random' or 'empty' A 'random'
world has 10% 'living' pixels and 90% 'dead' pixels. An
'empty' world has 100% 'dead' pixels.
"""
world = []
## TASK 1 #############################################################
#
#
if opts.world_type == 'random':
for col in range(opts.cols):
#create temporary row before it's written to the world
tmp_row = []
#create requested number of rows
for row in range(opts.rows):
#each cell has a 10% probability of being alive
if random.random() <= 0.1:
tmp_row.append(1)
else:
tmp_row.append(0)
#append the temporary row to the world
world.append(tmp_row)
elif opts.world_type == 'empty':
#create empty world of requested dimensions
world = [[0 for i in range(opts.cols)] for j in range(opts.rows)]
#
#
#######################################################################
return world
def update_frame(frame_num, opts, world, img):
"""
Accepts: frame_num -- (automatically passed in) current frame number
opts -- a populated command line options instance
world -- the 2D world pixel buffer
img -- the plot image
"""
# set the current plot image to display the current 2D world matrix
img.set_array(world)
# Create a *copy* of 'world' called 'new_world' -- 'new_world' will be
# our offscreen drawing buffer. We will draw the next frame to
# 'new_world' so that we may maintain an in-tact copy of the current
# 'world' at the same time.
new_world = []
for row in world:
new_world.append(row[:])
## TASK 3 #############################################################
#
#
for row_idx, row in enumerate(world):
for col_idx, col in enumerate(row):
#index values of rows and colums surrounding current cell
# useful for calculating indexes of surrounding cells
# compensate for possibility of wrap-around
last_row_idx = (row_idx - 1) % len(world)
next_row_idx = (row_idx + 1) % len(world)
last_col_idx = (col_idx - 1) % len(row)
next_col_idx = (col_idx + 1) % len(row)
#get values of all 8 surrounding cells
top = world[last_row_idx][col_idx]
bottom = world[next_row_idx][col_idx]
left = world[row_idx][last_col_idx]
right = world[row_idx][next_col_idx]
top_left = world[last_row_idx][last_col_idx]
bottom_left = world[next_row_idx][last_col_idx]
top_right = world[last_row_idx][next_col_idx]
bottom_right = world[next_row_idx][next_col_idx]
#sum values of surrounding cells
cell_sum = top + bottom + left + right + top_left + bottom_left + top_right + bottom_right
curr_cell = world[row_idx][col_idx]
#use sum of surrounding cells to determine if cell lives or dies
if cell_sum > 3 or cell_sum < 2:
curr_cell = 0
elif cell_sum is 3:
curr_cell = 1
#write value to new_world (the frame buffer)
new_world[row_idx][col_idx] = curr_cell
#
#######################################################################
# Copy the contents of the new_world into the world
# (i.e. make the future the present)
world[:] = new_world[:]
return img,
def blit(world, sprite, x, y):
"""
Accepts: world -- a 2D world pixel buffer generated by generate_world()
sprite -- a 2D matrix containing a pattern of 1s and 0s
x -- x world coord where left edge of sprite will be placed
y -- y world coord where top edge of sprite will be placed
Returns: (Nothing)
Description: Copies a 2D pixel pattern (i.e sprite) into the larger 2D
world. The sprite will be copied into the 2D world with
its top left corner being located at world coordinate (x,y)
"""
## TASK 2 #############################################################
#
#
#iterate through each row in world
for row_idx, sprite_row in enumerate(sprite):
#iterate through each column in current row
for col_idx, curr_val in enumerate(sprite_row):
#find target indexes in world, and compensate for wrap-around
target_row = (row_idx + x) % len(world)
target_col = (col_idx + y) % len(world[0])
#assign value of current position in sprite to target position in world
world[target_row][target_col] = curr_val
#
#
#######################################################################
def run_simulation(opts, world):
"""
Accepts: opts -- a populated command line options class instance
world -- a 2D world pixel buffer generated by generate_world()
Returns: (Nothing)
Description: This function generates the plot that we will use as a
rendering surfance. 'Living' cells (represented as 1s in
the 2D world matrix) will be rendered as black pixels and
'dead' cells (represetned as 0s) will be rendered as
white pixels. The method FuncAnimation() accepts 4
update_frameters: the figure, the frame update function, a
tuple containing arguments to pass to the update function,
and the frame update interval (in milliseconds). Once the
show() method is called to display the plot, the frame
update function will be called every 'interval'
milliseconds to update the plot image (img).
"""
if not world:
print "The 'world' was never created. Exiting"
sys.exit()
fig = plt.figure()
img = plt.imshow(world, interpolation='none', cmap='Greys', vmax=1, vmin=0)
ani = animation.FuncAnimation(fig,
update_frame,
fargs=(opts, world, img),
interval=opts.framedelay)
plt.show()
def report_options(opts):
"""
Accepts: opts -- a populated command line options class instance
Returns: (Nothing)
Descrption: This function simply prints the parameters used to
start the 'Game of Life' simulation.
"""
print "Conway's Game of Life"
print "====================="
print " World Size: %i x %i" % (opts.rows, opts.cols)
print " World Type: %s" % (opts.world_type)
print " Frame Delay: %i (ms)" % (opts.framedelay)
def get_commandline_options():
parser = argparse.ArgumentParser()
parser.add_argument('-r', '--rows',
help='set # of rows in the world',
action='store',
type=int,
dest='rows',
default=50)
parser.add_argument('-c', '--columns',
help='set # of columns in the world',
action='store',
type=int,
dest='cols',
default=50)
parser.add_argument('-w', '--world',
help='type of world to generate',
action='store',
type=str,
dest='world_type',
default='empty')
parser.add_argument('-d', '--framedelay',
help='time (in milliseconds) between frames',
action='store',
type=int,
dest='framedelay',
default=100)
opts = parser.parse_args()
return opts
def main():
"""
The main function -- everything starts here!
"""
opts = get_commandline_options()
world = generate_world(opts)
report_options(opts)
blit(world, patterns.glider, 20, 20)
run_simulation(opts, world)
if __name__ == '__main__':
main()
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.