Homework 4 - The Sand Class
Due by 11:59pm on 2023-10-18.
Starter Files
Download hw04.zip. Inside the archive, you will find starter files for the questions in this homework.
Topics
In Part 1 of the Sand Project, you solved the problem in a Functional Programming style. Your functions return new versions of the grid that you then used for the next steps. In this homework, we are going to get started on Part 2, and we are going to rewrite the program to use a more Object Oriented style of coding so that you can begin to get a feeling for how they differ. You already have your Grid class. In this Homework, you'll start on the Sand class. Instead of storing strings in the grid, we'll store Sand objects in the grid.
An object of the Sand class represents a single sand particle. Instead of having general functions that move sand, the Sand class will have methods that are responsible for moving itself and updating its position in the grid. Rocks will still be represented as a string with 'r'.
Required Questions
It might be worth having your code open from Part 1 of the Sand Project as reference.
Task 1 - Create a Sand class
Start by creating a new file Sand.py and in that file create a new Sand class. The __init__() method should take three parameters in addition to self: a reference to the Grid, and an initial x and y position. These latter two should have default values of zero so it should look like this:
def __init__(self, grid, x=0, y=0):
In the __init__() method, store the reference to the grid in a local variable and also create local variables for the x and y positions and store the passed in (or default) values.
Add a __str__() method that returns a string with the class name ("Sand") and the position of the particle like this:
Sand(<x>,<y>)
where <x> and <y> are the coordinates of the particles in the grid.
Task 2 - Finding where to move
Next let's add a gravity() method. This is similar to the do_gravity() function from Part 1 of the Sand Project; however, instead of actually moving the sand particle in the grid, it just returns the position the sand particle should move to. This method doesn't take any parameters and returns a tuple containing the x and y coordinates that the particle should move to. If there is no valid position to move to, the method should return None.
It follows the same rules as do_gravity() in Part 1, but since the Sand object knows its position, and has a reference to the grid, it doesn't need any parameters. It's method signature looks like this:
def gravity(self):
This method will need to call the is_move_ok() method. You should copy this function in to your class as a method of the class but it only needs two parameters, the x and y coordinates that you want to try to move to (x_to, and y_to) from the original version. The other three parameters are class variables so its signature looks like this:
def is_move_ok(self, x_to, y_to):
You can use the code from your functions in Part 1 here but you'll need to modify the code to use the class variables and have gravity() return the valid position to move to instead of moving the particle.
Reminder: Below is an image for a quick light reminder. Refer to the Sand Project for the sand movement rules if neccessary.
![]()
Recall that sand is now represented as objects or instances of the
Sandclass, while rocks are still represented as'r'. Also recall that theisinstance()function can be used to test if an object is in instance of a class.
Task 3 - Moving a particle
Next we will write the Sand object's move() method. This is similar to the do_move() function from Part 1 of the Sand project, but has to do a little more work to update both the internal data of the Sand object and the grid. This method takes in as its parameter a function that describes the rules for moving the object. We've only done simple gravity (our gravity() method above), but you could have other movement rules. Its signature looks like this:
def move(self, physics):
where physics is a function that returns a position to move to based on the objects current position. You can call physics anything you want, just remember that it's a function that handles the movement rules.
This function should do the following:
- Call
physics()to get the position to move to - If
physics()returns None, exit - Set the value in the grid at the particle's current position to
None - Update the
Sandobject's position (member variables) to the new position - Set the value in the
Gridto a reference to theSandobject (storeself)
Turn in your work
You'll submit both your Grid.py and Sand.py files on Canvas via Gradescope they it will be checked via the auto grader. We will be testing your program using a number of different data files. Make sure that you haven't "hard coded" anything specific to the test data we gave you. We do not guarantee that all scenarios are tested by the test data that we have provided you.