# CSE/ENGR 143
Homework #5 Turn-in Receipt

# 9825938

## Fitzpatrick, Brad J
bradfitz@bradfitz.com
Section AB

## Warning!

Your program did not compile successfully. We have accepted it, but you will get very few points for this homework. Here are the errors returned by the compiler:

Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.
ConsoleDisplay.cpp
DisplayInterface.cpp
Ghost.cpp
Mobile.cpp
Object.cpp
Pacster.cpp
Pellet.cpp
Space.cpp
User.cpp
Wall.cpp
World.cpp
Generating Code...
Microsoft (R) Incremental Linker Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
DisplayInterface.obj : error LNK2001: unresolved external symbol __imp__PlaySoundA@12
hw5.exe : fatal error LNK1120: 1 unresolved externals

### Turn-in logged at 99/05/26 13:01:46 PDT, Wednesday, May 26, 1999.

### We received the following. If this is not correct, use your web browser's "Back" button to return to the turn-in form, correct it, and try again.

- partner-firstname = Brad
- partner-middlename =
- partner-familyname = Emerson
- partner-email = bemerson@u.washington.edu
- partner-studentnumber = 9651244
- partner-section = AF
- system = Microsoft Visual C++ 5.0 (at home)
- systemother =
- optional-file1.cpp-tab = 4

### ##################################################

# optional-file1.cpp

Originally C:\users\brad\school\cse143\hw5\mod\ConsoleDisplay.cpp

### ##################################################

    // ConsoleDisplay.cpp: implementation of the ConsoleDisplay class.
    //
    //////////////////////////////////////////////////////////////////////

    #include "ConsoleDisplay.h"
    #include <stdio.h>

    //////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////

    //Default Constructor
    ConsoleDisplay::ConsoleDisplay()
    {
        width = def_display_width;
        height = def_display_height;

        screen = GetStdHandle( STD_OUTPUT_HANDLE );
        input = GetStdHandle( STD_INPUT_HANDLE );
        COORD window_size = { width + 2, height + 1 };
        SetConsoleScreenBufferSize( screen, window_size );
    }

    //Default Destructor
    ConsoleDisplay::~ConsoleDisplay()
    {
        CloseHandle( screen );
        CloseHandle( input );
    }

    //  Function receives coordinates and sprite_id, and draws
    //  appropriate ascii character at the x,y
    void ConsoleDisplay::DrawSprite(int bx, int by, int sprite_id)
    {
        char ch;
        WORD col = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;

        switch (sprite_id)
        {
            case SPRITE_PACMAN_UP:
            case SPRITE_PACMAN_DOWN:
            case SPRITE_PACMAN_LEFT:
            case SPRITE_PACMAN_RIGHT:
                col = FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY;
                ch = 'c';
                break;

            case SPRITE_PACMAN_DEAD:
                col = FOREGROUND_RED | FOREGROUND_INTENSITY;
                ch = 'c';
                break;

            case SPRITE_PACMAN_UP_FLASH:
            case SPRITE_PACMAN_DOWN_FLASH:
            case SPRITE_PACMAN_LEFT_FLASH:
            case SPRITE_PACMAN_RIGHT_FLASH:
                col = FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY;
                ch = 'C';
                break;

            case SPRITE_WALL:
                col = FOREGROUND_BLUE;
                ch = (char)178;
                break;

            case SPRITE_GHOST_1:
            case SPRITE_GHOST_2:
            case SPRITE_GHOST_3:
            case SPRITE_GHOST_4:
                col = FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSI
    TY;
                ch = (char)239;
                break;

            case SPRITE_PELLET:
                col = FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSI
    TY;
                ch = (char)250;
                break;

            case SPRITE_PELLET_SUPER:
                col = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
                ch = (char)233; //'o';  249
                break;

            case SPRITE_EMPTY:
            default:
                ch = ' ';
                break;
        }
        writexy(bx, by+2, ch, col);
    }

    //  Function updates menu section at top of screen
    void ConsoleDisplay::UpdateScoreStatus(int score) const
    {
        writexy(1, 0, "Score: ");
        writexy(8, 0, score);
    }

    //  Function updates menu section at top of screen
    void ConsoleDisplay::UpdateLivesStatus(int lives) const
    {
        writexy(13, 0, "Lives: ");
        for (int i=0; i<=lives; i++)
            writexy(20+i, 0, i==lives ? ' ' : 'C',
                FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY);
    }

    //  Function updates menu section at top of screen
    void ConsoleDisplay::UpdateLevelStatus(int level) const
    {
        char status[12];
        sprintf(status, "Level: %d ", level);
        writexy(30, 0, status);
    }

    //  Function enables user to write strings directly to the screen
    void ConsoleDisplay::DrawString (int bx, int by, const char *s)
    {
        writexy(bx, by, s);
    }

    //  Funtion simply writes blank lines over entire visible screen
    void ConsoleDisplay::clear()
    {
        char space[79];
        for (int i = 0; i < 80; i++)
            space[i] = ' ';

        DWORD word;
        for( int j = 0; j < height; j++ )
        {
            COORD position = { 0, j };
            WriteConsoleOutputCharacter( screen, (char *)&space, 79, position, &word );
        }
    }

    //  Function handles user input
    bool ConsoleDisplay::readchar( char &c, bool &quit )
    {
        quit = false;
        unsigned long eventsread;
        int err = GetNumberOfConsoleInputEvents( input, &eventsread );
        if( err == 0 || eventsread == 0 )
            return false;
        err = ReadConsoleInput( input, &ir, 1, &eventsread );
        if( err == 0 || eventsread != 1 || ir.EventType != KEY_EVENT ||
            ir.Event.KeyEvent.bKeyDown == false )
            return false;
        c = ir.Event.KeyEvent.uChar.AsciiChar;
        quit = (c=='q' || c=='Q' || c==27);
        return true;
    }

    // Returns the display width
    int ConsoleDisplay::get_width( )
    {
        return width;
    }

    // Returns the display height
    int ConsoleDisplay::get_height( )
    {
        return height;
    }

    //// PRIVATE

    // Write a character at a given x and y coordinate, default white color
    void ConsoleDisplay::writexy( int x, int y, char c ) const
    {
        writexy(x, y, c, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);

    //  COORD position = { x, y };
    //  DWORD word;
    //  WriteConsoleOutputCharacter( screen, &c, 1, position, &word );

    }

    void ConsoleDisplay::writexy( int x, int y, char c, WORD att) const
    {
        COORD position = { x, y };
        DWORD written;  // return spacce for WriteConsole

        SetConsoleTextAttribute(screen, att);
        SetConsoleCursorPosition( screen, position );
        WriteConsole( screen, &c, 1, &written, NULL);
    }

    // Write a string at a given x and y coordinate
    // if the string does not fit on the line, it will wrap around the screen
    void ConsoleDisplay::writexy( int x, int y, const char *s ) const
    {
        if( !( s == 0 || *s == '\0' ) ) {
            writexy( x, y, *s );
            if( x < width ) {
                writexy( x + 1, y, &s[1] );
            }
            else if( y < height ) {
                writexy( 1, y + 1, &s[1] );
            }
            else writexy( 1, 1, &s[1] );
        }
    }

    // Write an integer at a given x and y coordinate
    void ConsoleDisplay::writexy( int x, int y, int i ) const
    {
        char intstring[10];
        sprintf( intstring, "%d", i );
        writexy( x, y, intstring );
    }

    void ConsoleDisplay::pause( int time ) const
    {
        COORD topleft = { 0, 0 };

        //move cursor to upper-left part of screen
        SetConsoleCursorPosition( screen, topleft );
        Sleep( time );
    }

