33. Level 2 - Sand Grain#
In this topic, you will demonstrate your ability to use Python to perform: tests, while and for loops, list manipulations and 2d list.
To do this, you will create a simple automaton simulating the fall of sand grain.
In a few words, an automaton is a grid made up of cells. Each cell can take on different values. A cell will evolve over time based on the value it contains and the values in neighboring cells.
In our case, the rules are :
Sand falls down
Sand can’t go through walls
If the cell below is empty, the sand falls down. If the cell below is not empty, the sand goes to the right or left randomly. If the cell to the right and left is not empty, the sand stays in the same cell.
The world for our simulation is a list of lists containing the following symbols:
‘ ‘ empty cell
‘x’ sand grain
‘W’ wall cell
33.1. Creating the World#
33.1.1. Initialization#
Define two global variables WIDTH
and HEIGHT
that will be constants and represent the dimensions of our world. Initially, we will set them to small values for our tests.
Create a function init_world
that generates and returns a list of lists where each cell contains an empty string except the left and right columns and the bottom row. These cells are walls.
WIDTH = 10
HEIGHT = 5
def init_world():
# TO COMPLETE
world = init_world()
print(world)
Except output:
[['W', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'W'], ['W', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'W'], ['W', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'W'], ['W', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'W'], ['W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W']]
33.1.2. Displaying the World#
Add to our program a function intended to display the world in a rudimentary form. Later, we will improve this display.
Write a function print_world(world)
that takes as a parameter a list of lists representing an automaton and displays it in the terminal. A sand grain is represented using “░” and a wall using “█”.
def print_world(world):
# TO COMPLETE
world = init_world()
world[0][5] = "x"
print_world(world)
Excepted output:
█ ░ █
█ █
█ █
█ █
██████████
33.2. Evolution#
33.2.1. Next Position#
Create a function next_position(world, l, c)
which determines the position of a sand grain at the next step of the simulation. The function return a tuple of values.
If the cell below is empty, the sand falls down. If the cell below is not empty, the sand goes to the right or left randomly. If the cell to the right and left is not empty, the sand stays in the same cell.
def next_position(world, l, c):
# TO COMPLETE
world = init_world()
print(next_position(world, 0, 5))
print(next_position(world, 4, 5))
Expected output:
(1, 5)
(4, 5)
33.2.2. Updating the World#
We now implement a function update_world(world)
which update the position of sand grain, starting from the bottom row. The wall most not move.
def update_world(world):
# TO COMPLETE
world = init_world()
world[0][5] = "x"
print_world(world)
update_world(world)
print_world(world)
Expected output:
█ ░ █
█ █
█ █
█ █
██████████
█ █
█ ░ █
█ █
█ █
██████████
33.3. All Pieces Together#
You can now test your programm with the following main
function.
import time
def main():
w = init_world()
print_world(w)
w[0][5] = 'x'
for i in range(10):
if i % 5 == 0:
w[0][5]
update_world(w)
print_world(w)
time.sleep(0.2)
main()
33.4. Advanced Features#
Congratulations, you have reached the end of the guided part of this topic. You are now free to complete the project with any extension that you may imagine. This is an opportunity to show that you are now confident and can propose and develop new ideas independently.
Here are a few ideas:
There is a special ASCII character in Python that defines the color of the text displayed on a terminal. You could use it to change the color of the cell depending on their types.
You can imagine to add sand following special rules
Can we add wind?