CS 100  Programming I
Project 3

Revision Date: January 8, 2017

Printable Version


Preamble

You may develop your code on anywhere, but you must ensure it runs correctly on a Linux distribution before submission.

Jungle!

"Jungle love... it's driving me mad; it's making me crazy" - Refrain from Jungle Love, by the Steve Miller Band

Your task is to implement the game Jungle. Your program will play other programs by your classmates. You may learn about Jungle via this link:

http://en.wikipedia.org/wiki/Jungle_(board_game)

We will use the following variation. You may place your animals anywhere in the first three rows of your side of the board (except in the traps and den).

Program-to-program communication

The two competing programs will be designated player A or player B. When Player A starts up, it will:

At this point, Player A will not be able to display B's pieces. When Player B starts up, it will perform a manual pause until Player A has written its positions and moves files. Player B will then:

Player A will then:

Thereafter, each player, in turn:

This continues until a program captures the opponent's den or has captured all of the opponents pieces. When a capture is detected, each player should output details about the capture. Of course, a positions file only needs to be read once.

If a program is deemed to have purposefully corrupted the moves files, its authors will receive, at a minimum, a zero for the assignment and the incident will be filed under the UA and CS 100 academic misconduct policy for dismissal from the course with a failing grade. The same sanction applies for programs that read the opponent's position file before writing its own.

File formats

The positions files will look similar to:

    TIGER 0 0
    LION 0 6
    CAT 1 1
    DOG 1 5
    ELEPHANT 2 0
    WOLF 2 2
    LEOPARD 2 4
    MOUSE 2 6

The moves files will look similar to:

    MOUSE ahead
    ELEPHANT left
    TIGER back
    WOLF right

Note that animal names are to be written in all caps and the directions in all lowercase letters. Note also that a Player writes to the files from its perspective. When reading an opponents file, the locations and directions need to be converted to the reader's perspective: row 0 for the opponent becomes row 6 for the reader, and so on. The same is true for column numbers and directions; these values need to be converted as well.

Remember to close all files after appending to them!

Automating the action

Your program should pause at the very beginning if it is player B. The owner of the program will signal the program to continue. This is known as a manual pause.

Before reading the opponent's moves file, your program should pause. By default, the program should perform an automatic pause. When pausing automatically, your program waits until the write timestamp of the opponent's moves file changes before reading it. However, if a second command-line argument is given when starting the program, then the pause should not be automatic. Rather, the program should perform a manual pause before reading the opponent's moves file. After reading the file, the program should record the write time of the moves file.

Here is a possible pausing function (with supporting functions) that performs both kinds of pausing based upon a global boolean variable named manual:

    import os
    import time

    lastTime = None
    moveCount = None
    opponentMovesFile = None

    def pause():
        global moveCount
        print(Move " + moveCount + ": ",end="")
        if manual:
            userPause()
        else:
            autoPause()
        moveCount += 2

    def userPause():
        input(press Enter to continue...")

    def autoPause():
        time.sleep(0.5)
        while lastTime == os.path.getmtime(opponentMovesFile)
            time.sleep(0.1)

    def setLastTime()
        global lastTime
        lastTime = os.path.getmtime(opponentMovesFile)

The function setLastTime should be called after every time the opponent's moves file is read so that the variable lastTime is properly initialized by the time the pause function is called. Also, Player A needs to initialize moveCount to zero upon startup; Player B needs to initialize moveCount to one. Both players need to initial variables like opponentMovesFile.

Reading and writing to files

To read the moves files, you may use the Scanner class from previous assignments:

    wget troll.cs.ua.edu/cs100/python/projects/scanner.py

To write to a file, you will need to read Chapter 8 of your textbook. Make sure you open the moves file in append mode so you don't wipe out what's already there.

Command-line arguments

Your program shall be started with one or two command-line arguments. The first argument is the letter A or the letter B, designating player A or player B. Here is an example:

    python3  jungle.py  A

A second command-line argument, if present (it doesn't matter what the argument is), causes the system to wait for user input after each move before continuing. See the section on Automating the action for more information.

Stepwise Refinement

The stepwise refinement methodology of the previous programming assignment exhibited a top-down approach. In a to-down approach, the main function is sequentially refined until the project is finished. For this project, you should take a bottom-up approach, in which you start out by writing the most basic functions and then write higher-level functions that call these basic functions, and so on.

Level 0
Define a function that returns the last move in the opponent's move file. Test your function thoroughly so that you are convinced that they are working. Do this thorough testing for all functions you define.
Level 1
Define a function that appends a move to your moves file.
Level 2
Define a function that translates a row and column value from your opponent's perspective to your perspective. Define another function that translates a direction from your opponent's perspective to your perspective.
Level 3
Define a function that creates a board. A jungle board can be represented as a list of 9 lists, each 7 items long. Define another function that reads an opponents positions file and correctly positions those pieces on the board (make sure you translate from your opponents perspective to your perspective). Define a function that displays a jungle board in a nice way.
Level 4
Define a function that places your pieces on a board. Define a function that writes your position pieces to your positions file.
Level 5
Define a function that determines that returns the rank of an animal occupying a board location. Return sentinel values to indicate if the location is empty, water, trap, your trap, your den, your opponent's trap or your opponent's den. Define a function that determines if a move is legal or not. Illegal moves include:
Level 6
Define a function that, when given a board and a legal move, determines if two animals will end up on the same square. Define a function given two animals, determines which one would win if the animals are on the same square. Define a function the prints out capture information.
Level 7
Define a function that determines whether the current board represents a win or a loss for the player.
Level 8
Define a function that generates a legal move. To start with, this function can generate a random move. If the move is legal, return the move. Otherwise, try again. Define a function that, when given a board and a legal move, determines the new configuration of the board.
Level 9
Define a function for Player A that implements the actions to be performed at the very start. Define a function for Player B that implements the actions to be performed at the very start. Define a function that Player A uses after Player B starts. Define a function the implements a turn by a player. Place this last function in a loop. Exit the loop upon detecting an illegal move by your opponent or upon winning or losing the game. Weave all your functions into a working program.
Level 10 - Optional
Implement a simple strategy for generating the next move.
Level 11 - Optional
Implement more complex strategies for generating the next move.

Note, for each function you write at each level, you should use top-down stepwise refinement. That is to say, start with the simplest version of the function and successively add capability to the function. Save each program from each level.

Submission Instructions

Change to the directory containing your assignment and run the command:

    submit cs100 xxxx project3

Replace xxxx with your instructor's nixie login name.

lusth@cs.ua.edu