- optional-file2.cpp-tab = 4

### ##################################################

# optional-file2.cpp

Originally C:\users\brad\school\cse143\hw5\mod\ConsoleDisplay.h

### ##################################################

    // ConsoleDisplay.h: interface for the ConsoleDisplay class.
    //
    //////////////////////////////////////////////////////////////////////

    #ifndef _CONSOLEDISPLAY_H_
    #define _CONSOLEDISPLAY_H_

    #include "DisplayInterface.h"
    #include <windows.h>

    const int def_display_width = 78;  // default display width
    const int def_display_height = 24; // default display height

    class ConsoleDisplay : public DisplayInterface
    {
    public:
        ConsoleDisplay();
        virtual ~ConsoleDisplay();

        virtual void DrawSprite(int bx, int by, int obj_id);

        // Returns the display width
        virtual int get_width( );

        // Returns the display height
        virtual int get_height( );

        virtual void UpdateScoreStatus(int score) const;
        virtual void UpdateLivesStatus(int lives) const;
        virtual void UpdateLevelStatus(int level) const;

        virtual void DrawString (int bx, int by, const char *s);

        // Clears the screen
        virtual void clear();

        virtual bool readchar( char &c, bool &quit );

        // Pauses for a number of milliseconds
        virtual void pause( int time ) const;

    private:

        // Write a character at a given x and y coordinate
        void writexy( int x, int y, char c ) const;
        void writexy( int x, int y, char c, WORD att ) const;

        // Write a string at a given x and y coordinate
        // if the string does not fit on the line, it will wrap around the screen
        void writexy( int x, int y, const char *s ) const;

        // Write an integer at a given x and y coordinate
        void writexy( int x, int y, int i ) const;

        int width, height; // width and height of the screen
        HANDLE screen;     // output screen
        HANDLE input;      // input buffer
        INPUT_RECORD ir;   // input record

    };

    #endif

- optional-file3.cpp-tab = 4

### ##################################################

# optional-file3.cpp

Originally C:\users\brad\school\cse143\hw5\mod\DisplayInterface.cpp

### ##################################################

    #include "DisplayInterface.h"
    #include <windows.h>

    // Pauses for a number of milliseconds
    void DisplayInterface::pause( int time ) const
    {
        Sleep( time );
    }

    //  Uses windowsmm.lib, plays given .WAV file
    void DisplayInterface::PlayWAV ( const char *wav ) const
    {
        PlaySound(wav, NULL, SND_ASYNC | SND_FILENAME);
    }

    //  Uses windowsmm.lib, loops given .WAV file
    void DisplayInterface::LoopWAV ( const char *wav ) const
    {
        PlaySound(wav, NULL, SND_ASYNC | SND_FILENAME | SND_LOOP);
    }

    //  Uses windowsmm.lib, Stops all .WAVs
    void DisplayInterface::StopWAV ( ) const
    {
        PlaySound(NULL, NULL, 0);
    }

- optional-file4.cpp-tab = 4

### ##################################################

# optional-file4.cpp

Originally C:\users\brad\school\cse143\hw5\mod\DisplayInterface.h

