Introduction to Computer Programming

Program 2: Simple game REPL

Due date: Friday, September 29 at 5pm


Instructions


Guidelines

Unless explicitly indicated otherwise:


The assignment itself

  1. Complete function char_to_int(c) so that it returns a number between 0 and 9 corresponding to the character c assuming it is one of '0', '1', or ... '9'; if not, it returns None. Do not use the int() function (you are welcome to use the isdigit() method). Examples:

    >>> char_to_int('0')
    0
    >>> char_to_int('9')
    9
    >>> char_to_int('x') is None
    True
    >>> char_to_int('43') is None
    True
  2. Complete string_to_int(s) so that it returns a nonnegative integer corresponding to the string s assuming it consists entirely of the digits '0', '1', or ... '9'; if not, it returns None. Examples:

    >>> string_to_int('0')
    0
    >>> string_to_int('41933')
    41933
    >>> string_to_int('000041933')     # leading 0s are ok
    41933
    >>> string_to_int('-1') is None    # minus sign not allowed
    True
    >>> string_to_int('3.14') is None
    True
    >>> string_to_int('5x7') is None
    True
    >>> string_to_int('') is None
    True
  3. Complete read_number_in_range(start, stop) so that it returns a number between start (inclusive) and stop (exclusive) by repeatedly prompting the user for such a number until a valid one is provided. Example:

    >>> read_number_in_range(5, 12)
    Enter a value between 5 and 12: 19
    19 is out of range. Please try again.
    Enter a value between 5 and 12: x
    x is not a number. Please try again.
    Enter a value between 5 and 12: 3
    3 is out of range. Please try again.
    Enter a value between 5 and 12: 10
    10
  4. Fix get_board_size() so that it matches its specification: namely so that it returns column and row dimensions (as a pair of numbers) for the game board after asking for them via user input. It should verify that the dimensions are within the ranges specified by the MIN/MAX constants. Example:

    >>> get_board_size()
    
    Choose the number of columns. Enter a value between 5 and 40: 4
    4 is out of range. Please try again.
    Enter a value between 5 and 40: 40
    40 is out of range. Please try again.
    Enter a value between 5 and 40: hello
    "hello" is not a valid number. Please try again.
    Enter a value between 5 and 40: 35
    Choose the number of rows. Enter a value between 3 and 25: -33
    "-33" is not a valid number. Please try again.
    Enter a value between 3 and 25: 14
    (35, 14)
  5. Add an option to the main REPL so that the help command triggers the help() function to be called to generate the REPL response.

  6. Add an option to the main REPL so that if the users requests status, status_check(...) is called to generate the REPL response.

  7. Complete normalize_action(action) so it returns a string that represents a normalization of the action string. This should allow for case insensitivity and single-letter abbreviations. Examples:

     >>> normalize_action('East')
    'east'
     >>> normalize_action('e')
    'east'
     >>> normalize_action('STATUS')
     'status'
     >>> normalize_action('H')
     'help'
     >>> normalize_action('WhatEver')   # if action not valid command, still lowercased
     'whatever'
  8. Complete request_yes(prompt) that returns True if the user, given the string prompt, inputs yes or y (case insensitive). Returns False if the user enters no (or n, case insensitive). Repeats the request for user input until a valid yes or no is supplied. Examples:

    >>> request_yes('Keep playing? ')
    Keep playing? what?
    Enter "yes" or "no".
    Keep playing? ok
    Enter "yes" or "no".
    Keep playing? n
    False
    >>> request_yes('Need help? ')
    Need help? who me?
    Enter "yes" or "no".
    Need help? YES
    True
  9. Fix welcome so that it matches its specification. Examples:

    >>> welcome()
    Welcome to Find the Flag!
    
    Would you like to see the instructions? what?
    Enter "yes" or "no".
    Would you like to see the instructions? n
    
    >>> welcome()
    Welcome to Find the Flag!
    
    Would you like to see the instructions? yes
    
    Your goal is to find the flag hidden on one cell of an invisible
    grid in as few moves as possible.
    
    At the outset of the game...
  10. Modify the main REPL so that the cardinal direction actions work: namely, moving east, north, south or west, moves the player's row and column one position at a time. Be sure to only allow the move if the coordinates remain within the bounds of the game board. If a move is successful, the move counter should be increased by 1. Examples:

    %> e
    ok.
    
    %> s
    ok.
    
    %> status
    You are at row 5 and column 4.
    You are 5 units from the flag.
    You have made 2 moves so far.
    
    %> s
    ok.
    
    %> status
    You are at row 6 and column 4.
    You are 6 units from the flag.
    You have made 3 moves so far.
    
    %> s
    You cannot go that way.
    
    %> status
    You are at row 6 and column 4.
    You are 6 units from the flag.
    You have made 3 moves so far.
  11. Use the random.randrange(...) function to introduce randomness so that:

    1. the player's initial position is a random row and column within the range allowed by the game constants MIN_ROW, etc.
    2. the flag position is a random row and column, but such that it is at least MIN_DISTANCE away from the player's starting position. (Hint: use a while loop until the distance requirement is satisfied.)
  12. Implement winning: if the player reaches the flag, the game ends. For example:

    %> n
    Congratulations, you have captured the flag!
    You played a total of 5 moves.
    Thank you for playing.
  13. Implement losing: if the player fails to reach the flag before max_moves are exhausted, the game ends. The maximum number of moves can be computed in relation to the size of the board (you can choose precisely what that relation is). An example of losing:

    %> s
    Unfortunately, you have run out of time.
    You played a total of 8 moves.
    Thank you for playing.
  14. Add warmer/colder hints for the player so that when they move if they are getting closer to the flag they receive a "warmer" response, away from the flag, a "colder" response. Examples:

    %> e
       Warmer!
    %> s
       Warmer!
    %> s
       Colder.
    %> w
       Colder.
    %> e
       Warmer!
    %> e
       Warmer!
    %> e
       Warmer!
    %> n
    Congratulations, you have captured the flag!
    You played a total of 8 moves.
    Thank you for playing.

Extra credit

Implement functions scan_row, scan_column and scan_board according to their specification. Be sure to make each of them count for more than one move (otherwise the game is too easy to play)