Section 1. Karel the Robot


This week in section, your first priority is to meet your section leader and discover what sections in CS106A are all about. Your section leader will therefore spend the first part of section on introductions and course logistics. Afterwards, you'll solve some Karel problems using decomposition and stepwise refinement.

Here’s the Section 1 starter code. You'll unzip/extract this file and open it in PyCharm just like you did with your Assignment 1 starter code.

1. Hospital Karel

Countries around the world are dispatching hospital-building robots to make sure anyone who gets sick can be treated. They have decided to enlist Karel robots, and your job is to program those robots.

Karel begins at the left (west) end of a row that might look like this:

Karel's starting state for hospital karel, on the bottom left of the world facing east, with beepers placed along the path.

Each beeper in the figure represents a pile of supplies. Karel's job is to walk along 1st Street and build a new hospital in the places marked by each beeper. The new hospital should be centered at the point at which the bit of debris was left, which means that the first hospital in the diagram above will be constructed with its left edge along 2nd Avenue, since the beeper was originally at 3rd Avenue.

At the end of the run, Karel should be at the east end of 1st street having created a set of hospitals that look like this for the initial conditions shown above:

Karel's end state, in place of each beeper is a 'hospital' which is three sets of three columns of stacked beepers, each 3 beepers tall, with the middle column of beepers shifted up one place from the left and right columns

Keep in mind the following information about the world:

  1. Karel starts facing east at (1, 1) with an infinite number of beepers in its beeper bag.
  2. The beepers indicating the positions at which hospitals should be built will be spaced so that there is room to build the hospitals without overlapping or hitting walls.
  3. You will not have to build a hospital that starts in either of the last two columns.
  4. Karel should not crash into a wall if it builds a hospital that ends in the final corner.

Write the code to implement Hospital Karel. Use helper functions. Think, "what are the high-level steps Karel needs to take?" and make these steps into helper functions. Remember that your program should work for any world that meets the above conditions.

If you're working in the starter project, write your code in the main() function of HospitalKarel.py. To test your code, open the terminal and enter:

python3 HospitalKarel.py

(replace python3 with py or python if you're using Windows).

"""
Program: Hospital Karel
Karel traverses 1st street from west to east, building hospitals
wherever it encounters a beeper.
"""

def turn_around():
    turn_left()
    turn_left()

def turn_right():
    turn_left()
    turn_left()
    turn_left()

def back_up():
    turn_around()
    move()
    turn_around()

def move_to_wall():
    while front_is_clear():
        move()

def return_to_base():
    """
    Karel turns around and goes to the wall.
    Pre-condition: Karel is at the end of the column
        it just built, facing north.
    Post-condition: Karel has returned to 1st Street,
        below the column is just built, facing south.
    """
    turn_around()
    move_to_wall()

def put_three_beepers():
    """
    Karel places three beepers in a row.
    Pre-condition: Karel is on the corner where we want
        to place the first beeper.
    Post-condition: Karel is on the corner where it
        placed the third beeper in a row.
    """
    put_beeper()
    move()
    put_beeper()
    move()
    put_beeper()

def do_one_column():
    """
    Karel builds a single column of a hospital.
    Pre-condition: Karel is facing east at the bottom
        of where we want to build a column.
    Post-condition: Karel is facing east at the bottom
        of the column it just built.
    """
    turn_left()
    put_three_beepers()
    return_to_base()
    turn_left()

def build_hospital():
    """
    Karel picks up supplies and builds a hospital.
    Pre-condition: Karel is on a beeper, representing a
        pile of supplies. Karel is facing east.
    Post-condition: Karel is standing at the bottom
        of the last column of the hospital, facing east.
    """
    # pick up supplies
    pick_beeper()
    back_up()
    # make hospital
    do_one_column()
    move()
    turn_left()
    move()
    turn_right()
    do_one_column()
    move()
    do_one_column()

def main():
    while front_is_clear():
        if beepers_present():
            build_hospital()
        if front_is_clear():
            move()

2. Karel Defends Democracy

The 2000 U.S. Presidential Election was plagued by the hanging-chad problem. To vote, voters punched columns out of a paper ballot, but if they only punched partially, the column was left hanging. This can lead to incorrect counts and recounts!

In Karel's world, a ballot consists of a series of columns that a voter can ā€œpunch outā€. Karel starts on the left of a ballot and should progress through each column. If a column contains a beeper in the center row, the voter did not intend to vote on that column, and Karel should move to the next column. However, if a column contains no beeper in the center row, Karel must make sure that there is no hanging chad. In other words, Karel should check the corners above and below and remove any beepers. A corner may contain any number of beepers. Karel must finish facing east at the rightmost edge of the ballot

An example initial world is shown on the left below. The world on the right below shows what Karel's final world should look like (when given the initial world on the left).

Democracy karel start and end states. Karel fills in each column by fixing the hanging chad.

Keep in mind the following information about the world:

  1. Karel starts facing east at (1, 2) with an infinite number of beepers in its beeper bag.
  2. Karel must end up facing east at the end of 2nd street.
  3. The world consists of an arbitrary number of 3-height columns, and Karel can travel along the middle row without hitting a wall.

Write the code to implement Democracy Karel. Use helper functions. Think, "what are the high-level steps Karel needs to take?" and make these steps into helper functions. Remember that your program should work for any world that meets the above conditions.

If you're working in the starter project, write your code in the main() function of DemocracyKarel.py. To test your code, open the terminal and enter:

python3 DemocracyKarel.py

(replace python3 with py or python if you're using Windows).

"""
Program: Democracy Karel
Karel traverses a ballot from left to right, removing the 
"hanging chads".
"""

def turn_around():
    turn_left()
    turn_left()

def back_up():
    turn_around()
    move()
    turn_around()

def remove_beepers_front():
    """
    Clears chad from whichever corner Karel is facing.
    Pre-condition: Karel is facing a corner to be cleared of 
        the chad (beepers).
    Post-condition: Karel is in the same location/orientation,
        but the chad has been cleared from the corner Karel 
        is facing.
    """
    move()
    while beepers_present():
        pick_beeper()
    back_up()

def remove_chad():
    """
    Clears chad from the current column.
    Pre-condition: Karel is standing in the center of a 
        column to be cleared, facing east.
    Postcondition: Karel is standing in the same place/
        orientation and the column has been cleared.
    """
    # clean upper corner
    turn_left()
    remove_beepers_front()
    turn_around()
    # clean lower corner
    remove_beepers_front()
    turn_left()

def process_column():
    """
    Clears chad from the current column, if any.
    Pre-condition: Karel is standing in the center of a column, 
        facing east. 
    Post-condition: Karel is back in the same place/orientation
        and chad (if any) has been cleared.
    """
    if no_beepers_present():
        remove_chad()

def main():
    while front_is_clear():
        process_column()
        move()
    # handles fencepost problem for last column
    process_column()