### ##################################################

    // DisplayInterface.h: interface for the DisplayInterface class.
    //
    //////////////////////////////////////////////////////////////////////

    #ifndef _DISPLAYINTERFACE_H_
    #define _DISPLAYINTERFACE_H_

    #include <windows.h>

    const int SPRITE_EMPTY = 0;
    const int SPRITE_WALL = 10;
    const int SPRITE_PACMAN_UP = 20;
    const int SPRITE_PACMAN_UP_FLASH = 21;
    const int SPRITE_PACMAN_DOWN = 22;
    const int SPRITE_PACMAN_DOWN_FLASH = 23;
    const int SPRITE_PACMAN_LEFT = 24;
    const int SPRITE_PACMAN_LEFT_FLASH = 25;
    const int SPRITE_PACMAN_RIGHT = 26;
    const int SPRITE_PACMAN_RIGHT_FLASH = 27;
    const int SPRITE_PACMAN_DEAD = 29;
    const int SPRITE_GHOST_1 = 41;
    const int SPRITE_GHOST_2 = 42;
    const int SPRITE_GHOST_3 = 43;
    const int SPRITE_GHOST_4 = 44;
    const int SPRITE_PELLET = 50;
    const int SPRITE_PELLET_SUPER = 51;

    class DisplayInterface
    {
    public:
    //  DisplayInterface();
    //  virtual ~DisplayInterface();

        virtual void DrawSprite(int bx, int by, int sprite_id) = 0;

        // Returns the display width
        virtual int get_width( ) = 0;

        // Returns the display height
        virtual int get_height( ) = 0;

        virtual void UpdateScoreStatus(int score) const = 0;
        virtual void UpdateLivesStatus(int lives) const = 0;
        virtual void UpdateLevelStatus(int level) const = 0;

        virtual void DrawString (int bx, int by, const char *s) = 0;

        virtual void PlayWAV (const char *wav) const;
        virtual void StopWAV () const;
        virtual void LoopWAV (const char *wav) const;

        // Clears the screen
        virtual void clear( ) = 0;

        // Pauses for a number of milliseconds
        virtual void pause( int time ) const;

        virtual bool readchar( char &c, bool &quit ) = 0;

    };

    #endif

- optional-file5.cpp-tab = 4

### ##################################################

# optional-file5.cpp

Originally C:\users\brad\school\cse143\hw5\mod\Ghost.cpp

### ##################################################

    #include "Ghost.h"
    #include "User.h"
    #include <stdlib.h>

    // Default Constructor- draws ghost at given coordinates
    Ghost::Ghost( DisplayInterface &d, int x, int y, int _actingspeed,
                  Direction _direction ) : Mobile( _actingspeed, _direction )
    {
        d.DrawSprite( x, y, SPRITE_GHOST_1 );
    }

    // returns Ghost identity
    int Ghost::identify( )
    {
        return ghost_id;
    }

    // takes a turn to act in the world
    bool Ghost::act( DisplayInterface &d, World *w, int x, int y, int time )
    {
        if( time % actingspeed == 0 && lastmoved != time ) {
            lastmoved = time;
            int newx = x, newy = y;
            if( rand( ) % 2 == 0 ) {
                newx = x + rand( ) % 3 - 1;
            }
            else {
                newy = y + rand( ) % 3 - 1;
            }

            // Slightly intelligent ghosts-  move toward user if 1 or 2
            // postions away.
            if( w->get_object( x + 1, y )->identify( ) == user_id ) {
                newx = x + 1;
                newy = y;
            }
            if( w->get_object( x - 1, y )->identify( ) == user_id ) {
                newx = x - 1;
                newy = y;
            }
            if( w->get_object( x, y + 1 )->identify( ) == user_id ) {
                newx = x;
                newy = y + 1;
            }
            if( w->get_object( x, y - 1 )->identify( ) == user_id ) {
                newx = x;
                newy = y - 1;
            }
            if( w->get_object( x + 2, y )->identify( ) == user_id ) {
                newx = x + 1;
                newy = y;
            }
            if( w->get_object( x - 2, y )->identify( ) == user_id ) {
                newx = x - 1;
                newy = y;
            }
            if( w->get_object( x, y + 2 )->identify( ) == user_id ) {
                newx = x;
                newy = y + 1;
            }
            if( w->get_object( x, y - 2 )->identify( ) == user_id ) {
                newx = x;
                newy = y - 1;
            }
            if( newx != x || newy != y ) {
                switch( w->get_object( newx, newy )->identify( ) ) {
                case space_id: case pellet_id:
                    w->swap_object( d, x, y, newx, newy );
                    break;
                case user_id:
                    {
                        User *u = static_cast<User*>(w->get_object(newx, newy));
                        if (! u->is_super())
                        {
                            u->die( d, w, newx, newy );
                            return (w->GetLives() > 0);
                        }
                    }
                }
            }
        }
        return true;
    }

    // disappears from the world
    void Ghost::die( DisplayInterface &d, World *w, int x, int y ) { }

    // shows the object at its spot in the world
    void Ghost::show( DisplayInterface &d, World *w, int x, int y )
    {
        d.DrawSprite( x, y, SPRITE_GHOST_1 );
    }

- optional-file6.cpp-tab = 4

### ##################################################

# optional-file6.cpp

Originally C:\users\brad\school\cse143\hw5\mod\Ghost.h

### ##################################################

    /***

      Ghost class

    ***/

    #ifndef _GHOST_H_
    #define _GHOST_H_

    #include "DisplayInterface.h"
    #include "Globals.h"
    #include "World.h"
    #include "Object.h"
    #include "Mobile.h"

    class Ghost : public Mobile {
    public:

        // constructor
        Ghost( DisplayInterface &d, int x, int y, int _actingspeed, Direction _direction );

        // returns user identity
        virtual int identify( );

        // takes a turn to act in the world
        virtual bool act( DisplayInterface &d, World *w, int x, int y, int time );

        // disappears from the world
        virtual void die( DisplayInterface &d, World *w, int x, int y );

        // shows the object at its spot in the world
        virtual void show( DisplayInterface &d, World *w, int x, int y );

    };

    #endif

- optional-file7.cpp-tab = 4

### ##################################################

# optional-file7.cpp

Originally C:\users\brad\school\cse143\hw5\mod\Globals.h

### ##################################################

    /***

    Global Definitions for Pacster Package

    ***/

    #ifndef _GLOBALS_H_
    #define _GLOBALS_H_

    const int space_id = 1;  // returned by identify of space class
    const int wall_id = 2;   // returned by identify of wall class
    const int user_id = 3;   // returned by identify of user class
    const int ghost_id = 4;  // returned by identify of ghost class
    const int pellet_id = 5; // returned by identify of pellet class

    const int time_delay = 60;             // time delay constant
    const int pellet_die_time = 50;        // time for pellet to disappear
    const int show_user_death_time = 1000; // time to show the user's death

    const int user_speed = 3;  // speed of user (lower is faster)
    const int ghost_speed = 4; // speed of ghost (lower is faster)

    const int pellet_power_time_increment = 100;

    const int score_inc_eat_ghost = 5;  //Point value of eating ghost
    const int score_inc_new_life = 200; //Number of points/new life

    const int ending_sound_time = 1952;  // how long death sound takes

    enum Direction { NONE, NORTH, EAST, SOUTH, WEST };

    #endif

- optional-file8.cpp-tab = 4

### ##################################################

# optional-file8.cpp

Originally C:\users\brad\school\cse143\hw5\mod\Mobile.cpp

### ##################################################

- optional-file9.cpp-tab = 4

### ##################################################

# optional-file9.cpp

Originally C:\users\brad\school\cse143\hw5\mod\Mobile.h

### ##################################################

    /***

      Mobile class

    ***/

    #ifndef _MOBILE_H_
    #define _MOBILE_H_

    #include "DisplayInterface.h"
    #include "Globals.h"
    #include "World.h"
    #include "Object.h"

    class Mobile : public Object {
    public:

        Mobile( int _actingspeed, Direction _direction ) :
          Object( _actingspeed ) { direction = _direction; }

    protected:

        Direction direction; // current direction facing and moving
        int lastmoved;       // time stamp of last movement

    };

    #endif

- optional-file10.cpp-tab = 4

### ##################################################

# optional-file10.cpp

Originally C:\users\brad\school\cse143\hw5\mod\Object.cpp

### ##################################################

- optional-file11.cpp-tab = 4

### ##################################################

# optional-file11.cpp

Originally C:\users\brad\school\cse143\hw5\mod\Object.h

### ##################################################

    /***

      Object class

    ***/

    #ifndef _OBJECT_H_
    #define _OBJECT_H_

    #include "DisplayInterface.h"
    #include "Globals.h"
    #include "World.h"

    class World;

    class Object {
    public:

        // constructor
        Object( int _actingspeed ) { actingspeed = _actingspeed; }

        // returns object identity
        virtual int identify( ) = 0;

        // takes a turn to act in the world
        // returns false if the game should end
        virtual bool act( DisplayInterface &d, World *w, int x, int y, int time ) = 0;

        // disappears from the world
        virtual void die( DisplayInterface &d, World *w, int x, int y ) = 0;

        // shows the object at its spot in the world
        virtual void show( DisplayInterface &d, World *w, int x, int y ) = 0;

    protected:

        int actingspeed; // speed of object, acts when speed mod time is zero

    };

    #endif

- optional-file12.cpp-tab = 4

### ##################################################

# optional-file12.cpp

Originally C:\users\brad\school\cse143\hw5\mod\Pacster.cpp

### ##################################################

    /***

    Pacster Main Program

    ***/

    #include "ConsoleDisplay.h"
    #include "Globals.h"
    #include "World.h"
    #include "Object.h"
    #include <stdlib.h>
    #include <time.h>

    #include <iostream.h>

    //#include <afx.h>
    //#include <afxsock.h>

    void main( )
    {
    /*  CSocket cs;
        cs.Create();
        cs.Connect("localhost", 80);
        CSocketFile csf(&cs);

        csf << "HEAD / HTTP/1.0" << endl << endl;
        CString bob;
        bob << csf;
        bob >> cout;
        return;
    */

        srand( clock( ) );

        // our display interface way:
        ConsoleDisplay Screen;

        // old ghetto way:
        // Display Screen;

        World W( Screen );

        Screen.clear( );
        W.load( Screen, W.GetLevel() );
        while ( W.advance( Screen ) );

        // Ending sequence:  clear the screen and say goodbye
        Screen.clear();
        Screen.DrawString(0, 0, "Thanks for playing.");
    }

- optional-file13.cpp-tab = 4

### ##################################################

# optional-file13.cpp

Originally C:\users\brad\school\cse143\hw5\mod\Pellet.cpp

### ##################################################

    #include "Pellet.h"

    // constructor
    Pellet::Pellet( DisplayInterface &d, int x, int y, bool super ) : Object( 0 )
    {
        super_pellet = super;
        if (super_pellet)
            d.DrawSprite( x, y, SPRITE_PELLET_SUPER );
        else
            d.DrawSprite( x, y, SPRITE_PELLET );
    }

    // returns object identity
    int Pellet::identify( )
    {
        return pellet_id;
    }

    // takes a turn to act in the world; pellets do nothing
    bool Pellet::act( DisplayInterface &d, World *w, int x, int y, int time )
    {
        return true;
    }

    // disappears from the world
    void Pellet::die( DisplayInterface &d, World *w, int x, int y )
    {
    //  d.writexy( x, y, '+' );
        d.pause(pellet_die_time);
        d.DrawSprite( x, y, SPRITE_EMPTY );
    }

    // shows the object at its spot in the world
    void Pellet::show( DisplayInterface &d, World *w, int x, int y )
    {
        if (super_pellet)
            d.DrawSprite( x, y, SPRITE_PELLET_SUPER );
        else
            d.DrawSprite( x, y, SPRITE_PELLET );
    }

    bool Pellet::is_super ( ) const
    {
        return super_pellet;
    }

- optional-file14.cpp-tab = 4

### ##################################################

# optional-file14.cpp

Originally C:\users\brad\school\cse143\hw5\mod\Pellet.h

### ##################################################

    /***

      Pellet class

    ***/

    #ifndef _PELLET_H_
    #define _PELLET_H_

    #include "DisplayInterface.h"
    #include "Globals.h"
    #include "World.h"
    #include "Object.h"

    class Pellet : public Object {
    public:

        // constructor
        Pellet( DisplayInterface &d, int x, int y, bool super );

        // returns object identity
        virtual int identify( );

        // takes a turn to act in the world
        virtual bool act( DisplayInterface &d, World *w, int x, int y, int time );

        // disappears from the world
        virtual void die( DisplayInterface &d, World *w, int x, int y );

        // shows the object at its spot in the world
        virtual void show( DisplayInterface &d, World *w, int x, int y );

        // interface to get to is_super variable
        virtual bool is_super( ) const;

    private:

        bool super_pellet;

    };

    #endif

- optional-file15.cpp-tab = 4

### ##################################################

# optional-file15.cpp

Originally C:\users\brad\school\cse143\hw5\mod\Space.cpp

### ##################################################

    #include "Space.h"

    // constructor
    Space::Space( DisplayInterface &d, int x, int y ) : Object( 0 )
    {
        d.DrawSprite( x, y, SPRITE_EMPTY );
    }

    // returns object identity
    int Space::identify( )
    {
        return space_id;
    }

    // takes a turn to act in the world, space does nothing
    bool Space::act( DisplayInterface &d, World *w, int x, int y, int time )
    {
        return true;
    }

    // disappears from the world
    void Space::die( DisplayInterface &d, World *w, int x, int y ) { }

    // shows the object at its spot in the world
    void Space::show( DisplayInterface &d, World *w, int x, int y )
    {
        d.DrawSprite( x, y, SPRITE_EMPTY );
    }

- optional-file16.cpp-tab = 4

### ##################################################

# optional-file16.cpp

Originally C:\users\brad\school\cse143\hw5\mod\Space.h

### ##################################################

    /***

      Space class

    ***/

    #ifndef _SPACE_H_
    #define _SPACE_H_

    #include "DisplayInterface.h"
    #include "Globals.h"
    #include "World.h"
    #include "Object.h"

    class Space : public Object {
    public:

        // constructor
        Space( DisplayInterface &d, int x, int y );

        // returns object identity
        virtual int identify( );

        // takes a turn to act in the world
        virtual bool act( DisplayInterface &d, World *w, int x, int y, int time );

        // disappears from the world
        virtual void die( DisplayInterface &d, World *w, int x, int y );

        // shows the object at its spot in the world
        virtual void show( DisplayInterface &d, World *w, int x, int y );

    };

    #endif

- optional-file17.cpp-tab = 4

### ##################################################

# optional-file17.cpp

Originally C:\users\brad\school\cse143\hw5\mod\User.cpp

### ##################################################

    #include <iostream.h>
    #include "User.h"
    #include "Space.h"
    #include "Globals.h"
    #include "Pellet.h"

    #include <stdio.h>

    User::User( DisplayInterface &d, int x, int y, int _actingspeed,
                Direction _direction ) : Mobile( _actingspeed, _direction )
    {
        d.DrawSprite( x, y, SPRITE_PACMAN_RIGHT );

        super_time = 0;         // no eaten super pellet
        pacman_flash = false;
    }

    // returns user identity
    int User::identify( )
    {
        return user_id;
    }

    // takes a turn to act in the world:
    //  Determines movement of pacman in world
    bool User::act( DisplayInterface &d, World *w, int x, int y, int time )
    {
        if (super_time > 0)
            if (--super_time <= 0)
            {
                pacman_flash = false;
                d.StopWAV();
            }

    //  char intstring[10];
    //  sprintf( intstring, "%d ", super_time);
    //  d.DrawString(40,0,intstring);

        if( time % actingspeed == 0 && lastmoved != time ) {
            lastmoved = time;
            char c;
            bool quit = false;
            if (d.readchar(c, quit))
            {
                if (quit)
                    return false;

                switch( c ) {
                case 'q': case 'Q': case (char)27:
                    return false;
                    break;
                case 'a': case 'A':
                    direction = WEST;
                    break;
                case 'd': case 'D':
                    direction = EAST;
                    break;
                case 'w': case 'W':
                    direction = NORTH;
                    break;
                case 's': case 'S':
                    direction = SOUTH;
                    break;
                }
            }

            //Level wrapping...
            int newx = x + (direction == EAST ? 1 : 0) + (direction == WEST ? -1 : 0);
            if (newx < 0)
                newx = w->get_width()-1;
            if (newx > w->get_width()-1)
                newx = 0;

            int newy = y + (direction == NORTH ? -1 : 0) + (direction == SOUTH ? 1 : 0);
            if (newy < 0)
                newy = w->get_height()-1;
            if (newy > w->get_height()-1)
                newy = 0;

            if( newx != x || newy != y )
            {
                //alternates flash state, so pacman changes normal to super
                if (super_time > 0)
                    pacman_flash = ! pacman_flash;

                switch( w->get_object( newx, newy )->identify( ) )
                {
                case space_id:
                    w->swap_object( d, x, y, newx, newy );
                    break;
                case ghost_id:
                    if (super_time > 0)
                    {
                        // d.PlayWAV("eatghost.wav");
                        Object *o = w->get_object( newx, newy );
                        w->ChangeScoreBy(d, score_inc_eat_ghost);
                        o->die( d, w, newx, newy );
                        delete o;

                        //replace ghost with space and swap
                        Object *tmp = new Space( d, newx, newy );
                        w->set_object( d, newx, newy, tmp );
                        w->swap_object( d, x, y, newx, newy );
                    }
                    else
                    {
                        //die, and return true if remaining lives > 0
                        die( d, w, x, y );
                        return (w->GetLives() > 0);
                    }
                    break;
                case pellet_id:
                    {
                        if (super_time == 0)
                            d.PlayWAV("pellet.wav");
                        Pellet *p = static_cast<Pellet*>(w->get_object( newx, newy ));
                        if (p->is_super())
                        {
                            if (super_time == 0)
                                d.LoopWAV("powermusic.wav");
                            super_time += pellet_power_time_increment;
                        }
                        p->die( d, w, newx, newy );
                        delete p;

                        //replace pellet with space and swap
                        Object *tmp = new Space( d, newx, newy );
                        w->set_object( d, newx, newy, tmp );
                        w->swap_object( d, x, y, newx, newy );
                        w->ChangeScoreBy(d, 1);
                        w->AtePellet(d);
                        break;
                    }
                case wall_id:
                    if (super_time > 0)
                        this->show(d, w, x, y);
                    break;
                }  // end switch
            } // if
        }
        return true;
    }

    // disappears from the world
    void User::die( DisplayInterface &d, World *w, int x, int y )
    {
        w->UserDied(d, x, y);
    }

    // shows the object at its spot in the world
    void User::show( DisplayInterface &d, World *w, int x, int y )
    {
        if (pacman_flash)
            d.DrawSprite( x, y, SPRITE_PACMAN_RIGHT_FLASH );
        else
            d.DrawSprite( x, y, SPRITE_PACMAN_RIGHT );
    }

    // Returns true if SuperPellet has not run out
    bool User::is_super () const
    {
        return (super_time > 0);
    }

- optional-file18.cpp-tab = 4

### ##################################################

# optional-file18.cpp

Originally C:\users\brad\school\cse143\hw5\mod\User.h

### ##################################################

    /***

      User class

    ***/

    #ifndef _USER_H_
    #define _USER_H_

    #include "DisplayInterface.h"
    #include "Globals.h"
    #include "World.h"
    #include "Object.h"
    #include "Mobile.h"

    class User : public Mobile {
    public:

        // constructor
        User( DisplayInterface &d, int x, int y, int _actingspeed, Direction _direction );

        // returns user identity
        virtual int identify( );

        // takes a turn to act in the world
        virtual bool act( DisplayInterface &d, World *w, int x, int y, int time );

        // disappears from the world
        virtual void die( DisplayInterface &d, World *w, int x, int y );

        // shows the object at its spot in the world
        virtual void show( DisplayInterface &d, World *w, int x, int y );

        // interface to get to is_super variable
        virtual bool is_super( ) const;

    protected:

        char nkey, ekey, skey, wkey;

        int super_time;
        // Alternating bool for display
        bool pacman_flash;

    };

    #endif

- optional-file19.cpp-tab = 4

### ##################################################

# optional-file19.cpp

Originally C:\users\brad\school\cse143\hw5\mod\Wall.cpp

### ##################################################

    #include "Wall.h"

    // constructor
    Wall::Wall( DisplayInterface &d, int x, int y ) : Object( 0 )
    {
        d.DrawSprite( x, y, SPRITE_WALL);
    }

    // returns object identity
    int Wall::identify( )
    {
        return wall_id;
    }

    // takes a turn to act in the world
    bool Wall::act( DisplayInterface &d, World *w, int x, int y, int time )
    {
        return true;
    }

    // disappears from the world
    void Wall::die( DisplayInterface &d, World *w, int x, int y ) { }

    // shows the object at its spot in the world
    void Wall::show( DisplayInterface &d, World *w, int x, int y )
    {
        d.DrawSprite( x, y, SPRITE_WALL);
    }

- optional-file20.cpp-tab = 4

### ##################################################

# optional-file20.cpp

Originally C:\users\brad\school\cse143\hw5\mod\Wall.h

### ##################################################

    #ifndef _WALL_H_
    #define _WALL_H_

    #include "DisplayInterface.h"
    #include "Globals.h"
    #include "World.h"
    #include "Object.h"

    class Wall : public Object {
    public:

        // constructor
        Wall( DisplayInterface &d, int x, int y );

        // returns object identity
        virtual int identify( );

        // takes a turn to act in the world
        virtual bool act( DisplayInterface &d, World *w, int x, int y, int time );

        // disappears from the world
        virtual void die( DisplayInterface &d, World *w, int x, int y );

        // shows the object at its spot in the world
        virtual void show( DisplayInterface &d, World *w, int x, int y );

    };

    #endif

- optional-file21.cpp-tab = 4

### ##################################################

# optional-file21.cpp

Originally C:\users\brad\school\cse143\hw5\mod\World.cpp

### ##################################################

    /***

      World class

    ***/

    #include <iostream.h>
    #include <stdio.h>

    #include <fstream.h>
    #include "DisplayInterface.h"
    #include "Globals.h"
    #include "Object.h"
    #include "World.h"
    #include "Space.h"
    #include "Wall.h"
    #include "Pellet.h"
    #include "Mobile.h"
    #include "User.h"
    #include "Ghost.h"

    // default constructor
    World::World( DisplayInterface &d )
    {
        objects = 0;
        width = 0;
        height = 0;
        x = 0;
        y = 0;
        time = 0;

        lives = 3;
        score = 0;
        level = 1;
        new_lives = 0;

        pellets_in_world = 0;

        game_over = false;

        wallobject = new Wall( d, x, y );
    }

    // Change the score by given score_delta
    void World::ChangeScoreBy (DisplayInterface &d, int score_delta)
    {
        score += score_delta;

        // Incremants lives every time score_inc_new_life is reached
        if( (score / score_inc_new_life) > new_lives)
        {
            lives++;
            new_lives++;
            d.UpdateLivesStatus(lives);
            d.StopWAV();
            d.PlayWAV("newlife.wav");
        }

        d.UpdateScoreStatus(score);
    }

    void World::ChangeLivesBy (DisplayInterface &d, int lives_delta)
    {
        lives += lives_delta;
        // update the display
        d.UpdateLivesStatus(lives);
    }

    // Dafault load function used when first level is loaded
    //   (no previous world to load over)
    bool World::load( DisplayInterface &d, int level_number)
    {
        return load(d, level_number, NULL);
    }

    // returns true if a world was successfully loaded.
    // Allows a newer world to be laid on top of oldworld.  Retains
    // eaten pellets, redraws walls, ghost, spaces, and user
    bool World::load( DisplayInterface &d, int level_number, World *oldworld)
    {
        pellets_in_world = 0;

        // Level files will be in the format: "level01.txt"
        // Level number in form: 01, 02, 10, 50
        char filename[20];
        sprintf(filename, "level%02d.txt", level_number);

        ifstream in( filename, ios::nocreate | ios::in );
        if( !in ) return false;

        in >> width >> height;
        if (! oldworld)
        {
            // if reloading level, don't reallocate memory.
            // TODO: should ensure alloc'ed memory size still matches
            //       size of level.  somebody could've screwed with something.
            objects = new Object **[width];
            for( int k = 0; k < width; k++ )
            {
                objects[k] = new Object *[height];
            }
        }

        for( int j = 0; j < height; j++ )
        {
            for( int i = 0; i < width; i++ )
            {
                bool needshow = false;
                char c = '\n';
                // Allows for both Unix and Windows style end char
                while( c == '\n' || c == '\r')
                    in.get( c );
                switch( c ) {
                case 'X': case 'x':
                    if (oldworld)
                        needshow = true;
                    else
                        objects[i][j] = new Wall( d, i, j );
                    break;
                case ' ':
                    if (oldworld)
                    {
                        if (oldworld->objects[i][j]->identify() == pellet_id ||
                            oldworld->objects[i][j]->identify() == space_id)
                        {
                            needshow = true;
                        }
                        else
                        {
                            delete oldworld->objects[i][j];
                            objects[i][j] = new Space( d, i, j );
                        }
                    }
                    else
                        objects[i][j] = new Space( d, i, j );

                    break;
                case 'U': case 'u':
                    if (oldworld)
                        delete oldworld->objects[i][j];
                    objects[i][j] = new User( d, i, j, user_speed, NONE );
                    break;
                // captial O and capital zero (heh.. it's tall) are super pellets.
                // see the constructor?  yeah.
                case 'o': case '0': case 'O':
                    if (oldworld)
                    {
                        if (oldworld->objects[i][j]->identify() == space_id)
                        {
                            needshow = true;
                        }
                        else
                        {
                            delete oldworld->objects[i][j];
                            objects[i][j] = new Pellet (d, i, j, c!='o');
                            pellets_in_world++;
                        }
                    }
                    else
                    {
                        objects[i][j] = new Pellet( d, i, j, c!='o' );
                        pellets_in_world++;
                    }
                    break;
                case 'G': case 'g':
                    if (oldworld)
                        delete oldworld->objects[i][j];
                    objects[i][j] = new Ghost( d, i, j, ghost_speed, NONE );
                    break;
                default:
                    cout << "oh no " << c << endl;
                    cout << "terminate";
                    exit(1);
                }

                if (needshow)
                    objects[i][j]->show(d, this, i, j);
            }
        }

        x = 0;
        y = 0;

        time = 0;

        //Update the dislpay above gamemboard
        d.UpdateScoreStatus(score);
        d.UpdateLivesStatus(lives);
        d.UpdateLevelStatus(level);

        return true;
    }

    // acts on the current active object and advances to another object
    // Keeps track of time
    bool World::advance( DisplayInterface &d )
    {
        if (game_over)
            return false;

        if( x < width - 1 ) {
            x++;
        }
        else if( y < height - 1 ) {
            x = 0;
            y++;
        }
        else {
            x = 0;
            y = 0;
            time++;
            if( time > 100000 )
                time = 1;
            d.pause( time_delay );
        }
        return objects[x][y]->act( d, this, x, y, time );
    }

    // set the current active object
    void World::set_current( int _x, int _y )
    {
        x = _x;
        y = _y;
    }

    // return a pointer to a specified object
    Object *World::get_object( int _x, int _y )
    {
        if( _x < 0 || _x >= width || _y < 0 || _y >= height )
            return wallobject;
        return objects[_x][_y];
    }

    // sets an object in the world
    void World::set_object( DisplayInterface &d, int _x, int _y, Object *o )
    {
        objects[_x][_y] = o;
        objects[_x][_y]->show(d, this, _x, _y);
    }

    // swaps two objects in the world
    void World::swap_object( DisplayInterface &d, int x1, int y1, int x2, int y2 )
    {
        Object *tmp = objects[x1][y1];
        objects[x1][y1] = objects[x2][y2];
        objects[x2][y2] = tmp;
        objects[x1][y1]->show(d, this, x1, y1);
        objects[x2][y2]->show(d, this, x2, y2);
    }

    int World::GetLevel () const
    {
        return level;
    }

    int World::GetLives () const
    {
        return lives;
    }

    int World::GetScore () const
    {
        return score;
    }

    void World::UserDied (DisplayInterface &d, int dx, int dy)
    {
        // If user has no more lives, game terminates
        if (--lives <= 0)
        {
            d.PlayWAV("ending.wav");
            d.DrawSprite( dx, dy, SPRITE_PACMAN_DEAD);
            d.pause( show_user_death_time );
            d.clear( );
            d.DrawString( 2, 5, "GAME OVER!");
            d.pause( ending_sound_time );
        }
        else
        {
            // we still gots us lives.  reload level.  play again.
            d.PlayWAV("userdie.wav");

            //show bloody pacman
            d.DrawSprite( dx, dy, SPRITE_PACMAN_DEAD);
            d.pause( show_user_death_time );

            d.clear();
            d.DrawString(5,10,"You's Dead.  But you gots lives left.");
            d.pause ( show_user_death_time * 2);
            d.clear();

            //destroy();
            // Reload the level, with the old pellets remaining
            load(d, level, this);
        }
    }

    void World::AtePellet (DisplayInterface &d)
    {
        //If user ate all the pellets
        if (--pellets_in_world <= 0)
        {
            //destroy the old world, see if there is a new level to load
            destroy();
            if (! load(d, ++level))
            {
                d.clear();
                d.PlayWAV("userwin.wav");
                d.DrawString(2,5, "You won.  Yea'.");
                d.pause(5000);

                game_over = true;
            }
        }
    }

    // destructor
    World::~World( )
    {
        destroy( );
    }

    // destroys a world
    void World::destroy( )
    {
        //if object array is allready empty, then we're done
        if (! objects)
            return;

        for( int i = 0; i < width; i++ ) {
            for( int j = 0; j < height; j++ ) {
                delete objects[i][j];
            }
        }

        for( int k = 0; k < width; k++ ) {
            delete [] objects[k];
        }

        delete [] objects;
        // clean up pointers
        objects = NULL;
    }

- optional-file22.cpp-tab = 4

### ##################################################

# optional-file22.cpp

Originally C:\users\brad\school\cse143\hw5\mod\World.h

### ##################################################

    /***

      World class

    ***/

    #ifndef _WORLD_H_
    #define _WORLD_H_

    #include "DisplayInterface.h"
    #include "Globals.h"
    #include "Object.h"

    class Object;

    class World {
    public:

        World( DisplayInterface &d );

        // returns true if a world was successfully loaded
        bool load( DisplayInterface &d, int level_number);
        bool load( DisplayInterface &d, int level_number, World *oldworld);

        // acts on the current active object and advances to another object
        // returns the value that the current objects act routine returns
        bool advance( DisplayInterface &d );

        // set the current active object
        void set_current( int _x, int _y );

        // return a pointer to a specified object
        Object *get_object( int _x, int _y );

        // sets an object in the world
        void set_object( DisplayInterface &d, int _x, int _y, Object *o );

        // swaps two objects in the world
        void swap_object( DisplayInterface &d, int x1, int y1, int x2, int y2 );

        void ChangeScoreBy (DisplayInterface &d, int score_delta);
        void ChangeLivesBy (DisplayInterface &d, int lives_delta);

        int GetLevel () const;
        int GetLives () const;
        int GetScore () const;

        void AtePellet (DisplayInterface &d);
        void UserDied (DisplayInterface &d, int dx, int dy);

        int get_width( ) { return width; }

        int get_height( ) { return height; }

        // destructor
        ~World( );

    private:

        Object ***objects;  // objects in the world
        int width, height;  // width and height of the world
        int x, y;           // position of the active object in the world
        int time;           // time of the world
        Object *wallobject; // wall object to be returned to out of bounds queries

        int pellets_in_world;

        int lives;
        int score;
        int level;
        int new_lives;

        bool game_over;

        // destroys a world
        void destroy( );

        // copys from another world to this world
        void copy( const World &w );

    };

    #endif

- optional-file23.cpp-tab = 4

### ##################################################

# optional-file23.cpp

Originally

### ##################################################

- optional-file24.cpp-tab = 4

### ##################################################

# optional-file24.cpp

Originally

### ##################################################

- optional-file25.cpp-tab = 4

### ##################################################

# optional-file25.cpp

Originally

### ##################################################

- optional-file26.cpp-tab = 4

### ##################################################

# optional-file26.cpp

Originally

### ##################################################

- optional-file27.cpp-tab = 4

### ##################################################

# optional-file27.cpp

Originally

### ##################################################

- optional-file28.cpp-tab = 4

### ##################################################

# optional-file28.cpp

Originally

### ##################################################

- optional-file29.cpp-tab = 4

### ##################################################

# optional-file29.cpp

Originally

### ##################################################

- optional-file30.cpp-tab = 4

### ##################################################

# optional-file30.cpp

Originally

### ##################################################