first commit

This commit is contained in:
Jose Caban
2025-06-07 01:59:34 -04:00
commit 388ac241f0
3558 changed files with 9116289 additions and 0 deletions

View File

@@ -0,0 +1,275 @@
/**
* CS1312 Lab #17 - The Model.
* <PRE>
* Calculator.java - A basic calculator.
*
* Revisions: 1.1 Mar. 14, 2001
* Added minor modifications to calculation behavior. Added
* some documentation.
* 1.0 Jan. 11, 2001
* Created the Calculator class
*
* </PRE>
*
* @author <A HREF="mailto:demox@cc.gatech.edu">Luke A. Olbrish</A>
* @version Version 1.1, Mar. 14, 2001
*/
public class Calculator
{
// Constants
/**
* This constant denotes the use of the clear operation.
*/
public static final int CLR_OP = 0;
/**
* This constant denotes the computation operation.
*/
public static final int EQL_OP = 1;
/**
* This constant denotes that addition should be used.
*
* @see #DIV_OP
* @see #MUL_OP
* @see #SUB_OP
*/
public static final int ADD_OP = 2;
/**
* This constant denotes that subtraction should be used.
*
* @see #ADD_OP
* @see #DIV_OP
* @see #MUL_OP
*/
public static final int SUB_OP = 3;
/**
* This constant denotes that multiplication should be used.
*
* @see #ADD_OP
* @see #DIV_OP
* @see #SUB_OP
*/
public static final int MUL_OP = 4;
/**
* This constant denotes that division should be used.
*
* @see #ADD_OP
* @see #MUL_OP
* @see #SUB_OP
*/
public static final int DIV_OP = 5;
// Data Block
/**
* Status variable that determines if operator1 is in an initialized form.
*
* @see #isOperator2Set
* @see #operator1
*/
private boolean isOperator1Set = false;
/**
* The value of the first operator.
*
* @see #isOperator1Set
* @see #operator2
*/
private int operator1 = Integer.MIN_VALUE;
/**
* Status variable that determines if operator2 is in an initialized form.
*
* @see #isOperator1Set
* @see #operator2
*/
private boolean isOperator2Set = false;
/**
* The value of the second operator.
*
* @see #isOperator2Set
* @see #operator1
*/
private int operator2 = Integer.MIN_VALUE;
/**
* Status variable that determines if the operation is in an initialized
* form.
*
* @see #operation
*/
private boolean isOperationSet = false;
/**
* The value of the math operation.
*
* @see #isOperationSet
*/
private int operation = Integer.MIN_VALUE;
// Accessors
/**
* Reports whether the operation has been set yet.
*
* @see #isOperator1Set
* @see #isOperator2Set
*/
public boolean isOperationSet()
{
return this.isOperationSet;
}// end of isOperationSet()
/**
* Reports whether operation 1 has been set yet.
*
* @see #isOperationSet
* @see #isOperator2Set
*/
public boolean isOperator1Set()
{
return this.isOperator1Set;
}// end of isOperator1Set()
/**
* Reports whether operation 2 has been set yet.
*
* @see #isOperationSet
* @see #isOperator1Set
*/
public boolean isOperator2Set()
{
return this.isOperator2Set;
}// end of isOperator2Set()
/**
* Gets the calculation of the operators and operation if possible. If
* only operator1 is initialized, then operator1 is returned. If
* non of the operators or operation are initialized than an Arithmetic
* Exception is thrown.
* <BR><BR>
*
* @exception ArithmeticException
* @return an integer representing the calculation of the operators and the
* operation.
*/
public int getCalculation() throws ArithmeticException
{
int returnVal = Integer.MIN_VALUE;
// check to see if operators and operation are initialized.
if(( !isOperationSet ) ||
( !isOperator2Set ))
{
if( isOperator1Set )
return operator1;
else
throw new ArithmeticException( "Not Enough Information" );
}// end of if
// Do the proper operation based upon the operation constant.
switch( operation )
{
case ADD_OP:
returnVal = operator1 + operator2;
break;
case SUB_OP:
returnVal = operator1 - operator2;
break;
case MUL_OP:
returnVal = operator1 * operator2;
break;
case DIV_OP:
returnVal = operator1 / operator2;
break;
default:
throw new ArithmeticException( "Not Enough Information" );
}// end of switch( int )
// reset the data
isOperator1Set = false;
operator1 = Integer.MIN_VALUE;
isOperator2Set = false;
operator2 = Integer.MIN_VALUE;
isOperationSet = false;
operation = 0;
return returnVal;
}// end of getCalculation()
// Modifiers
/**
* Sets the first operator. This function will also set a flag that
* indicates that the operator has a valid value.
* <BR><BR>
*
* @param operator1 the new value of the first operator
*/
public void setOperator1( int operator1 )
{
this.isOperator1Set = true;
this.operator1 = operator1;
}// end of setOperator1( int )
/**
* Sets the second operator. This function will also set a flag that
* indicates that the operator has a valid value.
* <BR><BR>
*
* @param operator2 the new value of the second operator
*/
public void setOperator2( int operator2 )
{
this.isOperator2Set = true;
this.operator2 = operator2;
}// end of setOperator2( int )
/**
* Sets the math operation. This function will also set a flag that
* indicates that the operation has a valid value.
* <BR><BR>
*
* @param operation the new value of the operation
*/
public void setOperation( int operation )
{
if(( !isOperator1Set ) ||
(( this.operation >= ADD_OP ) &&
( this.operation <= DIV_OP )))
return;
this.isOperationSet = true;
this.operation = operation;
}// end of setOperation( int )
// Operational Functions
/**
* This function clears all information from the calculator. It will reset
* the calculator to the state that it was when it was first created.
* <BR><BR>
*/
public void clearCalulator()
{
// Reset all information back to the default state.
isOperator1Set = false;
operator1 = Integer.MIN_VALUE;
isOperator2Set = false;
operator2 = Integer.MIN_VALUE;
isOperationSet = false;
operation = 0;
}// end of clearCalculator
}// end of class Calculator

View File

@@ -0,0 +1,192 @@
/**
* <PRE>
* CalculatorGUI.java
*
* Revisions: 1.1 Mar. 14, 2001
* Added minor modifications to calculation behavior. Added
* some documentation.
* 1.0 Jan. 11, 2001
* Created the CalculatorGUI class
*
* </PRE>
*
* @author <A HREF="mailto:demox@cc.gatech.edu">Luke A. Olbrish</A>
* @version Version 1.0, Jan. 11, 2001
*/
// I must import java libraries in order to work with swing.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CalculatorGUI
{
/**
* The main frame of the program. This will contain all of the other
* gui components.
*/
private JFrame guiFrame = null;
/**
* This panel will be the only component directy added to the frame.
* Instead, this panel will be where all other gui components will be added.
*/
private Container contentPane = null;
/**
* This label will be used as the display for the numbers of the calculator.
* The label will be placed in the top of the contentPane.
*/
private JLabel numberLabel = null;
/**
* This panel is where the operator and digit buttons will be placed. It
* will be the main content of the contentPane.
*/
private JPanel buttonPanel = null;
/**
* This panel will contain the clear and equal buttons. It will be in the
* lower section of the content pane.
*/
private JPanel operationPanel = null;
/**
* This array, which will be of size 10. It will hold 10 digit buttons.
*/
private JButton[] numberedButtons = null;
/**
* This array, which will be of size 6. It will hold the operations.
*/
private JButton[] operationButtons = null;
/**
* This is the control for the program. It will handle all events that
* occur in this gui.
*/
private EventHandler event = null;
// Constructors
public CalculatorGUI()
{
doMakeObjects();
doAddObjects();
doCustomizations();
doEventHandling();
// This sets the size of the screen based on the preferred size of the
// GUI components.
guiFrame.pack();
guiFrame.setVisible( true );
}// end of constructor()
// Constructor Helpers
/**
* This function will create all of the components that are needed for the
* gui. It should initialize the guiFrame, contentPane, buttonPanel,
* operationPanel, numberLabel, numberedButtons, and operationButtons.
* You should also set your layouts here.
*/
public void doMakeObjects()
{
// ### Add your code here. ####
guiFrame.getContentPane().setLayout(new BorderLayout());
// ### Done ###
}// end of doMakeObjects()
/**
* This function is where you should add the components. You should add
* the numberedButtons and +, -, *, / to buttonPanel. Clr and = should
* be added to operationPanel. numberLabel should be added to the top of
* the contentPane, buttonPanel to the center, and operationPanel to the
* bottom.
*/
public void doAddObjects()
{
guiFrame.setContentPane( contentPane );
// ### Add your code here. ####
// ### Done ###
}// end of doAddObjects()
/**
* This is where you should set the background colors for the buttons.
* You should also increase the label's font size and prevent all the
* buttons from having their focus be painted.
*/
public void doCustomizations()
{
// ### Add your code here. ####
// ### Done ###
}// end of doCustomizations()
public void doEventHandling()
{
// Add the event handler that will monitor events from this GUI.
event = new EventHandler( this );
// Make event respond to button presses on the numbers from the GUI.
for( int x = 0; x < 10; x++ )
numberedButtons[x].addActionListener( event );
// Make event respond to button presses on the other buttons from the
// GUI.
for( int x = 0; x < 6; x++ )
operationButtons[x].addActionListener( event );
// This is a specialized way of creating a class that will handle
// window frame events. More on this in the next lab...
guiFrame.addWindowListener( new WindowAdapter()
{
public void windowClosing( WindowEvent we )
{
System.exit( 0 );
}// end of windowClosing( WindowEvent )
});// end of WindowAdapter inner class
}// end fo doEventHandling()
// Accessors
/**
* This function should return the text from the numberLabel.
*
* @return the contents of numberLabel.
*/
public String getDisplay()
{
// ### Add your code here. ####
return numberLabel.getText();
// ### Done ###
}// end of getDisplay()
// Modifiers
/**
* This function should set the text in numberLabel.
*
* @param value the string to set as the text for numberLabel
*/
public void setDisplay( String value )
{
// ### Add your code here. ####
numberLabel.setText(value);
// ### Done ###
}// end of setDisplay( String )
/**
* The driver for the program.
*
* @param args a String array of arguements.
*/
public static void main( String[] args )
{
CalculatorGUI gui = new CalculatorGUI();
}// end of main( String[] )
}// end of class CalculatorGUI

View File

@@ -0,0 +1,207 @@
/**
* <PRE>
* EventHandler.java
*
* Revisions: 1.1 Mar. 14, 2001
* Added minor modifications to event handling behavior. Added
* some documentation.
* 1.0 Jan. 13, 2001
* Created the EventHandler class
*
* </PRE>
*
* @author <A HREF="mailto:demox@cc.gatech.edu">Luke A. Olbrish</A>
* @version Version 1.0, Jan. 13, 2001
*/
import java.awt.event.*;
public class EventHandler implements ActionListener
{
// Data Block
/**
* The actual gui that will be the view for this program.
*/
private CalculatorGUI gui = null;
/**
* This is the model that will actually perform calculations.
*/
private Calculator calc = null;
/**
* This state variable will be used to keep track of whether the number
* on the display needs to be replaced by new digits.
*/
private boolean isNumberStarted = false;
// Constructors
/**
* Creates a new event handler that is bound by the gui view thats passed
* as a parameter.
*
* @param gui the view that this control connects to.
*/
public EventHandler( CalculatorGUI gui )
{
// If the gui is null, then this class is being used improperly and should
// exit.
if( gui == null )
System.exit( 0 );
// Add the model and view to the control.
this.gui = gui;
this.calc = new Calculator();
}// end of constructor( CalculatorGUI )
// Action Listener
/**
* This function recieves an action event and interprets the event to take
* the proper action. It receives all the button actions from
* CalculatorGUI.
*
* @param ae the action event that needs to be processed.
*/
public void actionPerformed( ActionEvent ae )
{
// No action to process.
if(( ae == null ) ||
( ae.getActionCommand() == null ))
return;
// Clear the calculator screen and model.
if( ae.getActionCommand().equals( "Clr" ) )
doClearCalculator();
// Find out if an operation was selected and handle it.
switch( ae.getActionCommand().charAt(0) )
{
case '=':
doCalculation();
break;
case '+':
doSetOp( Calculator.ADD_OP );
break;
case '-':
doSetOp( Calculator.SUB_OP );
break;
case '*':
doSetOp( Calculator.MUL_OP );
break;
case '/':
doSetOp( Calculator.DIV_OP );
break;
default:
break;
}// end of switch
// Find out if a digit was pressed
if( Character.isDigit( ae.getActionCommand().charAt(0) ) )
doAddDigit( ae.getActionCommand() );
}// end of actionPerformed( ActionEvent )
// Operational Functions
/**
* This function assists the EventHandler by doing the actions needed to
* add a digit to the display.
*
* @see #actionPerformed
* @param digit a string that should have a single digit contents.
*/
private void doAddDigit( String digit )
{
// If diplay needs to be cleared before the digit is added.
if( !isNumberStarted )
{
gui.setDisplay( digit );
isNumberStarted = true;
}
else
gui.setDisplay( gui.getDisplay() + digit );
}// end of doAddDigit( String )
/**
* Clears the gui display and resets the calculator model.
*
* @see #actionPerformed
*/
private void doClearCalculator()
{
isNumberStarted = false;
gui.setDisplay( " " );
calc.clearCalulator();
return;
}// end of doClearCalculator()
/**
* Attempts to do a calculation. GUI is updated based on whether a
* calculation occurs and returns the calculation to the gui.
*
* @see #actionPerformed
*/
public void doCalculation()
{
// holds the parsed operator #2.
int val = 0;
try
{
// Attempt to parse an int from the gui.
val = Integer.parseInt( gui.getDisplay() );
// If preconditions are met, then attempt a calculation.
if(( calc.isOperator1Set() ) &&
( calc.isOperationSet() ))
{
// Calculate and update gui.
calc.setOperator2( val );
gui.setDisplay( "" + calc.getCalculation() );
// Reset display to take in numbers.
isNumberStarted = false;
}// end of if
}// end of try
catch( NumberFormatException nfe )
{
calc.clearCalulator();
gui.setDisplay( "Error!" );
return;
}// end of catch( NumberFormatException )
catch( ArithmeticException ae )
{
calc.clearCalulator();
gui.setDisplay( "Calc. Error!" );
return;
}// end of catch( ArithmeticException )
}// end of doCalculation()
/**
* Set the operation for the calculation. If the operation is already set,
* then do a calculation then set the operation.
*
* @see #actionPerformed
*/
public void doSetOp( int operation )
{
try
{
// Do calculation if operation is already set.
if( calc.isOperationSet() )
doCalculation();
// Set the first operator and set the operation.
calc.setOperator1( Integer.parseInt( gui.getDisplay() ));
calc.setOperation( operation );
isNumberStarted = false;
}// end of try.
catch( NumberFormatException nfe )
{
calc.clearCalulator();
gui.setDisplay( "Error!" );
}// catch( NumberFormatException )
}// end of doSetOp( int )
}// end of class EventHandler

View File

@@ -0,0 +1,336 @@
CS1322: Lab #15 - Spring 2002.
Basic GUI Information
========================================================================
It has probably been covered in class how Swing differs from AWT
(Abstract Windowing Toolkit). The basic idea is that java handles its
components more in Swing instead of relying so much on the underlying
operating system. Swing offers an object oriented approach to GUI
creation by having base classes for all of the GUI components and then
extending those classes in order to make specialized components. All
swing components (except JFrame) inherit from Object->Component->
Container->JComponent (JFrame doesn't extend from JComponent). Open
up the java API and look at some of these classes. Some of these
function names might not make sense to you, but there are many like
Component.isVisible that you can probably guess what they do. For a
list of Swing components, goto the J's in the API. Some examples are
JButton, JPanel, JLabel, JMenu, etc...
Now you have a basic idea that there are some classes that exist and
you use these classes to make GUIs. To actually use these classes,
you must import java.awt.* (for classes like Component) and
javax.swing.* (for the Swing components). You will also need to
import java.awt.event.*, but this will be covered in lab18. Importing
is a way of including classes that are not normally loaded. All of
your programs up to this point have not needed the GUI classes, so it
was more efficient to not ask java to include the GUI files. Now that
you need these classes, you must ask java to look for them. Here's an
example of how you would include:
/**
* My class, bla bla bla...
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MyGUI
{
....
The basic starting point for all Swing GUIs -- that are not applets --
use JFrame. The JFrame class is the actual window. It will contain
all other GUI components. The basic order of operations is to create
a JFrame, add and customize the JFrame, and then make the JFrame
visible. Some people choose to subclass from JFrame and then override
the constructor when they create a GUI. While others choose to treat
the JFrame as an independent component.
(These are "working" examples, but you will need to kill them with
Ctrl-C, because we haven't specified a way to close them nicely. You
need to type this at the command line in order to close the GUI.)
imports...
public class MyGUI1 extends JFrame
{
public MyGUI1()
{
super( "Hello cs1322 Students" );
setSize( 240, 100 );
setVisible( true );
}
public static void main( String[] args )
{
MyGUI1 mg = new MyGUI1();
}
}
The other way:
public class MyGUI1
{
private JFrame frame;
public MyGUI1()
{
frame = new JFrame( "Hello cs1322 Students" );
frame.setSize( 240, 100 );
frame.setVisible( true );
}
public static void main( String[] args )
{
MyGUI1 mg = new MyGUI1();
}
}
Both of these examples will create a window that is 240 pixels wide
and 100 pixels long. The title will say "Hello cs1322 Students". The
frame isn't visible until its set visible.
Now that there is a window, its time to be able to add and populate
the window. All frames have a content pane. This content pane is a
Container (or any subclass of Container).
frame = new JFrame();
Container = frame.getContentPane();
or
frame = new JFrame();
Container c = new JPanel();
frame.setContentPane( c );
One of the important functions that exists in Container is setLayout(
LayoutManager ). A LayoutManager is a class that implements
LayoutManager and allows the programmer to layout components in an
easy manner. Anyone can make a LayoutManager, but this info file will
discuss how to use 4 common types. It would be to you advantage to
try these examples.
BorderLayout:
public MyGUI1()
{
frame = new JFrame( "Hello" );
Container c = new JPanel();
frame.setContentPane( c );
c.setLayout( new BorderLayout() );
c.add( new JButton( "CENTER" ) );
// or c.add( new JButton( "CENTER" ), BorderLayout.CENTER );
c.add( new JButton( "NORTH" ), BorderLayout.NORTH );
c.add( new JButton( "SOUTH" ), BorderLayout.SOUTH );
c.add( new JButton( "EAST" ), BorderLayout.EAST );
c.add( new JButton( "WEST" ), BorderLayout.WEST );
frame.setSize( 400, 400 );
frame.setVisible( true );
}
Creates this:
----------------------------------
| NORTH |
|----------------------------------|
| | | |
| | | |
| EAST | CENTER | WEST |
| | | |
| | | |
|----------------------------------|
| SOUTH |
----------------------------------
Basically, The BorderLayout allows you to have a main content area
(CENTER) and allows for secondary content areas. Also, you can embed
content areas:
public MyGUI1()
{
frame = new JFrame( "Hello" );
Container c = new JPanel();
JPanel embed = new JPanel();
frame.setContentPane( c );
c.setLayout( new BorderLayout() );
embed.setLayout( new BorderLayout() );
c.add( embed, BorderLayout.CENTER );
embed.add( new JButton( "CENTER" ), BorderLayout.CENTER );
embed.add( new JButton( "E. NORTH" ), BorderLayout.NORTH );
embed.add( new JButton( "E. SOUTH" ), BorderLayout.SOUTH );
embed.add( new JButton( "E. EAST" ), BorderLayout.EAST );
embed.add( new JButton( "E. WEST" ), BorderLayout.WEST );
c.add( new JButton( "NORTH" ), BorderLayout.NORTH );
c.add( new JButton( "SOUTH" ), BorderLayout.SOUTH );
c.add( new JButton( "EAST" ), BorderLayout.EAST );
c.add( new JButton( "WEST" ), BorderLayout.WEST );
frame.setSize( 500, 250 );
frame.setVisible( true );
}
(run the code to see what it actually looks like).
GridLayout:
public MyGUI1()
{
frame = new JFrame( "Hello" );
Container c = new JPanel();
frame.setContentPane( c );
c.setLayout( new GridLayout( 2, 3 ) );
c.add( new JButton( "1" ) );
c.add( new JButton( "2" ) );
c.add( new JButton( "3" ) );
c.add( new JButton( "4" ) );
c.add( new JButton( "5" ) );
c.add( new JButton( "6" ) );
frame.setSize( 500, 250 );
frame.setVisible( true );
}
Creates this:
-----------------
| | | |
| 1 | 2 | 3 |
| | | |
|-----------------|
| | | |
| 4 | 5 | 6 |
| | | |
-----------------
c.add( new JButton( "1" ), 0 );
c.add( new JButton( "2" ), 0 );
c.add( new JButton( "3" ), 0 );
c.add( new JButton( "4" ), 0 );
c.add( new JButton( "5" ), 0 );
c.add( new JButton( "6" ), 0 );
Creates this( it inserts into slot 0 and pushes everything back):
-----------------
| | | |
| 6 | 5 | 4 |
| | | |
|-----------------|
| | | |
| 3 | 2 | 1 |
| | | |
-----------------
The GridLayout allows the programmer to make a grid that scales in
size and can have a component embedded into each grid location.
BoxLayout:
public MyGUI1()
{
frame = new JFrame( "Hello" );
Container c = new JPanel();
frame.setContentPane( c );
c.setLayout( new BoxLayout( c, BoxLayout.X_AXIS ) );
c.add( new JButton( "1" ) );
c.add( new JButton( "2" ) );
c.add( new JButton( "3" ) );
c.add( new JButton( "4" ) );
c.add( new JButton( "5" ) );
c.add( new JButton( "6" ) );
frame.setSize( 500, 250 );
frame.setVisible( true );
}
Creates this:
-----------------------------------------------------
| |
| |
| |
|----------------------------------- |
| | | | | | | |
| 1 | 2 | 3 | 4 | 5 | 6 | |
| | | | | | | |
|----------------------------------- |
| |
| |
| |
-----------------------------------------------------
Basically, the BoxLayout adds components in order, but doesn't do the
same kind of resizing like Border and Grid. Try BoxLayout.Y_AXIS
too.
FlowLayout:
FlowLayout is the default layout used by components. To test this,
take the code from BoxLayout and delete the line c.setLayout. Be sure
to resize the window. You will notice how the flow layout just seems
to add other components and places them in order. If your resize to a
smaller window, some buttons move down to different lines.
JLabel, JButton, and Customizations
========================================================================
A JLabel is a GUI Component that displays text, but does not allow the
user to modify the information.
public MyGUI1()
{
frame = new JFrame( "Hello" );
Container c = new JPanel();
frame.setContentPane( c );
JLabel jl = new JLabel( "This is a test." );
// Or
// jl = new JLabel();
// jl.setText( "This is a test." );
c.add( jl );
frame.setSize( 250, 250 );
frame.setVisible( true );
}
JLabels can have their information changed by the program through
setText and you can also get the text through getText. Like all Swing
components JLabels have all the functions from Component, Container,
JComponent, as well as the functions JLabel adds. These functions
allow for many customizations and options. for example this code
below takes the default font from the Jlabel jl and increases the size
by 2.5:
font = jl.getFont();
font = font.deriveFont( (float)( font.getSize2D() * 2.5 ) );
jl.setFont( font );
If you want to customize a java component, there usually is a very
good chance that someone else has wanted that customization also.
Check the API, the java tutorial, and search the internet.
The JButton is a GUI component that can be clicked and the click often
signafies an action to the program (covered in lab 18). This lab is
concerned with your ability to create, add to layouts, and customize
JButtons.
JButton jb = new JButton();
jb.setText( "My Button" );
jb.setBackground( java.awt.Color.red );
jb.setFocusPainted( false ); // Doesn't draw that box around the
// button, when clicked.
jb.setEnabled( false ); // disables the button.

View File

@@ -0,0 +1,111 @@
CS1322: Lab #15 - Spring 2002.
Program Title: Complete the Calculator GUI.
Files Provided
========================================================================
o lab15.nfo
o CalculatorGUI.java - The View (the only file you edit).
o EventHandler.java - The Control.
o Calculator.java - The Model.
Introduction
========================================================================
Its time to learn about Graphical User Interfaces. In this lab, you
will be using the Swing GUI library to create a user interface. It
will focus on GUI layout and component creation. You are given a
working EventHandler that will handle your button presses and a model
that will actually do the calculations. You will need to Complete
CalculatorGUI so that the GUI components are displayed to the
specification stated later in this nfo file.
Excellent References:
o The JAVA API
http://java.sun.com/products/jdk/1.3/docs/api/index.html
o The JAVA Tutorial
http://java.sun.com/docs/books/tutorial/
Also, lab15.intro is an excellent source for learning besic GUI
information. Anyone who has not done Swing GUI programming before
should go through its examples (you are responsible for that
information).
You will probably need to visit the API to properly finish this lab
and are expected to be able to do this.
The Project
========================================================================
It is your job to create the components for a CalculatorGUI, so that
one can use the calulator.
-----------------------
|cs1322 Lab15 |X| The guiFrame should say "cs1322 is fun!"
|-----------------------| The numberLabel should say "Calculator"
| | There should be 10 numberedButtons
| Calculator | numberedButtons[0 - 9] = "0" - "9"
| | There should be 6 operationButtons
|-----------------------| operationButtons[0] = "Clr"
| | | | | operationButtons[1] = "="
| 1 | 2 | 3 | + | operationButtons[2] = "+"
| | | | | operationButtons[3] = "-"
|-----------------------| operationButtons[4] = "*"
| | | | | operationButtons[5] = "/"
| 4 | 5 | 6 | - | The empty spots by "0" should be empty JPanels
| | | | |
|-----------------------| contentPane should be a JPanel with a BorderLayout
| | | | | operationPanel should be a JPanel with a
| 7 | 8 | 9 | * | GridLayout thats 1 row by 2 columns.
| | | | | buttonPanel should be a JPanel with a GridLayout
|-----------------------| thats 4 by 4.
| | | | |
| | 0 | | / | contentPane should become guiFrame's content pane.
| | | | | numberLabel should be in the North of contentPane.
|-----------------------| buttonPanel should be in the Center of contentPane.
| | | operationPanel should be in the South.
| Clr | = | "Clr" and "=" should be in operationPanel.
| | | "1" - "9", "+" - "/" should be in buttonPanel.
-----------------------
Customizations:
The numberLabel should have its font increased by a factor of 2.0 (size * 2.0)
(you may want to do numberLabel.setHorizontalAlignment(numberLabel.RIGHT); too)
"0" - "9" should have their backgrounds changed to java.awt.Color.cyan
"=" - "/" should have their backgrounds changed to java.awt.Color.pink
"Clr" should have their backgrounds changed to java.awt.Color.yellow
Prevent all the buttons from having their focus be painted.
In CalculatorGUI:
Complete the functions:
- doMakeObjects();
- doAddObjects();
- doCustomizations();
The function doEventHandler is provided for you (this time). This
information will be the focus of lab16.
Two more functions. These functions will be used by the event
handler to update the calculator's display. The event handler needs
to be able to set the display and then read the display to do
calculations.
- getDisplay
It should return the text contained in numberLabel.
- setDisplay
It should set the text in numberLabel.
To test your code, compile the supplied files and run CalculatorGUI.
TURNIN
========================================================================
o Files to be turned in:
CalculatorGUI.java

BIN
CS1322/p6/Floor.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 B

BIN
CS1322/p6/FloorNibble.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 B

106
CS1322/p6/FloorPiece.java Normal file
View File

@@ -0,0 +1,106 @@
/**
* <PRE>
* FloorPiece.java
*
* Revisions: 1.0 Nov. 11, 2002
* Created the FloorPiece class
* 1.1 Nov. 11, 2002
* Compiled, Commented, Finished
*
* </PRE>
*
* Collaboration Statement:
* I worked on the homework assignment alone, using only
* course materials.
*
* Created with JCreatorLE, some indents are off when viewed through notepad
* or EMACS
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.1, Nov. 11, 2002
*/
public class FloorPiece extends GamePiece{
/**
*Defines whether or not the piece has a little yellow ball for Pacman
*/
private boolean bHasNibble;
/**
*Defines whether or not the piece has a ghost nibble thing
*/
private boolean bHasSpecial;
///////////////
//Constructor//
///////////////
/**
*Constructor
*@param x, the x coordinate
*@param y, the y coordinate
*@param bHasNibble, nibble on space or not
*@param bHasSpecial, has Special nibble or not
*/
public FloorPiece(int x, int y, boolean bHasNibble, boolean bHasSpecial){
super(x,y);
this.bHasNibble = bHasNibble;
this.bHasSpecial = bHasSpecial;
}
///////////////////////
//Accessors/Modifiers//
///////////////////////
/**
*Modifier for bHasNibble
*@param bHasNibble, the value to be placeds in bHasNibble
*/
public void setNibble(boolean bHasNibble){
this.bHasNibble = bHasNibble;
}
/**
*Accessor for bHasNibble
*@return the value of bHasNibble
*/
public boolean getNibble(){
return bHasNibble;
}
/**
*Modifier for bHasSpecial
*@param bHasSpecial the new value for bHasSpecial
*/
public void setSpecial(boolean bHasSpecial){
this.bHasSpecial = bHasSpecial;
}
/**
*Accessor for bHasSpecial
*@return the value of bHasSpecial
*/
public boolean getSpecial(){
return bHasSpecial;
}
public String toString(){
return (super.toString() + "Floor Piece]");
}
/********************************************************************/
/**
* Debugging main for class FloorPiece.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args) {
}// end of main(String[] args)
}// end of class FloorPiece

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 B

317
CS1322/p6/GameBoard.java Normal file
View File

@@ -0,0 +1,317 @@
import javax.swing.*;
import java.awt.*;
/**
* CS1322: Programming Assignment #6 - Fall 2002
*
* <PRE>
* IDBox for: GameBoard.java
*
* Revisions: 1.0 Nov. 24, 2002
* Created the GameBoard class
* 1.1 Nov. 25, 2002
* Compiled, Finished, Done
*
* </PRE>
*
* Collaboration statement:
* I collaborated with Roland Krystian Alberciak on this phase of the
* program.
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose M. Caban</A>
* @version Version 1.1, Nov. 25, 2002
*/
/**
*Note to Bill:
* Roland coded this one more than I, you can see that in the style.
*However, we colaborated on doing it.
*/
/**
* VIEW.
* GameBoard. GameBoard extends JPanel.
* Responsible for drawing or painting the board
* according to the GamePiece array created in PacmanFileReader.
*/
public class GameBoard extends JPanel
{
Pacman pacman;
Ghost[] ghosts;
/** Debug value for toggling System.out.* output */
public static boolean DEBUG = false;
public static boolean DEBUG_CODE = false;
public static boolean DEBUG_MAIN = false;
/**
* pieceArray. The board seen in the GUI.
* This array will model the board seen in the GUI.
*/
private GamePiece[][] pieceArray;
private PacmanFileReader pfr;
private ImageIcon iiPACMAN;
private ImageIcon iiGHOSTS[];
ImageIcon iiGH_RUN_AWAY;
/* End of Global Declarations */
////////////////
//Constructors//
////////////////
/**
* Constructor
* @param file_name a String file name of a board file.
* file_name is also passed off to a PacmanFileReader.
* @return GameBoard instance/object.
*/
public GameBoard(String file_name)
{
pfr = new PacmanFileReader(file_name);
setPieceArray( pfr.getPieceArray() );
init_images();
pacman = pfr.getPacman();
ghosts = pfr.getGhosts();
} //end of GameBoard(String)
///////////////////////
//Constructor Helpers//
///////////////////////
/**
* init_images. Initializes the images used in Pacman program.
* initializes the provided images of the four ghosts,
* the image of a ghost in run away mode, and of pacman.
*/
public void init_images( )
{
iiPACMAN= new ImageIcon( P6Constants.PACMAN );
iiGHOSTS = new ImageIcon[4];
iiGHOSTS[0]= new ImageIcon( P6Constants.GHOST_1 ); //Ghost 1
iiGHOSTS[1]= new ImageIcon( P6Constants.GHOST_2 ); //Ghost 2
iiGHOSTS[2]= new ImageIcon( P6Constants.GHOST_3 ); //Ghost 3
iiGHOSTS[3]= new ImageIcon( P6Constants.GHOST_4 ); //Ghost 4
iiGH_RUN_AWAY= new ImageIcon( P6Constants.GH_RUN_AWAY );
} //end init_images
///////////
//Methods//
///////////
/**
*
*/
protected void paintComponent( Graphics g )
{
int width, height; //of rectangle
Object pieceAt=null; //generic reference
super.paintComponent(g);
width= this.getWidth()/P6Constants.BOARD_SIZE_X;
height= this.getHeight()/P6Constants.BOARD_SIZE_Y;
for (int yc=0; yc<P6Constants.BOARD_SIZE_Y; yc=yc+1)
{
for (int xc=0; xc<P6Constants.BOARD_SIZE_Y; xc=xc+1)
{
try{
pieceAt= pieceArray[xc][yc];
}catch (Exception e){ //Perhaps NullPointerException, perhaps not.
String err="";
err= "Perhaps pieceArray[][] has not been initialized?";
System.out.println(err);
}
if (pieceAt instanceof WallPiece){
g.setColor(P6Constants.WALL_COLOR);
g.drawRect(xc*width,yc*height,width,height);//draw
g.fillRect(xc*width,yc*height,width,height);//then fill
} //endif
else if (pieceAt instanceof FloorPiece)
{
FloorPiece fpTemp = (FloorPiece)pieceAt;
// First we make a default floor Piece, where we assume
// (fpTemp.getNibble()==false) && (fpTemp.getSpecial()==false)
g.setColor(P6Constants.FLOOR_COLOR);
g.drawRect(xc*width,yc*height,width,height);//draw
g.fillRect(xc*width,yc*height,width,height);//then fill
//then we modify over it.
if (
(fpTemp.getNibble()==true)
&& (fpTemp.getSpecial()==false)
) //Floor with Nibble but not a Special.
{
g.setColor(P6Constants.NIBBLE_COLOR);
g.drawRect(xc*width+width/2-width/4,
yc*height+height/2-height/4,
width/4,
height/4);//draw
g.fillRect(xc*width+width/2-width/4,
yc*height+height/2-height/4,
width/4,
height/4);//then fill
}//endif
else if (
(fpTemp.getNibble()==false)
&& (fpTemp.getSpecial()==true)
)
{
g.setColor(P6Constants.SPECIAL_COLOR);
g.drawRect(xc*width+width/2-width/4,
yc*height+height/2-height/4,
width/4,
height/4);//draw
g.fillRect(xc*width+width/2-width/4,
yc*height+height/2-height/4,
width/4,
height/4);//then fill
}// endelse
//for error. Flag to programmer to correct something.
else if (
(fpTemp.getNibble()==true)
&& (fpTemp.getSpecial()==true)
)
{
String errMsg="";
errMsg=" Error: Cannot draw Nibble with Special";
String fpWas="";
fpWas="A floorpiece of:"+ fpTemp.toString()+" ";
System.out.println(this.getClass()+fpWas+"\n"+errMsg);
} //endelse
}//endelse
}//end xc-for
}//end yc-for
//Now to draw Pacman, Ghosts.
// First, Pacman.
g.drawImage(iiPACMAN.getImage(),
pacman.getX()*width, //get X position on board..
pacman.getY()*height, //get Y position on board..
iiPACMAN.getImageObserver()
);
// Now, the Ghosts.
for (int loop=0; loop<iiGHOSTS.length; loop=loop+1)
{
Ghost tempG = ghosts[loop];
if (tempG.getRunAwayFlag()==false) //draw normal Ghost
g.drawImage(iiGHOSTS[loop].getImage(),
tempG.getX()*width, //get X position on board..
tempG.getY()*height, //get Y position on board..
iiGHOSTS[loop].getImageObserver()
);
else // if (tempG.getRunAwayFlag()==true) //draw spooked Ghost
g.drawImage(iiGH_RUN_AWAY.getImage(),
tempG.getX()*width, //get X position on board..
tempG.getY()*height, //get Y position on board..
iiGH_RUN_AWAY.getImageObserver()
);
}//endfor-go through ghosts
} //end PaintComponent(Graphics)
///////////////////////
//Accessors/Modifiers//
///////////////////////
/**
* Get the value of pieceArray.
* @return value of pieceArray.
*/
public GamePiece[][] getPieceArray()
{
return pieceArray;
}
/**
* Set the value of pieceArray.
* @param v Value to assign to pieceArray.
*/
public void setPieceArray(GamePiece[][] v)
{
this.pieceArray = v;
}
/**
* Get the value of pfr.
* @return value of pfr.
*/
public PacmanFileReader getPfr()
{
return pfr;
}
/**
* Set the value of pfr.
* @param v Value to assign to pfr.
*/
public void setPfr(PacmanFileReader v)
{
this.pfr = v;
}
public Ghost[] getGhosts(){
return ghosts;
}
public Pacman getPacman(){
return pacman;
}
/*
// =======================================================================
// Main method (overrides this commenting system for readibility reasons)
// =======================================================================
*/
/**
* Debugging main for class GameBoard.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args)
{
if ( (args.length==1) && (args[0].equals("-db") ) )
DEBUG_MAIN=true; //else leave false: ignore input.
if (DEBUG_MAIN)
{ // NOTE: This {} encapsulates most of main and is leftmost margin as a flag.
// redundant ifs left in, in case the main if(DEBUG) statement was ommitted,
// this would then print out neat output, as an example of real running.
if (DEBUG) System.out.println("end main(String[] args) call:");
} //end of DEBUG if
} //end of main(String[] args)
} //end of class GameBoard

102
CS1322/p6/GamePiece.java Normal file
View File

@@ -0,0 +1,102 @@
/**
* <PRE>
* GamePiece.java
*
* Revisions: 1.0 Nov. 11, 2002
* Created the GamePiece class
* 1.1 Nov. 11, 2002
* Compiled, Commented, Finished
*
* </PRE>
*
* Collaboration Statement:
* I worked on the homework assignment alone, using only
* course materials.
*
* Created with JCreatorLE, some indents are off when viewed through notepad
* or EMACS
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.1, Nov. 11, 2002
*/
public abstract class GamePiece {
/////////////////////////////////////////////////////
//coordinates such that (0,0) is the top left pixel//
/////////////////////////////////////////////////////
/**
*The X-Pos
*/
protected int x;
/**
*The Y-Pos
*/
protected int y;
///////////////
//Constructor//
///////////////
/**
*Default Constructor for GamePiece
*@param x, the x coordinate
*@param y, the y coordinate
*/
public GamePiece(int x, int y){
this.x = x;
this.y = y;
}
/////////////
//Accessors//
/////////////
/**
*@return the X-Corrdinate
*/
public int getX(){
return x;
}
/**
*@return the Y-Coordinate
*/
public int getY(){
return y;
}
///////////
//Methods//
///////////
/**
*@param x, the x value of the piece
*@param y, the y value of the piece
*/
public void setPosition(int x, int y){
this.x = x;
this.y = y;
}
public String toString(){
return ("[X: " +x+ "Y: " +y+ "]");
}
/***********************************************************/
/**
* Debugging main for class GamePiece.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args) {
}// end of main(String[] args)
}// end of class GamePiece

147
CS1322/p6/Ghost.java Normal file
View File

@@ -0,0 +1,147 @@
/**
* <PRE>
* Ghost.java
*
* Revisions: 1.0 Nov. 12, 2002
* Created the Ghost class
*
* </PRE>
*
* Collaboration Statement:
* I worked on the homework assignment alone, using only
* course materials.
*
* Created with JCreatorLE, some indents are off when viewed through notepad
* or EMACS
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.0, Nov. 12, 2002
*/
public class Ghost extends MoveablePiece{
/**
*number of the ghost
*/
private int ghostNum;
/**
*true if the ghost is running away from pacman
*/
private boolean runAwayFlag;
/**
*Times ghost will run from Pacman
*/
private int runAwayCount;
/**
*Starting coordinates of the ghost
*/
private int startX;
private int startY;
public Ghost(int x, int y, int ghostNum){
super(x,y);
startX = x;
startY = y;
this.ghostNum = ghostNum;
runAwayCount=0;
}
/////////////
//Accessors//
/////////////
/**
*@return ghostNumber
*/
public int getGhostNum(){
return ghostNum;
}
/**
*@return runaway y/n
*/
public boolean getRunAwayFlag(){
return runAwayFlag;
}
/**
*@return the XstartPos
*/
public int getStartX(){
return startX;
}
/**
*@return the YstartPos
*/
public int getStartY(){
return startY;
}
///////////
//Methods//
///////////
/**
*Make the ghost run like hell
*/
public void runAway(){
runAwayFlag = true;
runAwayCount = RUN_AWAY_DURATION;
}
/**
*reset the stupid ghost
*/
public void resetGhost(){
runAwayFlag = false;
setPosition(startX,startY);
}
/**
*@param x, the x coord of Pacman
*@param y, the y coord of Pacman
*@return an array of moves for the ghost
*/
public int[] getMove(int x, int y){
runAwayCount--;
if(runAwayCount<1){
runAwayFlag = false;
}
if(!runAwayFlag){
return GhostAI.getGhostMove(this.x,this.y,x,y);
}
else{
int[] array = GhostAI.getGhostMove(this.x,this.y,x,y);
int[] tmpArray = new int[array.length];
for(int i=0; i<array.length; i++){
tmpArray[i] = array[array.length-i-1];
}
return tmpArray;
}
}
/**
*@return String
*/
public String toString(){
return (super.toString() + "Ghost]");
}
/**
* Debugging main for class Ghost.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args) {
}// end of main(String[] args)
}// end of class Ghost

BIN
CS1322/p6/Ghost1000.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

BIN
CS1322/p6/Ghost1001.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 B

BIN
CS1322/p6/Ghost2000.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 B

BIN
CS1322/p6/Ghost2001.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 B

BIN
CS1322/p6/Ghost3000.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 B

BIN
CS1322/p6/Ghost3001.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

BIN
CS1322/p6/Ghost4000.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

BIN
CS1322/p6/Ghost4001.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 B

View File

@@ -0,0 +1,233 @@
/**
* CS1322: Programming Assignment #6 - Fall 2002
*
* <PRE>
* IDBox for: FloorPiece.java
*
* Revisions: 1.0 Nov. 21, 2002
* Created the FloorPiece class
*
* </PRE>
*
* Collaboration statement:
* "I worked on the homework assignment alone, using only
* course materials."
*
* @author
<A HREF="mailto:gtg142g@mail.gatech.edu">Roland Krystian Alberciak</A>
* @version Version 1.0, Nov. 21, 2002
*/
// imports are listed above IDBox
/**
* MODEL.
* Floorpiece. Floorpiece extends GamePiece.
* Adds the functionality of nibbles (The dots that Pacman eats).
* Each FloorPiece can have a regular nibble, a special nibble
* (one that allows Pacman to chase the ghosts),
* or neither (but not both).
*/
public class FloorPiece extends GamePiece
{
/** Debug value for toggling System.out.* output */
public static boolean DEBUG = false;
public static boolean DEBUG_MAIN = false;
/*
// =======================================================================
// Constructors
// =======================================================================
*/
/**
* Constructor 1. Specified default-overriding constructor for FloorPiece.
* @param void No parameters.
* @return FloorPiece instance/object.
*
public FloorPiece()
{
} //end of FloorPiece()
*/
/**
* Constructor 2. Specified default-overloading constructor for FloorPiece.
* Takes in the location and storage of a FloorPiece::GamePiece object
* @param x the location along the x-axis.
* @param y the location along the y-axis.
* @param hasNibble whether this FloorPiece should have a nibble
* @param hasSpecial whether this FloorPiece should have a special
* @return FloorPiece instance/object.
*/
public FloorPiece(int x, int y, boolean hasNibble, boolean hasSpecial)
{
// STUB
//if then for if both are true? override with hasSpecial=true;
super(x,y); //Chains to the super constructor. (GamePiece)
this.setNibble(hasNibble);
this.setSpecial(hasSpecial);
} //end of FloorPiece(int, int, boolean, boolean)
/*
// =======================================================================
// Methods which override class Object methods
// =======================================================================
*/
/**
* Equal instance comparison. Compares if two instances are equal.
* @param o object-type reference of (hopefully) an FloorPiece.
* @return boolean whether objects are equal.
*
public boolean equals (Object o)
{
} //end of equals(Object)
*/
/**
* toString instance printer. Prints properties of FloorPiece.
* @return System.out.println(FloorPiece instance) instance print.
*/
public String toString()
{
String result="";
if ( (getNibble()==false) && (getSpecial()==false) )
result= P6Constants.FLOOR;
else if ( (getNibble()==true) && (getSpecial()==false) )
result= P6Constants.NIBBLE;
else if ( (getNibble()==false) && (getSpecial()==true) )
result= P6Constants.SPECIAL;
else //if ( (getNibble()==true) && (getSpecial()==true) )
result= "E"; //for error. Flag to programmer.
result = result+" "; //cleanup, autoprepare for output
return result;
} //end of toString()
/*
// =======================================================================
// Class specific methods local to this instance
// =======================================================================
*/
/*
// =======================================================================
// Methods dealing directly with the data within this instance
// (accessors, modifiers, etc)
// =======================================================================
*/
/**
* Get the value of hasNibble.
* @return value of hasNibble.
*/
public boolean getNibble()
{
return hasNibble;
}
/**
* Set the value of hasNibble.
* @param v Value to assign to hasNibble.
*/
public void setNibble(boolean v)
{
this.hasNibble = v;
}
/**
* Get the value of hasSpecial.
* @return value of hasSpecial.
*/
public boolean getSpecial()
{
return hasSpecial;
}
/**
* Set the value of hasSpecial.
* @param v Value to assign to hasSpecial.
*/
public void setSpecial(boolean v)
{
this.hasSpecial = v;
}
/*
// =======================================================================
// Private Variables local to this instance
// =======================================================================
*/
/**
* hasNibble. Whether floorpiece has a regular nibble.
* Represents whether or not this FloorPiece has a nibble that Pacman eats
* (the regular ones, not the ones that lets Pacman chase Ghosts)
*/
private boolean hasNibble;
/**
* hasSpecial. Whether floorpiece has a special nibble.
* Represents whether or not this FloorPiece has a special nibble
* (the special ones which allows Pacman to chase Ghosts.)
*/
private boolean hasSpecial;
/*
// =======================================================================
// Main method (overrides this commenting system for readibility reasons)
// =======================================================================
*/
/**
* Debugging main for class FloorPiece.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args)
{
if ( (args.length==1) && (args[0].equals("-db") ) )
DEBUG_MAIN=true; //else leave false: ignore input.
if (DEBUG_MAIN)
{ // NOTE: This {} encapsulates most of main and is leftmost margin as a flag.
// redundant ifs left in, in case the main if(DEBUG) statement was ommitted,
// this would then print out neat output, as an example of real running.
FloorPiece f1 = new FloorPiece(4,7, false, false);
FloorPiece f2 = new FloorPiece(3,7, false, true);
FloorPiece f3 = new FloorPiece(2,7, true, false);
FloorPiece f4 = new FloorPiece(1,7, true, true);
System.out.println(f1);
System.out.println(f2);
System.out.println(f3);
System.out.println(f4);
if (DEBUG) System.out.println("end main(String[] args) call:");
} //end of DEBUG if
} //end of main(String[] args)
} //end of class FloorPiece

View File

@@ -0,0 +1,298 @@
import javax.swing.*;
import java.awt.*;
/**
* CS1322: Programming Assignment #6 - Fall 2002
*
* <PRE>
* IDBox for: GameBoard.java
*
* Revisions: 1.0 Nov. 24, 2002
* Created the GameBoard class
*
* </PRE>
*
* Collaboration statement:
* I collaborated with Roland Krystian Alberciak on this phase of the
* program.
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose M. Cabank</A>
* @version Version 1.0, Nov. 24, 2002
*/
/**
* VIEW.
* GameBoard. GameBoard extends JPanel.
* Responsible for drawing or painting the board
* according to the GamePiece array created in PacmanFileReader.
*/
public class GameBoard extends JPanel
{
/** Debug value for toggling System.out.* output */
public static boolean DEBUG = false;
public static boolean DEBUG_CODE = false;
public static boolean DEBUG_MAIN = false;
/**
* pieceArray. The board seen in the GUI.
* This array will model the board seen in the GUI.
*/
private GamePiece[][] pieceArray;
private PacmanFileReader pfr;
private ImageIcon iiPACMAN;
private ImageIcon iiGHOSTS[];
ImageIcon iiGH_RUN_AWAY;
/* End of Global Declarations */
////////////////
//Constructors//
////////////////
/**
* Constructor
* @param file_name a String file name of a board file.
* file_name is also passed off to a PacmanFileReader.
* @return GameBoard instance/object.
*/
public GameBoard(String file_name)
{
pfr = new PacmanFileReader(file_name);
setPieceArray( pfr.getPieceArray() );
init_images();
} //end of GameBoard(String)
///////////////////////
//Constructor Helpers//
///////////////////////
/**
* init_images. Initializes the images used in Pacman program.
* initializes the provided images of the four ghosts,
* the image of a ghost in run away mode, and of pacman.
*/
public void init_images( )
{
iiPACMAN= new ImageIcon( P6Constants.PACMAN );
iiGHOSTS = new ImageIcon[4];
iiGHOSTS[0]= new ImageIcon( P6Constants.GHOST_1 ); //Ghost 1
iiGHOSTS[1]= new ImageIcon( P6Constants.GHOST_2 ); //Ghost 2
iiGHOSTS[2]= new ImageIcon( P6Constants.GHOST_3 ); //Ghost 3
iiGHOSTS[3]= new ImageIcon( P6Constants.GHOST_4 ); //Ghost 4
iiGH_RUN_AWAY= new ImageIcon( P6Constants.GH_RUN_AWAY );
} //end init_images
///////////
//Methods//
///////////
/**
*
*/
protected void paintComponent( Graphics g )
{
int width, height; //of rectangle
Object pieceAt=null; //generic reference
super.paintComponent(g);
width= this.getWidth()/P6Constants.BOARD_SIZE_X;
height= this.getHeight()/P6Constants.BOARD_SIZE_Y;
for (int yc=0; yc<P6Constants.BOARD_SIZE_Y; yc=yc+1)
{
for (int xc=0; xc<P6Constants.BOARD_SIZE_Y; xc=xc+1)
{
try{
pieceAt= pieceArray[xc][yc];
}catch (Exception e){ //Perhaps NullPointerException, perhaps not.
String err="";
err= "Perhaps pieceArray[][] has not been initialized?";
System.out.println(err);
}
if (pieceAt instanceof WallPiece){
g.setColor(P6Constants.WALL_COLOR);
g.drawRect(xc*width,yc*height,width,height);//draw
g.fillRect(xc*width,yc*height,width,height);//then fill
} //endif
else if (pieceAt instanceof FloorPiece)
{
FloorPiece fpTemp = (FloorPiece)pieceAt;
// First we make a default floor Piece, where we assume
// (fpTemp.getNibble()==false) && (fpTemp.getSpecial()==false)
g.setColor(P6Constants.FLOOR_COLOR);
g.drawRect(xc*width,yc*height,width,height);//draw
g.fillRect(xc*width,yc*height,width,height);//then fill
//then we modify over it.
if (
(fpTemp.getNibble()==true)
&& (fpTemp.getSpecial()==false)
) //Floor with Nibble but not a Special.
{
g.setColor(P6Constants.NIBBLE_COLOR);
g.drawRect(xc*width+width/2-width/4,
yc*height+height/2-height/4,
width/4,
height/4);//draw
g.fillRect(xc*width+width/2-width/4,
yc*height+height/2-height/4,
width/4,
height/4);//then fill
}//endif
else if (
(fpTemp.getNibble()==false)
&& (fpTemp.getSpecial()==true)
)
{
g.setColor(P6Constants.SPECIAL_COLOR);
g.drawRect(xc*width+width/2-width/4,
yc*height+height/2-height/4,
width/4,
height/4);//draw
g.fillRect(xc*width+width/2-width/4,
yc*height+height/2-height/4,
width/4,
height/4);//then fill
}// endelse
//for error. Flag to programmer to correct something.
else if (
(fpTemp.getNibble()==true)
&& (fpTemp.getSpecial()==true)
)
{
String errMsg="";
errMsg=" Error: Cannot draw Nibble with Special";
String fpWas="";
fpWas="A floorpiece of:"+ fpTemp.toString()+" ";
System.out.println(this.getClass()+fpWas+"\n"+errMsg);
} //endelse
}//endelse
}//end xc-for
}//end yc-for
//Now to draw Pacman, Ghosts.
// First, Pacman.
g.drawImage(iiPACMAN.getImage(),
pfr.getPacman().getX()*width, //get X position on board..
pfr.getPacman().getY()*height, //get Y position on board..
iiPACMAN.getImageObserver()
);
// Now, the Ghosts.
for (int loop=0; loop<iiGHOSTS.length; loop=loop+1)
{
Ghost tempG = pfr.getGhosts()[loop];
if (tempG.getRunAwayFlag()==false) //draw normal Ghost
g.drawImage(iiGHOSTS[loop].getImage(),
tempG.getX()*width, //get X position on board..
tempG.getY()*height, //get Y position on board..
iiGHOSTS[loop].getImageObserver()
);
else // if (tempG.getRunAwayFlag()==true) //draw spooked Ghost
g.drawImage(iiGH_RUN_AWAY.getImage(),
tempG.getX()*width, //get X position on board..
tempG.getY()*height, //get Y position on board..
iiGH_RUN_AWAY.getImageObserver()
);
}//endfor-go through ghosts
} //end PaintComponent(Graphics)
///////////////////////
//Accessors/Modifiers//
///////////////////////
/**
* Get the value of pieceArray.
* @return value of pieceArray.
*/
public GamePiece[][] getPieceArray()
{
return pieceArray;
}
/**
* Set the value of pieceArray.
* @param v Value to assign to pieceArray.
*/
public void setPieceArray(GamePiece[][] v)
{
this.pieceArray = v;
}
/**
* Get the value of pfr.
* @return value of pfr.
*/
public PacmanFileReader getPfr()
{
return pfr;
}
/**
* Set the value of pfr.
* @param v Value to assign to pfr.
*/
public void setPfr(PacmanFileReader v)
{
this.pfr = v;
}
/*
// =======================================================================
// Main method (overrides this commenting system for readibility reasons)
// =======================================================================
*/
/**
* Debugging main for class GameBoard.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args)
{
if ( (args.length==1) && (args[0].equals("-db") ) )
DEBUG_MAIN=true; //else leave false: ignore input.
if (DEBUG_MAIN)
{ // NOTE: This {} encapsulates most of main and is leftmost margin as a flag.
// redundant ifs left in, in case the main if(DEBUG) statement was ommitted,
// this would then print out neat output, as an example of real running.
if (DEBUG) System.out.println("end main(String[] args) call:");
} //end of DEBUG if
} //end of main(String[] args)
} //end of class GameBoard

View File

@@ -0,0 +1,214 @@
/**
* CS1322: Programming Assignment #6 - Fall 2002
*
* <PRE>
* IDBox for: GamePiece.java
*
* Revisions: 1.0 Nov. 21, 2002
* Created the GamePiece class
*
* </PRE>
*
* Collaboration statement:
* "I worked on the homework assignment alone, using only
* course materials."
*
* @author
<A HREF="mailto:gtg142g@mail.gatech.edu">Roland Krystian Alberciak</A>
* @version Version 1.0, Nov. 21, 2002
*/
// imports are listed above IDBox
/**
* MODEL.
* GamePiece. GamePiece is abstract.
* This class is the super class to all pieces of the game board.
*/
public abstract class GamePiece
{
/** Debug value for toggling System.out.* output */
public static boolean DEBUG = false;
public static boolean DEBUG_MAIN = false;
/*
// =======================================================================
// Constructors
// =======================================================================
*/
/**
* Constructor 1. Specified default-overriding constructor for GamePiece.
* @param void No parameters.
* @return GamePiece instance/object.
*
public GamePiece()
{
} //end of GamePiece()
*/
/**
* Constructor 2. Specified default-overloading constructor for GamePiece.
* @param x the location along the x-axis.
* @param y the location along the y-axis.
* @return GamePiece instance/object.
*/
public GamePiece( int x, int y )
{
this.setPosition(x,y);
} //end of GamePiece(int, int)
/*
// =======================================================================
// Methods which override class Object methods
// =======================================================================
*/
/**
* Equal instance comparison. Compares if two instances are equal.
* @param o object-type reference of (hopefully) an GamePiece.
* @return boolean whether objects are equal.
*
public boolean equals (Object o)
{
} //end of equals(Object)
*/
/**
* toString instance printer. Prints properties of GamePiece.
* @return System.out.println(GamePiece instance) instance print.
*
public String toString()
{
} //end of toString()
*/
/*
// =======================================================================
// Class specific methods local to this instance
// =======================================================================
*/
/**
* setPosition. Sets the location variables to passed in x,y parameters.
* @param x the new location along the x-axis.
* @param y the new location along the y-axis.
*/
public void setPosition( int x, int y )
{
this.setX(x);
this.setY(y);
} //end of setPosition(int, int)
/*
// =======================================================================
// Methods dealing directly with the data within this instance
// (accessors, modifiers, etc)
// =======================================================================
*/
/**
* Get the value of x.
* @return value of x.
*/
public int getX()
{
return x;
} //end of getX()
/**
* Set the value of x.
* @param v Value to assign to x.
*/
public void setX(int v)
{
this.x = v;
} //end of setX(int)
/**
* Get the value of y.
* @return value of y.
*/
public int getY()
{
return y;
} //end of getY()
/**
* Set the value of y.
* @param v Value to assign to y.
*/
public void setY(int v)
{
this.y = v;
} //end of setY(int)
/*
// =======================================================================
// Private/Protected Variables local to this instance
// =======================================================================
*/
/**
* Together these two variables represent the exact location of the
* board this particular piece is in. The location (0,0) is the
* upper left hand corner of the game board.
*/
/**
* x. Column placeholder.
* This variable represents which column the piece is in.
* i.e., it's location along the x-axis.(the top edge of the screan)
*/
protected int x;
/**
* y. Row placeholder.
* This variable representswhich row the piece is in.
* i.e., it's location along the y-axis. (the side edge of the screan)
*/
protected int y;
/*
// =======================================================================
// Main method (overrides this commenting system for readibility reasons)
// =======================================================================
*/
/**
* Debugging main for class GamePiece.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args)
{
if ( (args.length==1) && (args[0].equals("-db") ) )
DEBUG_MAIN=true; //else leave false: ignore input.
if (DEBUG_MAIN)
{ // NOTE: This {} encapsulates most of main and is leftmost margin as a flag.
// redundant ifs left in, in case the main if(DEBUG) statement was ommitted,
// this would then print out neat output, as an example of real running.
if (DEBUG) System.out.println("end main(String[] args) call:");
} //end of DEBUG if
} //end of main(String[] args)
} //end of class GamePiece

View File

@@ -0,0 +1,396 @@
/**
* CS1322: Programming Assignment #6 - Fall 2002
*
* <PRE>
* IDBox for: Ghost.java
*
* Revisions: 1.0 Nov. 23, 2002
* Created the Ghost class
*
* </PRE>
*
* Collaboration statement:
* "I worked on the homework assignment alone, using only
* course materials."
*
* @author
<A HREF="mailto:gtg142g@mail.gatech.edu">Roland Krystian Alberciak</A>
* @version Version 1.0, Nov. 23, 2002
*/
// imports are listed above IDBox
/**
* MODEL.
* Ghost. Ghost extends MoveablePiece.
* This class will model the Ghost piece which the AI will control.
*/
public class Ghost extends MoveablePiece
{
/** Debug value for toggling System.out.* output */
public static boolean DEBUG = false;
public static boolean DEBUG_CODE = false;
public static boolean DEBUG_MAIN = false;
/*
// =======================================================================
// Constructors
// =======================================================================
*/
/**
* Constructor 1. Specified default-overriding constructor for Ghost.
* @param void No parameters.
* @return Ghost instance/object.
*
public Ghost()
{
} //end of Ghost()
*/
/**
* Constructor 2. Specified default-overloading constructor for Ghost.
* @param x the location along the x-axis.
* @param y the location along the y-axis.
* @param ghostNum this ghost's number.
* @return Ghost instance/object.
*/
public Ghost( int x, int y, int ghostNum )
{
super(x,y);
this.setStartX(x);
this.setStartY(y);
this.setGhostNum(ghostNum);
} //end of Ghost(int, int, int)
/*
// =======================================================================
// Methods which override class Object methods
// =======================================================================
*/
/**
* Equal instance comparison. Compares if two instances are equal.
* @param o object-type reference of (hopefully) an Ghost.
* @return boolean whether objects are equal.
*
public boolean equals (Object o)
{
} //end of equals(Object)
*/
/**
* toString instance printer. Prints properties of Ghost.
* @return System.out.println(Ghost instance) instance print.
*/
public String toString()
{
String result="";
result = "I am Ghost #"+getGhostNum()+
" located at (x,y): (" +getX()+", "+getY()+")";
return result;
} //end of toString()
/*
// =======================================================================
// Class specific methods local to this instance (ex: forced by interface)
// =======================================================================
*/
/**
* runAway. Modifies this instance's runAwayFlag and runAwayCount.
* [1.]: Sets runAwayFlag to true and
* [2.]: Initializes runAwayCount to RUN_AWAY_DURATION from P6Constants
*/
public void runAway()
{
this.setRunAwayFlag(true);
this.setRunAwayCount(P6Constants.RUN_AWAY_DURATION);
}
/**
* resetGhost. Modifies this instance's runAwayFlag and startX, startY
* This method will be invoked if this ghost is eaten by Pacman.
* [1.]: Turns runAwayFlag to false and
* [2.]: Returns the ghost to its start coordinates.
*/
public void resetGhost()
{
this.setRunAwayFlag(false);
setPosition( getStartX(), getStartY() );
}
/**
* getMove. Calculate the array of size four containing this ghost's choices
of movement as described above. Feel free to use the GhostAI
class. Keep in mind however that the getGhostMove method
provided assumes the ghost is chasing pacman. You will need to
modify the array to have the ghost run away from Pacman if this
is the case. If the Ghost is indeed running from Pacman, be sure
to deduct a turn from runAwayCount and check to see if
runAwayCount is zero, in which case you should have the ghost no
longer run from Pacman. This method will not actually set the
location of the ghost based on the GhostAI method. It simply
returns the array of choices. We do this because this ghost has
no clue whether any of its choices will take it into a wall. A
class later in the project will process the choices and decide
which moves are legal for this ghost. The ghost will then be
told which way to move.
* @param pacmanX Pacman's x location.
* @param pacmanY Pacman's y location.
* @return int[] Ghost's choices of movement (as done in GhostAI)
*/
public int[] getMove( int pacmanX, int pacmanY ) // Pacman's x, y
{
int result[];
if (getRunAwayFlag() == false) // ghost chasing pacman
{
result = GhostAI.getGhostMove(
getX(), //ghost's X (from GamePiece)
getY(), //ghost's Y (from GamePiece)
pacmanX, //pacman's X (from parameter)
pacmanY //pacman's Y (from parameter)
);
}
else // (getRunAwayFlag() == true) // ghost fleeing pacman
{
result = GhostAI.getGhostMove(
getX(), //ghost's X (from GamePiece)
getY(), //ghost's Y (from GamePiece)
pacmanX, //pacman's X (from parameter)
pacmanY //pacman's Y (from parameter)
);
int temp;
int left= 0;
int right= result.length-1;
while (left < right) //reverse result array (flip across middle)
{
temp = result[left];
result[left]=result[right];
result[right]=temp;
left=left+1;
right=right-1;
} //endwhile
// Preferable to a switch statement because of the >0. (case 1,2,3...)
if (getRunAwayCount() > 0) //for all integers I such that I>=1
this.setRunAwayCount( getRunAwayCount()-1 );
else if (getRunAwayCount()==0) //0 is min value & known at this point.
this.setRunAwayFlag(false); //get Pacman!
else // (getRunAwayCount()<0) //Error condition
System.out.println("An error has occurred, getRunAwayCount<0");
}
return result;
}
/*
// =======================================================================
// Methods dealing directly with the data within this instance
// (accessors, modifiers, etc)
// =======================================================================
*/
/**
* Get the value of ghostNum.
* @return value of ghostNum.
*/
public int getGhostNum()
{
return ghostNum;
}
/**
* STUB - MAKE PRIVATE
* Set the value of ghostNum.
* @param v Value to assign to ghostNum.
*/
private void setGhostNum(int v)
{
this.ghostNum = v;
}
/**
* Get the value of runAwayFlag.
* @return value of runAwayFlag.
*/
public boolean getRunAwayFlag()
{
return runAwayFlag;
}
/**
* STUB - MAKE PRIVATE
* Set the value of runAwayFlag.
* @param v Value to assign to runAwayFlag.
*/
private void setRunAwayFlag(boolean v)
{
this.runAwayFlag = v;
}
/**
* STUB - REVIEW MAKE PRIVATE
* Get the value of runAwayCount.
* @return value of runAwayCount.
*/
public int getRunAwayCount()
{
return runAwayCount;
}
/**
* STUB - MAKE PRIVATE
* Set the value of runAwayCount.
* @param v Value to assign to runAwayCount.
*/
private void setRunAwayCount(int v)
{
this.runAwayCount = v;
}
/**
* Get the value of startX.
* @return value of startX.
*/
public int getStartX()
{
return startX;
}
/**
* STUB - MAKE PRIVATE
* Set the value of startX.
* @param v Value to assign to startX.
*/
private void setStartX(int v)
{
this.startX = v;
}
/**
* Get the value of startY.
* @return value of startY.
*/
public int getStartY()
{
return startY;
}
/**
* STUB - MAKE PRIVATE
* Set the value of startY.
* @param v Value to assign to startY.
*/
private void setStartY(int v)
{
this.startY = v;
}
/*
// =======================================================================
// Protected Variables local to this instance
// =======================================================================
*/
/*
// =======================================================================
// Private Variables local to this instance
// =======================================================================
*/
/**
* ghostNum. The number of the ghost.
*/
private int ghostNum;
/**
* runAwayFlag. Flag representing whether or not ghost is hunting Pacman.
* true if this Ghost is running from Pacman, and
* false if the Ghost is chasing Pacman.
*/
private boolean runAwayFlag;
/**
* runAwayCount. Contains the number of returns remaining
* for this ghost to run from Pacman.
* (A ghost will run from Pacman for a fixed number of moves
* if Pacman eats a special nibble).
*/
private int runAwayCount;
/**
* startX. Contains the starting x coordinate for this ghost.
*/
private int startX;
/**
* startY. Contains the starting y coordinate for this ghost.
*/
private int startY;
/*
// =======================================================================
// Main method (overrides this commenting system for readibility reasons)
// =======================================================================
*/
/**
* Debugging main for class Ghost.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args)
{
if ( (args.length==1) && (args[0].equals("-db") ) )
DEBUG_MAIN=true; //else leave false: ignore input.
if (DEBUG_MAIN)
{ // NOTE: This {} encapsulates most of main and is leftmost margin as a flag.
// redundant ifs left in, in case the main if(DEBUG) statement was ommitted,
// this would then print out neat output, as an example of real running.
Ghost g1 = new Ghost(4,6,1);
Ghost g2 = new Ghost(7,3,2);
Ghost g3 = new Ghost(8,5,3);
Ghost g4 = new Ghost(4,4,4);
System.out.println(g1);
System.out.println(g2);
System.out.println(g3);
System.out.println(g4);
System.out.println("Ghost's class is:" +g1.getClass().getName());
if (DEBUG) System.out.println("end main(String[] args) call:");
} //end of DEBUG if
} //end of main(String[] args)
} //end of class Ghost

View File

@@ -0,0 +1,197 @@
/**
* CS1322: Programming Assignment #6 - Fall 2002
*
* <PRE>
* IDBox for: MoveablePiece.java
*
* Revisions: 1.0 Nov. 21, 2002
* Created the MoveablePiece class
*
* </PRE>
*
* Collaboration statement:
* "I worked on the homework assignment alone, using only
* course materials."
*
* @author
<A HREF="mailto:gtg142g@mail.gatech.edu">Roland Krystian Alberciak</A>
* @version Version 1.0, Nov. 21, 2002
*/
// imports are listed above IDBox
/**
* MODEL.
* MoveablePiece. MoveablePiece is abstract and extends GamePiece.
* This class will be the super class of both Ghost and Pacman.
*/
public abstract class MoveablePiece extends GamePiece
{
/** Debug value for toggling System.out.* output */
public static boolean DEBUG = false;
public static boolean DEBUG_MAIN = false;
/*
// =======================================================================
// Constructors
// =======================================================================
*/
/**
* Constructor 1. Specified default-overriding constructor for MoveablePiece.
* @param void No parameters.
* @return MoveablePiece instance/object.
*
public MoveablePiece()
{
} //end of MoveablePiece()
*/
/**
* Constructor 2. Specified default-overloading constructor for MoveablePiece.
* @param x the location along the x-axis.
* @param y the location along the y-axis.
* @return MoveablePiece instance/object.
*/
public MoveablePiece( int x, int y )
{
super(x,y); //Chains to the super constructor. (GamePiece)
} //end of MoveablePiece(int, int)
/*
// =======================================================================
// Methods which override class Object methods
// =======================================================================
*/
/**
* Equal instance comparison. Compares if two instances are equal.
* @param o object-type reference of (hopefully) an MoveablePiece.
* @return boolean whether objects are equal.
*
public boolean equals (Object o)
{
} //end of equals(Object)
*/
/**
* toString instance printer. Prints properties of MoveablePiece.
* @return System.out.println(MoveablePiece instance) instance print.
*
public String toString()
{
} //end of toString()
*/
/*
// =======================================================================
// Class specific methods local to this instance
// =======================================================================
*/
/*
// =======================================================================
// Methods dealing directly with the data within this instance
// (accessors, modifiers, etc)
// =======================================================================
*/
/**
* move. Moves the GamePiece.
* Takes in an int representing a direction. In this
* method the piece is "moved".
* (The piece has it's x or y location modifed accordingly.)
* Remember: (0,0) is the top left corner of the board.
* @param direction direction to move GamePiece.
* Is either NORTH, EAST, SOUTH, or WEST from P6Constants.
* Represents up, right, down and left respectively.
*/
public void move( int direction )
{
switch (direction)
{
case (P6Constants.NORTH):
super.setX( getX() );
super.setY( (getY()-1) );
break;
case (P6Constants.EAST):
super.setX( (getX()+1) );
super.setY( getY() );
break;
case (P6Constants.SOUTH):
super.setX( getX() );
super.setY( (getY()+1) );
break;
case (P6Constants.WEST):
super.setX( (getX()-1) );
super.setY( getY() );
break;
default:
System.out.println("An error in possible directions");
} //endswitch
/*
if (direction == NORTH)
this( getX(), getY()-1 );
else if (direction == EAST)
this( getX()+1, getY() );
else if (direction == SOUTH)
this( getX(), getY()+1 );
else if (direction == WEST)
this( getX()-1,getY() );
else
System.out.println("An error in possible directions");
*/
}
/*
// =======================================================================
// Private Variables local to this instance
// =======================================================================
*/
/*
// =======================================================================
// Main method (overrides this commenting system for readibility reasons)
// =======================================================================
*/
/**
* Debugging main for class MoveablePiece.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args)
{
if ( (args.length==1) && (args[0].equals("-db") ) )
DEBUG_MAIN=true; //else leave false: ignore input.
if (DEBUG_MAIN)
{ // NOTE: This {} encapsulates most of main and is leftmost margin as a flag.
// redundant ifs left in, in case the main if(DEBUG) statement was ommitted,
// this would then print out neat output, as an example of real running.
if (DEBUG) System.out.println("end main(String[] args) call:");
} //end of DEBUG if
} //end of main(String[] args)
} //end of class MoveablePiece

View File

@@ -0,0 +1,61 @@
/**
* CS1322: Programming Assignment #6 - Fall 2002
*
* <PRE>
* IDBox for: P6.java
*
* Revisions: 1.0 Nov. 25, 2002
* Created the P6 class
*
* </PRE>
*
* Collaboration statement:
* "I worked on the homework assignment alone, using only
* course materials."
*
* @author
<A HREF="mailto:gtg142g@mail.gatech.edu">Roland Krystian Alberciak</A>
* @version Version 1.0, Nov. 25, 2002
*/
// imports are listed above IDBox
public class P6
{
/** Debug value for toggling System.out.* output */
public static boolean DEBUG = false;
public static boolean DEBUG_CODE = false;
public static boolean DEBUG_MAIN = true;
/*
// =======================================================================
// Main method (overrides this commenting system for readibility reasons)
// =======================================================================
*/
/**
* Debugging main for class P6.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args)
{
if ( (args.length==1) && (args[0].equals("-db") ) )
DEBUG_MAIN=true; //else leave false: ignore input.
if (DEBUG_MAIN)
{ // NOTE: This {} encapsulates most of main and is leftmost margin as a flag.
// redundant ifs left in, in case the main if(DEBUG) statement was ommitted,
// this would then print out neat output, as an example of real running.
PacmanFrame pf = new PacmanFrame();
if (DEBUG) System.out.println("end main(String[] args) call:");
} //end of DEBUG if
} //end of main(String[] args)
} //end of class P6

View File

@@ -0,0 +1,86 @@
/**
* <PRE>
* P6Constants.java
*
* Revisions: 1.0 Aug. 25, 2002
* Created the P6Constants class
*
* </PRE>
*
* @author <A HREF="mailto:bsbeck@cc.gatech.edu">Brandon Beck</A>
* @version Version 1.0, Aug. 25, 2002
*/
public interface P6Constants {
//The color of Walls
public static final java.awt.Color WALL_COLOR = java.awt.Color.blue;
//The color of Floors
public static final java.awt.Color FLOOR_COLOR = java.awt.Color.black;
//The color of a regular nibble
public static final java.awt.Color NIBBLE_COLOR = java.awt.Color.yellow;
//The color of a special nibble
public static final java.awt.Color SPECIAL_COLOR = java.awt.Color.orange;
//The name of the file to parse to obtain the board
public static final String BOARD_FILE = "board_1.txt";
//The image file containing Pacman
public static final String PACMAN = "pacman.gif";
//The four image files containing each of the ghosts while chasing pacman
public static final String GHOST_1 = "gh1.gif";
public static final String GHOST_2 = "gh2.gif";
public static final String GHOST_3 = "gh3.gif";
public static final String GHOST_4 = "gh4.gif";
//The image file applied to all ghosts while running from pacman
public static final String GH_RUN_AWAY = "ghRA.gif";
//The constant representing a WallPiece in a board file
public static final String WALL = "w";
//The constant representing a FloorPiece no nibbles in a board file
public static final String FLOOR = "f";
//The constant indicating a FloorPiece with a special nibble in
//a board file
public static final String SPECIAL = "s";
//The constant indicating a FloorPiece with a regular nibble in
//a board file
public static final String NIBBLE = "n";
//The number of columns (or pieces in one row) on the board
public static final int BOARD_SIZE_X = 15;
//The number of rows (or pieces in one column) on the board
public static final int BOARD_SIZE_Y = 15;
//The constant representing "up"
public static final int NORTH = 0;
//The constant representing "right"
public static final int EAST = 1;
//The constant representing "down"
public static final int SOUTH = 2;
//The constant representing "left"
public static final int WEST = 3;
//The number of moves a Ghost makes while running from Pacman before it
//returns to the state of chasing Pacman
public static final int RUN_AWAY_DURATION = 20;
//The interval between firings of the PacmanTimer controlling Pacman movements
public static final int PACMAN_INTERVAL = 350;
//The interval between firings of the GhostTimer controlling all Ghost movements
public static final int GHOST_INTERVAL = 500;
}// end of interface P6Constants

View File

@@ -0,0 +1,189 @@
/**
* CS1322: Programming Assignment #6 - Fall 2002
*
* <PRE>
* IDBox for: Pacman.java
*
* Revisions: 1.0 Nov. 23, 2002
* Created the Pacman class
*
* </PRE>
*
* Collaboration statement:
* "I worked on the homework assignment alone, using only
* course materials."
*
* @author
<A HREF="mailto:gtg142g@mail.gatech.edu">Roland Krystian Alberciak</A>
* @version Version 1.0, Nov. 23, 2002
*/
// imports are listed above IDBox
/**
* MODEL.
* Pacman. Pacman extends MoveablePiece.
* This class will model the Pacman piece which the user will control.
*/
public class Pacman extends MoveablePiece
{
/** Debug value for toggling System.out.* output */
public static boolean DEBUG = false;
public static boolean DEBUG_CODE = false;
public static boolean DEBUG_MAIN = false;
/*
// =======================================================================
// Constructors
// =======================================================================
*/
/**
* Constructor 1. Specified default-overriding constructor for Pacman.
* @param void No parameters.
* @return Pacman instance/object.
*
public Pacman()
{
} //end of Pacman()
*/
/**
* Constructor 2. Specified default-overloading constructor for Pacman.
* Takes in the location of the Pacman::MoveablePiece::GamePiece.
* @param x the location along the x-axis.
* @param y the location along the y-axis.
* @return Pacman instance/object.
*/
public Pacman(int x, int y)
{
super(x,y); //Chains to the super constructor. (MoveablePiece)
} //end of Pacman(int, int)
/*
// =======================================================================
// Methods which override class Object methods
// =======================================================================
*/
/**
* Equal instance comparison. Compares if two instances are equal.
* @param o object-type reference of (hopefully) an Pacman.
* @return boolean whether objects are equal.
*
public boolean equals (Object o)
{
} //end of equals(Object)
*/
/**
* toString instance printer. Prints properties of Pacman.
* @return System.out.println(Pacman instance) instance print.
*/
public String toString()
{
String result="";
result = "I am Pacman!! located at (x,y): (" +getX()+", "+getY()+")";
return result;
} //end of toString()
/*
// =======================================================================
// Class specific methods local to this instance (ex: forced by interface)
// =======================================================================
*/
/*
// =======================================================================
// Methods dealing directly with the data within this instance
// (accessors, modifiers, etc)
// =======================================================================
*/
/**
* Get the value of direction.
* @return value of direction.
*/
public int getDirection()
{
return direction;
}
/**
* Set the value of direction.
* @param v Value to assign to direction.
*/
public void setDirection(int v)
{
this.direction = v;
}
/*
// =======================================================================
// Protected Variables local to this instance
// =======================================================================
*/
/*
// =======================================================================
// Private Variables local to this instance
// =======================================================================
*/
/**
* direction. Contain one of the four constants from P6Constants:
* NORTH, EAST, SOUTH, WEST.
* Represents the direction Pacman is currently heading on the board.
* This variable is by default initialized to EAST.
*/
private int direction = P6Constants.EAST;
/*
// =======================================================================
// Main method (overrides this commenting system for readibility reasons)
// =======================================================================
*/
/**
* Debugging main for class Pacman.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args)
{
if ( (args.length==1) && (args[0].equals("-db") ) )
DEBUG_MAIN=true; //else leave false: ignore input.
if (DEBUG_MAIN)
{ // NOTE: This {} encapsulates most of main and is leftmost margin as a flag.
// redundant ifs left in, in case the main if(DEBUG) statement was ommitted,
// this would then print out neat output, as an example of real running.
Pacman pm = new Pacman(2,6);
System.out.println(pm);
if (DEBUG) System.out.println("end main(String[] args) call:");
} //end of DEBUG if
} //end of main(String[] args)
} //end of class Pacman

View File

@@ -0,0 +1,342 @@
import javax.swing.*; //includes Timer
import java.awt.event.*; //ActionListener
/**
* CS1322: Programming Assignment #6 - Fall 2002
*
* <PRE>
* IDBox for: PacmanEngine.java
*
* Revisions: 1.0 Nov. 24, 2002
* Created the PacmanEngine class
*
* </PRE>
*
* Collaboration statement:
* "I worked on the homework assignment alone, using only
* course materials."
*
* @author
<A HREF="mailto:gtg142g@mail.gatech.edu">Roland Krystian Alberciak</A>
* @version Version 1.0, Nov. 24, 2002
*/
// imports are listed above IDBox
/*
* CONTROLLER
*/
public class PacmanEngine implements ActionListener, KeyListener
{
/** Debug value for toggling System.out.* output */
public static boolean DEBUG = false;
public static boolean DEBUG_CODE = false;
public static boolean DEBUG_MAIN = false;
/*
// =======================================================================
// Constructors
// =======================================================================
*/
/**
* Constructor 1. Specified default-overriding constructor for PacmanEngine.
* @param void No parameters.
* @return PacmanEngine instance/object.
*
public PacmanEngine()
{
} //end of PacmanEngine()
*/
/**
* Constructor 2. Specified default-overloading constructor for PacmanEngine.
* @param void No parameters.
* @return PacmanEngine instance/object.
*/
public PacmanEngine(PacmanFrame pmf, GameBoard gb)
{
this.setPmf( pmf );
this.setBoard( gb );
this.setGhosts( gb.getPfr().getGhosts() );
this.setPacman( gb.getPfr().getPacman() );
/*
GhostTimer= new Timer(P6Constants.GHOST_INTERVAL, ); //add AL
PacmanTimer = new Timer(P6Constants.PACMAN_INTERVAL, ); //add AL
*/
} //end of PacmanEngine()
/*
// =======================================================================
// Methods which override class Object methods
// =======================================================================
*/
/**
* Equal instance comparison. Compares if two instances are equal.
* @param o object-type reference of (hopefully) an PacmanEngine.
* @return boolean whether objects are equal.
*
public boolean equals (Object o)
{
} //end of equals(Object)
*/
/**
* toString instance printer. Prints properties of PacmanEngine.
* @return System.out.println(PacmanEngine instance) instance print.
*
public String toString()
{
} //end of toString()
*/
/*
// =======================================================================
// Class specific methods local to this instance (ex: forced by interface)
// =======================================================================
*/
public void actionPerformed(ActionEvent ae)
{
int togglePG=0;
//CALL REPAINT
if( (ae.getSource() instanceof Timer) ==true )
{
//Now to determine if moves are legal
if
(
(ae.getActionCommand()=="PacmanTimer")
|| (ae.getActionCommand()=="GhostTimer")
)
{
checkMoveValid(
pacman.getDirection(),
pacman.getX(),
pacman.getY(),
this.board.getPieceArray()[pacman.getX()][pacman.getY()]
);
}
else
System.out.println(this.getClass()+" error: wrong Timer.");
if (this.legal==true)
{
if (ae.getActionCommand()=="PacmanTimer")
getPacman().move(pacman.getDirection());
if (ae.getActionCommand()=="GhostTimer")
{
int gMoves[];
for(int itr=0; itr<getGhosts().length; itr=itr+1)
gMoves= getGhosts()[itr].getMove(this.pacman.getX(),
this.pacman.getY()
);
}
}
}
}
// returns true if valid, false if not.
public void checkMoveValid( int direction, int xAt, int yAt, Object piece )
{
boolean result=false;
switch (direction)
{
case (P6Constants.NORTH):
break;
case (P6Constants.EAST):
break;
case (P6Constants.SOUTH):
break;
case (P6Constants.WEST):
break;
}
this.legal=result;
}
/**
* Invoked when a key has been pressed.
*/
public void keyPressed(KeyEvent e) {}
/**
* Invoked when a key has been released.
*/
public void keyReleased(KeyEvent e) {}
/**
* Invoked when a key has been typed.
*/
public void keyTyped(KeyEvent e) {}
/*
// =======================================================================
// Methods dealing directly with the data within this instance
// (accessors, modifiers, etc)
// =======================================================================
*/
/**
* Get the value of pmf.
* @return value of pmf.
*/
public PacmanFrame getPmf() {
return pmf;
}
/**
* Set the value of pmf.
* @param v Value to assign to pmf.
*/
public void setPmf(PacmanFrame v) {
this.pmf = v;
}
/**
* Get the value of pacman.
* @return value of pacman.
*/
public Pacman getPacman()
{
return pacman;
}
/**
* Set the value of pacman.
* @param v Value to assign to pacman.
*/
public void setPacman(Pacman v)
{
this.pacman = v;
}
/**
* Get the value of ghosts.
* @return value of ghosts.
*/
public Ghost[] getGhosts()
{
return ghosts;
}
/**
* Set the value of ghosts.
* @param v Value to assign to ghosts.
*/
public void setGhosts(Ghost[] v)
{
this.ghosts = v;
}
/**
* Get the value of board.
* @return value of board.
*/
public GameBoard getBoard() {
return board;
}
/**
* Set the value of board.
* @param v Value to assign to board.
*/
public void setBoard(GameBoard v) {
this.board = v;
}
/*
// =======================================================================
// Protected Variables local to this instance
// =======================================================================
*/
/*
// =======================================================================
// Private Variables local to this instance
// =======================================================================
*/
private Timer GhostTimer;
private Timer PacmanTimer;
/*
* board. GameBoard instance.
* The GameBoard instance used to draw the state of the board.
*/
private GameBoard board;
private PacmanFrame pmf;
private Ghost[] ghosts;
/**
* pacman. Pacman instance.
* The Pacman instance in play.
*/
private Pacman pacman;
private boolean legal;
/*
// =======================================================================
// Main method (overrides this commenting system for readibility reasons)
// =======================================================================
*/
/**
* Debugging main for class PacmanEngine.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args)
{
if ( (args.length==1) && (args[0].equals("-db") ) )
DEBUG_MAIN=true; //else leave false: ignore input.
if (DEBUG_MAIN)
{ // NOTE: This {} encapsulates most of main and is leftmost margin as a flag.
// redundant ifs left in, in case the main if(DEBUG) statement was ommitted,
// this would then print out neat output, as an example of real running.
if (DEBUG) System.out.println("end main(String[] args) call:");
} //end of DEBUG if
} //end of main(String[] args)
} //end of class PacmanEngine

View File

@@ -0,0 +1,411 @@
import java.util.*;
import java.io.*;
/**
* CS1322: Programming Assignment #6 - Fall 2002
*
* <PRE>
* IDBox for: PacmanFileReader.java
*
* Revisions: 1.0 Nov. 23, 2002
* Created the PacmanFileReader class
*
* </PRE>
*
* Collaboration statement:
* "I worked on the homework assignment alone, using only
* course materials."
*
* @author
<A HREF="mailto:gtg142g@mail.gatech.edu">Roland Krystian Alberciak</A>
* @version Version 1.0, Nov. 23, 2002
*/
// imports are listed above IDBox
public class PacmanFileReader
{
/** Debug value for toggling System.out.* output */
public static boolean DEBUG = false;
public static boolean DEBUG_CODE = false;
public static boolean DEBUG_MAIN = false;
/*
// =======================================================================
// Constructors
// =======================================================================
*/
/**
* Constructor 1. Specified default-overriding constructor for PacmanFileReader.
* @param void No parameters.
* @return PacmanFileReader instance/object.
*
public PacmanFileReader()
{
} //end of PacmanFileReader()
*/
/**
* Constructor 2. Specified default-overloading constructor for PacmanFileReader.
* @param file_name a String file name of a board file
* @return PacmanFileReader instance/object.
*/
public PacmanFileReader(String file_name)
{
ghosts = new Ghost[4]; //0->1, 1->2, 2->3, 3->4
this.FILE_NAME=file_name;
pieceArray=new GamePiece[15][15];
read_5_lines();
read_15_lines();
} //end of PacmanFileReader(String)
/*
// =======================================================================
// Methods which override class Object methods
// =======================================================================
*/
/**
* Equal instance comparison. Compares if two instances are equal.
* @param o object-type reference of (hopefully) an PacmanFileReader.
* @return boolean whether objects are equal.
*
public boolean equals (Object o)
{
} //end of equals(Object)
*/
/**
* toString instance printer. Prints properties of PacmanFileReader.
* @return System.out.println(PacmanFileReader instance) instance print.
*/
public String toString()
{
String result="";
result= result+pacman.toString()+"\n"; //gets toString of Pacman.
for (int i=0; i<ghosts.length; i=i+1)
result= result+ghosts[i].toString()+"\n"; //gets toString of ghosts.
for (int y=0; y<15; y=y+1)
{
for (int x=0; x<15; x=x+1)
result=result+pieceArray[x][y].toString();
result= result+"\n";
}
return result;
} //end of toString()
/*
// =======================================================================
// Class specific methods local to this instance (ex: forced by interface)
// =======================================================================
*/
/**
* read_5_lines. Reads the first 5 lines of the given file.
* Reads each of the first five lines of the board file,
* gets the x and y start coordinates of objects and
* instantiates Pacman or each of the four Ghosts
* (depending on input, being which line is read)
* @param void No parameters.
*/
public void read_5_lines()
{
StringTokenizer st;
String temp_token;
int startpos[];
int char_num;
String line;
Integer temp_Int;
try
{
br = new BufferedReader( new FileReader(FILE_NAME) );
startpos = new int[2];
char_num=0;
line = br.readLine();
for (int num_line=0;
( (num_line<5) && (line!=null) && (line.equals("")==false) );
num_line=num_line+1)
{
st = new StringTokenizer(line);
while ( st.hasMoreTokens() )
{
temp_token = st.nextToken();
// temp_Int = new Integer(temp_token);
startpos[char_num]=Integer.parseInt(temp_token);
char_num= char_num+1;
} //endwhile
char_num=0;
if (num_line == 0 )
pacman = new Pacman(startpos[0], startpos[1]);
else //if (num_line!=0)
ghosts[num_line-1] = new Ghost(startpos[0], startpos[1], num_line);
line = br.readLine();
} //endfor
br.close();
} //endtry
catch( IOException ioe)
{
System.out.println("Error making pacman and ghosts.");
} //endcatch
} //end read_5_lines(void)
/**
* read_15_lines. Reads the board.
* Instantiates each cell of pieceArray to the appropriate GamePiece subclass
* passing in the x and y index as the GamePiece coordinates.
* @param void No parameters.
*/
public void read_15_lines()
{
StringTokenizer st;
String temp_token;
char board_line[];
int char_num;
String line;
Integer temp_Int;
try
{
br = new BufferedReader( new FileReader(FILE_NAME) );
board_line = new char[15];
char_num=0;
//ignore first 5 lines
for (int i=0; i<5; i=i+1)
line = br.readLine();
// 5th line, the real stuff.
line = br.readLine();
for (int y_coord=0;
( (y_coord<15) && (line!=null) && (line.equals("")==false) );
y_coord=y_coord+1)
{
st = new StringTokenizer(line);
while ( st.hasMoreTokens() )
{
temp_token= st.nextToken();
// temp_Int = new Integer(temp_token);
board_line[char_num]= temp_token.charAt(0);
char_num= char_num+1;
} //endwhile
char_num=0;
for (int x_coord=0; x_coord<15; x_coord=x_coord+1)
{
if (P6Constants.WALL.charAt(0) == board_line[x_coord])
{
pieceArray[x_coord][y_coord]=
new WallPiece(x_coord, y_coord);
}
else if (P6Constants.FLOOR.charAt(0) == board_line[x_coord])
{
pieceArray[x_coord][y_coord]=
new FloorPiece(x_coord, y_coord, false, false);
}
else if (P6Constants.NIBBLE.charAt(0) == board_line[x_coord])
{
pieceArray[x_coord][y_coord]=
new FloorPiece(x_coord, y_coord, true, false);
}
else if (P6Constants.SPECIAL.charAt(0) == board_line[x_coord])
{
pieceArray[x_coord][y_coord]=
new FloorPiece(x_coord, y_coord, false, true);
}
else // error
System.out.println("Error char in file.");
//STUB - use references and dynamic binding.
/*
switch (board_line[itr_bl])
{
case P6Constants.WALL.charAt(0)://'w'
break;
case P6Constants.FLOOR.charAt(0)://'f'
break;
case P6Constants.NIBBLE.charAt(0)://'n'
break;
case P6Constants.SPECIAL.charAt(0)://'s'
break;
}
*/
} //endfor
line = br.readLine();
} //endfor
br.close();
} //endtry
catch( IOException ioe)
{
System.out.println("Error making the board to play on.");
} //endcatch
} //end read_15_lines(void)
/*
// =======================================================================
// Methods dealing directly with the data within this instance
// (accessors, modifiers, etc)
// =======================================================================
*/
/**
* Get the value of pacman.
* @return value of pacman.
*/
public Pacman getPacman()
{
return pacman;
}
/**
* Set the value of pacman.
* @param v Value to assign to pacman.
*
public void setPacman(Pacman v)
{
this.pacman = v;
}
NOT IMPLEMENTED
*/
/**
* Get the value of ghosts.
* @return value of ghosts.
*/
public Ghost[] getGhosts()
{
return ghosts;
}
/**
* Set the value of ghosts.
* @param v Value to assign to ghosts.
*/
public void setGhosts(Ghost[] v)
{
this.ghosts = v;
}
/**
* Get the value of pieceArray.
* @return value of pieceArray.
*/
public GamePiece[][] getPieceArray()
{
return pieceArray;
}
/**
* Set the value of pieceArray.
* @param v Value to assign to pieceArray.
*/
public void setPieceArray(GamePiece[][] v)
{
this.pieceArray = v;
}
/*
// =======================================================================
// Protected Variables local to this instance
// =======================================================================
*/
/*
// =======================================================================
// Private Variables local to this instance
// =======================================================================
*/
/**
* pieceArray. A 15x15 array of GamePieces.
* This array will model the board seen in the GUI.
*/
private GamePiece[][] pieceArray;
/**
* br. To read the board file.
*/
private BufferedReader br;
/**
* instance variables for pacman and four ghosts
*/
private Pacman pacman;
private Ghost[] ghosts;
// Perhaps to use in the constructor.
private String FILE_NAME;
/*
// =======================================================================
// Main method (overrides this commenting system for readibility reasons)
// =======================================================================
*/
/**
* Debugging main for class PacmanFileReader.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args)
{
if ( (args.length==1) && (args[0].equals("-db") ) )
DEBUG_MAIN=true; //else leave false: ignore input.
if (DEBUG_MAIN)
{ // NOTE: This {} encapsulates most of main and is leftmost margin as a flag.
// redundant ifs left in, in case the main if(DEBUG) statement was ommitted,
// this would then print out neat output, as an example of real running.
PacmanFileReader pfr1 = new PacmanFileReader("board_1.txt");
PacmanFileReader pfr2 = new PacmanFileReader("board_2.txt");
System.out.println(pfr1);
System.out.println(pfr2);
if (DEBUG) System.out.println("end main(String[] args) call:");
} //end of DEBUG if
} //end of main(String[] args)
} //end of class PacmanFileReader

View File

@@ -0,0 +1,226 @@
/**
* CS1322: Programming Assignment #6 - Fall 2002
*
* <PRE>
* IDBox for: PacmanFrame.java
*
* Revisions: 1.0 Nov. 24, 2002
* Created the PacmanFrame class
*
* </PRE>
*
* Collaboration statement:
* "I worked on the homework assignment alone, using only
* course materials."
*
* @author
<A HREF="mailto:gtg142g@mail.gatech.edu">Roland Krystian Alberciak</A>
* @version Version 1.0, Nov. 24, 2002
*/
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
/*
*o an instance of GameBoard
o a JMenu with two JMenuItems:
- one that activates a new game: This should restart the
game no matter what the state of the current game.
- one that exits the program. This should stop the JVM just
as if we clicked on the X in the top right corner of the
frame.
o a default constructor which sets up the frame with a
BorderLayout, instantiates a new GameBoard and adds it to the
center. There is a constant in P6Constants called BOARD_FILE
containing the name of the file to tokenize into a GamePiece
array.
o We recommend you set the size of the frame to be about 520x520
o helper methods that set up the menus.
o We recommend you have this class be a listener for its own
JMenuItems. You will need to then have this class implement
ActionListener.
o The program should exit gracefully if either the quit menu is
chosen or the X in the top right is clicked.
*/
public class PacmanFrame extends JFrame implements ActionListener{
GameBoard cGameBoard;
JMenu cGameMenu;
JMenuItem jNewGame;
JMenuItem jExitGame; //why the heck would you want to do that!!
/**
*PacmanFrame Default Constructor
*Basically sets up the game
*/
public PacmanFrame(){
public class PacmanFrame extends JFrame implements ActionListener
{
/** Debug value for toggling System.out.* output */
public static boolean DEBUG = false;
public static boolean DEBUG_CODE = false;
public static boolean DEBUG_MAIN = false;
/**
* Constructor 2. Specified default-overloading constructor for PacmanFrame.
* @param void No parameters.
* @return PacmanFrame instance/object.
*/
public PacmanFrame()
{
super("Pacman: Pac-a-delic, yo");
super.getContentPane().setLayout( new BorderLayout() );
// also, remember "board2.txt"
// this.setGb(new GameBoard("board_2.txt") );
this.setGb(new GameBoard(P6Constants.BOARD_FILE) );
super.getContentPane().add(getGb(), BorderLayout.CENTER);
makeGUI();
addToGUI();
super.setSize(520, 520);
super.setResizable(false); //processWindowEvent();
super.setDefaultCloseOperation(EXIT_ON_CLOSE);
super.setVisible(true); //super.show();
} //end of PacmanFrame()
public void makeGUI()
{
newGame = new JMenuItem("Restart Pacman");
exitGame = new JMenuItem("Exit Pacman");
mainMenu = new JMenu("Pacman Menu");
menuBar = new JMenuBar();
}
public void addToGUI()
{
mainMenu.add(newGame);
mainMenu.add(exitGame);
menuBar.add(mainMenu); // mainMenu is placed into menuBar.
super.setJMenuBar(menuBar);
}
public void actionPerformed(ActionEvent ae)
{
if( (ae.getSource() instanceof JMenuItem) ==true )
{
//Restart Pacman
if( ae.getActionCommand().equals("Restart Pacman") ==true )
{
System.out.println("Restarted Pacman");
} //endif
else if( ae.getActionCommand().equals("Exit Pacman") ==true )
{
System.exit(1); //Exits gracefully. Compassionate Conservative.
System.out.println("Exiting Pacman");
} //endif
}
}
/*
// =======================================================================
// Methods dealing directly with the data within this instance
// (accessors, modifiers, etc)
// =======================================================================
*/
/**
* Get the value of gb.
* @return value of gb.
*/
public GameBoard getGb()
{
return gb;
}
/**
* Set the value of gb.
* @param v Value to assign to gb.
*/
public void setGb(GameBoard v)
{
this.gb = v;
}
/*
// =======================================================================
// Protected Variables local to this instance
// =======================================================================
*/
/*
// =======================================================================
// Private Variables local to this instance
// =======================================================================
*/
/**
* gb. An instance of GameBoard.
* To be used in accessing GameBoard's elements, and displaying in Frame.
*/
private GameBoard gb;
private JMenu mainMenu;
private JMenuBar menuBar;
private JMenuItem newGame;
private JMenuItem exitGame;
/*
// =======================================================================
// Main method (overrides this commenting system for readibility reasons)
// =======================================================================
*/
/**
* Debugging main for class PacmanFrame.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args)
{
if ( (args.length==1) && (args[0].equals("-db") ) )
DEBUG_MAIN=true; //else leave false: ignore input.
if (DEBUG_MAIN)
{ // NOTE: This {} encapsulates most of main and is leftmost margin as a flag.
// redundant ifs left in, in case the main if(DEBUG) statement was ommitted,
// this would then print out neat output, as an example of real running.
PacmanFrame pf = new PacmanFrame();
if (DEBUG) System.out.println("end main(String[] args) call:");
} //end of DEBUG if
} //end of main(String[] args)
} //end of class PacmanFrame

View File

@@ -0,0 +1,155 @@
/**
* CS1322: Programming Assignment #6 - Fall 2002
*
* <PRE>
* IDBox for: WallPiece.java
*
* Revisions: 1.0 Nov. 21, 2002
* Created the WallPiece class
*
* </PRE>
*
* Collaboration statement:
* "I worked on the homework assignment alone, using only
* course materials."
*
* @author
<A HREF="mailto:gtg142g@mail.gatech.edu">Roland Krystian Alberciak</A>
* @version Version 1.0, Nov. 21, 2002
*/
// imports are listed above IDBox
/**
* MODEL.
* Gamepiece. Wallpiece extends GamePiece.
* Adds the functionality of a wall on the game board.
* Neither ghosts nor Pacman can travel on or through walls.
* They can only travel on FloorPieces.
*/
public class WallPiece extends GamePiece
{
/** Debug value for toggling System.out.* output */
public static boolean DEBUG = false;
public static boolean DEBUG_MAIN = false;
/*
// =======================================================================
// Constructors
// =======================================================================
*/
/**
* Constructor 1. Specified default-overriding constructor for WallPiece.
* @param void No parameters.
* @return WallPiece instance/object.
*
public WallPiece()
{
} //end of WallPiece()
*/
/**
* Constructor 1. Specified default-overriding constructor for WallPiece.
* @param x the location along the x-axis.
* @param y the location along the y-axis.
* @return WallPiece instance/object.
*/
public WallPiece(int x, int y)
{
super(x,y); //Chains to the super constructor (GamePiece)
} //end of WallPiece(int, int)
/*
// =======================================================================
// Methods which override class Object methods
// =======================================================================
*/
/**
* Equal instance comparison. Compares if two instances are equal.
* @param o object-type reference of (hopefully) an WallPiece.
* @return boolean whether objects are equal.
*
public boolean equals (Object o)
{
} //end of equals(Object)
*/
/**
* toString instance printer. Prints properties of WallPiece.
* @return System.out.println(WallPiece instance) instance print.
*/
public String toString()
{
String result="";
result= P6Constants.WALL;
result= result+" "; //cleanup, autoprepare for output
return result;
} //end of toString()
/*
// =======================================================================
// Class specific methods local to this instance
// =======================================================================
*/
/*
// =======================================================================
// Methods dealing directly with the data within this instance
// (accessors, modifiers, etc)
// =======================================================================
*/
/*
// =======================================================================
// Private Variables local to this instance
// =======================================================================
*/
/*
// =======================================================================
// Main method (overrides this commenting system for readibility reasons)
// =======================================================================
*/
/**
* Debugging main for class WallPiece.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args)
{
if ( (args.length==1) && (args[0].equals("-db") ) )
DEBUG_MAIN=true; //else leave false: ignore input.
if (DEBUG_MAIN)
{ // NOTE: This {} encapsulates most of main and is leftmost margin as a flag.
// redundant ifs left in, in case the main if(DEBUG) statement was ommitted,
// this would then print out neat output, as an example of real running.
WallPiece w1 = new WallPiece(1,5);
System.out.println(w1);
if (DEBUG) System.out.println("end main(String[] args) call:");
} //end of DEBUG if
} //end of main(String[] args)
} //end of class WallPiece

View File

@@ -0,0 +1,20 @@
0 7
1 1
13 1
13 13
1 13
w w w w w w w w w w w w w w w
w s f n n n n w n n n n f s w
w f w w w w n w n w w w w f w
w n w n n n n w n n n n w n w
w n w n w w w w w w w n w n w
w n w n n n n n n n n n w n w
w n w n n n w w w n n n w n w
f n n n n n w f w n n n n n w
w n w n n n w w w n n n w n w
w n w n n n n n n n n n w n w
w n w n w w w w w w w n w n w
w n w n n n n w n n n n w n w
w f w w w w n w n w w w w f w
w s f n n n n w n n n n f s w
w w w w w w w w w w w w w w w

View File

@@ -0,0 +1,20 @@
0 7
1 1
13 1
13 13
1 13
w w w w w w w w w w w w w w w
w s f n n n n n n n n n f s w
w f w w w w w n w w w w w f w
w n w f f f w n w f f f w n w
w n w w w w w n w w w w w n w
w n w n n n n n n n n n w n w
w n w n w n w w w n w n w n w
f n n n n n w f w n n n n n f
w n w n w n w w w n w n w n w
w n w n n n n n n n n n w n w
w n w w w w w n w w w w w n w
w n w f f f w n w f f f w n w
w f w w w w w n w w w w w f w
w s f n n n n n n n n n f s w
w w w w w w w w w w w w w w w

BIN
CS1322/p6/Krystian/gh1.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

BIN
CS1322/p6/Krystian/gh2.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 B

BIN
CS1322/p6/Krystian/gh3.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 B

BIN
CS1322/p6/Krystian/gh4.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

BIN
CS1322/p6/Krystian/ghRA.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 B

BIN
CS1322/p6/Krystian/p6.zip Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 B

View File

@@ -0,0 +1,92 @@
/**
* <PRE>
* MoveablePiece.java
*
* Revisions: 1.0 Nov. 11, 2002
* Created the MoveablePiece class
* 1.1 Nov. 11, 2002
* Compiled, Finished, Done
*
* </PRE>
*
* Collaboration Statement:
* I worked on the homework assignment alone, using only
* course materials.
*
* Created with JCreatorLE, some indents are off when viewed through notepad
* or EMACS
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.1, Nov. 11, 2002
*/
public abstract class MoveablePiece extends GamePiece implements P6Constants{
////////////////
//Constructors//
////////////////
/**
*Constructor
*@param x, the x coordinate
*@param y, the y coordinate
*/
public MoveablePiece(int x, int y){
super(x,y);
}
///////////
//Methods//
///////////
/**
*Move the piece in a direction
*@param direction to be moved
*/
public void move(int direction){
switch(direction){
case NORTH:
//if(y==0){}
//else{
y--;
//}
break;
case EAST:
//if(x==max){}
//else{
x++;
//}
break;
case SOUTH:
//if(y==max){}
//else{
y++;
//}
break;
case WEST:
//if(x==0){}
//else{
x--;
//}
break;
default:
System.err.println("How the heck did you do this");
break;
}
}
/*************************************************************/
/**
* Debugging main for class MoveablePiece.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args) {
}// end of main(String[] args)
}// end of class MoveablePiece

116
CS1322/p6/MyWay/CCoord.java Normal file
View File

@@ -0,0 +1,116 @@
/**
* <PRE>
* Coord.java
*
* Revisions: 1.0 Nov. 12, 2002
* Created the Coord class
* 1.1 Nov. 12, 2002
* Compiled, Commented, Finished
*
* </PRE>
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.1, Nov. 12, 2002
*/
/*
*Everything from the Model and Control are extenstions of Coord for the
*simple reason that everything in the 2D world will be a coordinate on a Grid
*handled by a separate class
*/
public class CCoord {
/**
*Points
*/
private int x;
private int y;
private int h;
///////////////
//Constructor//
///////////////
/**
*Default Constructor
*sets all values to 0
*/
public CCoord(){
x = 0;
y = 0;
h = 0;
}
/**
*Takes in params for all values
*@param x, the x coordinate
*@param y, the y coordinate
*@param h, the height value
*/
public CCoord(int x, int y, int h){
this.x = x;
this.y = y;
this.h = h;
}
///////////////////////
//Accessors/Modifiers//
///////////////////////
/**
*@return value of x
*/
public int getX(){
return x;
}
/**
*@param x, the new x coordinate
*/
public void setX(int x){
this.x = x;
}
/**
*@return value of y
*/
public int getY(){
return y;
}
/**
*@param y, the new y value
*/
public void setY(int y){
this.y = y;
}
/**
*@return the height
*/
public int getH(){
return h;
}
/**
*@param h, the new height
*/
public void setH(int h){
this.h = h;
}
/*********************************************/
/**
* Debugging main for class Coord.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args) {
}// end of main(String[] args)
}// end of class Coord

View File

@@ -0,0 +1,77 @@
/**
* <PRE>
* CEngine.java
*
* Revisions: 1.0 Nov. 17, 2002
* Created the CEngine class
*
* </PRE>
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.0, Nov. 17, 2002
*/
public class CEngine {
/**
*Scan the input file and assign game map to the grid
*/
public void scanMap(String inFile){
try{
BufferedReader br = new BufferedReader(new FileReader(inFile));
}
catch(FileNotFoundException fnfe){
System.err.println("File not found - CNode.scanMap()" + fnfe);
}
//skip first 5 lines
try{
for(int i=0;i<5;br.readLine());
}
catch(Exception e){
System.err.println(e+" when attempting to skip 5 lines of file"+
" - CNode.scanMap()");
}
for(int x=0; x<15; x++){
String strTemp = br.readLine();
for(int y=0; y<15; y++){
switch(strTemp.charAt(z)){
case s:
grid[x][y] = new CTile(x,y,1,false);
grid[x][y].setSpecial(true);
grid[x][y].setNibble(false);
break;
case f:
grid[x][y] = new CTile(x,y,1,false);
grid[x][y].setParam(false);
break;
case n:
grid[x][y] = new CTile(x,y,1,false);
grid[x][y].setNibble(true);
grid[x][y].setSpecial(false);
break;
//create a wall by default
default:
case w:
grid[x][y] = new CTile(x,y,2,false);
break;
}//end switch
}//end for(y)
}//end for(x)
}
/**
* Debugging main for class CEngine.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args) {
}// end of main(String[] args)
}// end of class CEngine

View File

@@ -0,0 +1,69 @@
/**
* <PRE>
* CGrid.java
*
* Revisions: 1.0 Nov. 17, 2002
* Created the CGrid class
*
* </PRE>
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.0, Nov. 17, 2002
*/
import java.io.*;
public class CGrid {
/**
*2D array to store the game data
*/
private CCoord[][] grid;
////////////////
//Constructors//
////////////////
public CGrid(){
//create default size
this(15,15);
}
public CGrid(int iLength, int iHeight){
grid = new CCord[iLength][iHeight];
}
public CGrid(String inFile){
this(15,15);
this.scanMap();
}
public CGrid(String inFile, boolean varGrid){
if(varGrid){
scanMap(inFile);
}
else{
this(15,15);
scanMap(inFile);
}
}
///////////
//Methods//
///////////
/**
* Debugging main for class CGrid.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args) {
}// end of main(String[] args)
}// end of class CGrid

View File

@@ -0,0 +1,57 @@
/**
* <PRE>
* CIntelligence.java
*
* Revisions: 1.0 Nov. 13, 2002
* Created the CIntelligence class
*
* </PRE>
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.0, Nov. 13, 2002
*/
public class CIntelligence implements Constants{
public CGrid createNodeGrid(CGrid cGrid, int iFloorLevel){
CGrid cToSend = new CGrid(cGrid.getX(),cGrid.getY());
for(int x=0; x<cGrid.length; x++){
for(int y=0; y<cGrid[].length;y++){
if(cGrid[x][y].getH() == iFloorLevel){
cToSend[x][y] = new Coord(x,y,iFloorLevel);
}
}
}
for(int x=0; x<cGrid.length;x++){
for(int y=0; y<cGrid[].length;y++){
if(cToSend[x][y] != null){
createNode(cToSend,new Coord(x,y,iFloorLevel));
}
}
}
}
private void createNode(CGrid cToAdd, Coord cAt){
int x = cAt.getX();
int y = cAt.getY();
int h = cAt.getH();
/**
* Debugging main for class CIntelligence.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args) {
}// end of main(String[] args)
}// end of class CIntelligence

View File

@@ -0,0 +1,59 @@
/**
* <PRE>
* Monster.java
*
* Revisions: 1.0 Nov. 13, 2002
* Created the Monster class
*
* </PRE>
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.0, Nov. 13, 2002
*/
public class CMonster extends CCoord implements Constants{
/**
*Defines the Intelligence of the monster
*whether player controlled or CPU controlled
*/
private CIntelligence oIntel;
/**
*Define image for monster
*Icons should be named as follows:
*Iconname000.jpg, with the 000 incrementing up with each animation number
*When used with the constructor, just give the iconname without 000 and the
*constructor will search for the correct icon (so for a single icon lacking
*any animation, it would be iconname000.jpg and be sent to the constructor
*as iconname. Similarly, an icon with animations would have files
*icon000.x, icon001.x, and icon002.x and have the name "icon" send to the
*constructor.
*/
ImageIcon[] imgSprite;
////////////////
//Constructors//
////////////////
public CMonster(int x, int y, int h, String iconFile, CIntelligence oIntel){
super(x,y,h);
}
///////////
//Methods//
///////////
/**
* Debugging main for class Monster.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args) {
}// end of main(String[] args)
}// end of class Monster

106
CS1322/p6/MyWay/CNode.java Normal file
View File

@@ -0,0 +1,106 @@
/**
* <PRE>
* CNode.java
*
* Revisions: 1.0 Nov. 17, 2002
* Created the CNode class
* 1.1 Nov. 17, 2002
* Added Primary code, Commented, Finished
*
* </PRE>
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.1, Nov. 17, 2002
*/
/**
*The Engine class (CEngine) can take in a board and turn it into a game map.
*The Engine class then creates another grid which will below the game map
* that holds the nodes for the Intelligence class (CIntelligence).
*The Node classes hold the data for where a ghost can move and are used to
* send ghosts after the player. If pacman is between Node A and Node B and
* a ghost finds itself in Node A, it will turn and head in the direction of
* Node B. These Intelligence specifics are handled in the
* CIntelligence->CIntelGhost class
*/
public class CNode extends CCoord{
/**
*Define where the ghost can move when at this node
*/
private boolean MV_LEFT;
private boolean MV_RIGHT;
private boolean MV_UP;
private boolean MV_DN;
private boolean INC_HEIGHT;
///////////////
//Constructor//
///////////////
/**
*@param up, can move up?
*@param down, can move down?
*@param left, can move left?
*@param right, can move right?
*@param incH, can increase height by using node?
*@param x, x-coord
*@param y, y-coord
*@param h, h-coord
*/
public CNode(boolean up, boolean down, boolean left, boolean right,
boolean incH, int x, int y, int h){
super(x,y,h);
MV_UP = up;
MV_DN = down;
MV_LEFT = left;
MV_RIGHT = right;
INC_HEIGHT = incH;
}
///////////
//Methods//
///////////
/**
*@return true if can go up from node
*/
public boolean canMV_UP(){
return MV_UP;
}
/**
*@return true if can go down from node
*/
public boolean canMV_DN(){
return MV_DN;
}
/**
*@return true if can move left from node
*/
public boolean canMV_LEFT(){
return MV_LEFT;
}
/**
*@return true if can move right
*/
public boolean canMV_RIGHT(){
return MV_RIGHT;
}
/**
*@return true if can increase height at this node
*/
public boolean canINC_HEIGHT(){
return INC_HEIGHT;
}
/**
*@return Coordinates of the Node
*/
public CCoord getNodeCoord(){
return (new CCoord(this.getX(), this.getY(), this.getH()));
}
}// end of class CNode

View File

@@ -0,0 +1,80 @@
/**
* <PRE>
* Tile.java
*
* Revisions: 1.0 Nov. 12, 2002
* Created the Tile class
*
* </PRE>
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.0, Nov. 12, 2002
*/
public class CTile extends CCoord{
/**
*Defines whether the object is coming from the ground up to a given level
*or whether it is a floating object (i.e. a bridge)
*/
private boolean bIsFloating;
/**
*Define whether block has a special nibble
*/
private boolean bHasSpecial;
/**
*Define whether block has a nibble
*/
private boolean bHasNibble;
////////////////
//Constructors//
////////////////
/**
*@param x, the x-coord
*@param y, the y-coord
*@param h, the height
*/
public CTile(int x, int y, int h){
this(x,y,h,false);
}
/**
*Same as other constructor but adds
*@param bIsFloating, defines whether the object is floating or not
*/
public CTile(int x, int y, int h, boolean bFloating){
super(x,y,h);
bIsFloating = bFloating;
}
///////////////////////
//Accessors/Modifiers//
///////////////////////
/**
*@return true if object can be passed over
*/
public boolean isPassable(Coord op){
if(op.getH() == this.h){
return true;
}
return false;
}
/**
* Debugging main for class Tile.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args) {
}// end of main(String[] args)
}// end of class Tile

View File

@@ -0,0 +1,27 @@
/**
* <PRE>
* Constants.java
*
* Revisions: 1.0 Nov. 13, 2002
* Created the Constants class
*
* </PRE>
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.0, Nov. 13, 2002
*/
public interface Constants {
/*Directions*/
/**
*Define 4 movement constants: MV_UP, MV_DN, MV_LFT, MV_RGHT
*/
public static final int MV_UP = 0;
public static final int MV_DN = 1;
public static final int MV_LFT = 2;
public static final int MV_RGHT = 3;
}// end of class Constants

View File

@@ -0,0 +1,20 @@
0 7
1 1
13 1
13 13
1 13
w w w w w w w w w w w w w w w
w s f n n n n w n n n n f s w
w f w w w w n w n w w w w f w
w n w n n n n w n n n n w n w
w n w n w w w w w w w n w n w
w n w n n n n n n n n n w n w
w n w n n n w w w n n n w n w
f n n n n n w f w n n n n n w
w n w n n n w w w n n n w n w
w n w n n n n n n n n n w n w
w n w n w w w w w w w n w n w
w n w n n n n w n n n n w n w
w f w w w w n w n w w w w f w
w s f n n n n w n n n n f s w
w w w w w w w w w w w w w w w

View File

@@ -0,0 +1,20 @@
0 7
1 1
13 1
13 13
1 13
w w w w w w w w w w w w w w w
w s f n n n n n n n n n f s w
w f w w w w w n w w w w w f w
w n w f f f w n w f f f w n w
w n w w w w w n w w w w w n w
w n w n n n n n n n n n w n w
w n w n w n w w w n w n w n w
f n n n n n w f w n n n n n f
w n w n w n w w w n w n w n w
w n w n n n n n n n n n w n w
w n w w w w w n w w w w w n w
w n w f f f w n w f f f w n w
w f w w w w w n w w w w w f w
w s f n n n n n n n n n f s w
w w w w w w w w w w w w w w w

800
CS1322/p6/MyWay/p6.nfo.txt Normal file
View File

@@ -0,0 +1,800 @@
CS1322: Programming Assignment #6 - Fall 2002.
Assigned: November 11, 2002
Phase I Instant Feedback Due Date: November 21, 2002 11:59:59
Phase II Instant Feedback Due Date: November 25, 2002 11:59:59
DUE Date: November 25, 2002 11:59:59 PM
Program Title: Pacman
Files Provided
====================================================================
o P6.nfo.txt - this file
o board_1.txt - an input file that specifies board #1
o board_2.txt - an input file that specifies board #2
o GhostAI.class - a class that makes decisions on Ghost movement
o P6Constants.java - Interface needed for P6
(You must use these constants when appropriate)
o various image files
Learning Objectives
====================================================================
o Advanced DataStructures
o Advanced GUIs
Other Resources
====================================================================
Website containing screenshots and nfo file with pictures at
http://128.61.63.158/cs1322/P6
PROGRAM OVERVIEW
====================================================================
Welcome to the 6th and final programming assignemnt! A word of
caution: This project will be the most difficult one in this course.
You will be required to utilize all that you have learned in order to
complete this assignment. START EARLY!
This assignment will be very similar to the arcade classic - Pacman.
For those of you who aren't familiar with the game, Pacman is a little
yellow smiley face controlled by you, the user. The goal is to have
Pacman eat all the nibbles (dots on the board). If Pacman completes
this objective, you win the game. However, there are 4 ghosts
pursuing Pacman. If one of the ghosts catches him, the game is over.
Pacman has one defense however: the special nibbles placed on the
board. If Pacman eats a special nibble, the ghosts can be eaten by
Pacman for a time. During this period, the ghosts run away from
Pacman. If a ghost is eaten, it returns to its start location on the
board and resumes it's role of pursing and attempting to catch Pacman
even if the others are still running from Pacman. After a time, all
the ghosts return to the original state of pursuing Pacman.
HEY! guess what! START EARLY!
A Word About Imlementation and Grading
====================================================================
In the past five assignments, the TAs and nfo files have largely
specified exactly which methods, parameters, classes and fields you
would need to complete the assignment. This assignment will be
different. While we will supply a recommended design, the exact means
of implementation in terms of which methods or fields you use is left
ambiguous. With the exception of the Instant Feedback phases, you
will be largely responsible for figuring out which methods you wish to
create to solve a given problem. This assignment will be graded more
in terms of functionality i.e. "does this feature function correctly?"
rather than "is this method present with these exact parameters".
With this in mind, you can feel free to create whatever methods you
wish to solve the problem. In addition, those of you looking for a
challenge or wanting to fight "the man" can feel free to deviate as
much or as little as you want from the design below. (Again, with the
exception of the Instant Feedback phases. You must do what we tell
you there.) Keep in mind, however, that as you deviate from the
recommended design, it becomes difficult to give partial credit if
things don't work correctly. So if you do choose to go your own way,
do so at your own risk. If you are not yet comfortable leaving the
nest, the design below is provided.
<cough>Start Early!
Overall Design
====================================================================
In the MVC (Model, View, Controller) paradigm of GUI programming, we
separate parts of the program into three pieces:
The Model - This class or group of classes stores the state of the
data in the program. It is often a data structure such as a BST or
Heap. The model typically is independent of any GUI widgets. This
allows our program to be more portable. If we wanted to use our
data in some interface other than a GUI, say a text console
interface, there would be little to no recoding of the model.
The View - This gruop of classes is responsible for displaying the
GUI. Often they extend or hold GUI widget instances. We don't
want the view to hold the state of any data. This is the role of
the model.
The Controller - This class or group of classes is responsible for
manipulating the model according to the needs of the program.
Often is the listener of events from GUI widgets (as EventHandler
was in P5)
The UIDelegate paradigm of GUI programming is very similar to MVC.
The only difference is that in UIDelegate we combine the roles of View
and Controller into one class or group of classes.
Now an overview of the classes of Pacman:
Model - GamePiece, WallPiece, FloorPiece, MoveablePiece, Ghost, Pacman
View - GameBoard, PacmanFrame
Controller - PacmanFileReader, PacmanEngine, PacmanFrame
Notice PacmanFrame is both a View and a Controller. This means it
will be a UIDelegate class.
PHASE I - The Pieces - Instant Feedback
====================================================================
The classes in this phase will be model classes that represent the
tiles and pieces on the board. They will be independent of any GUI
widgets. They merely will hold information about the piece such as
where it is on the board.
Create a class called GamePiece. This class will be an abstract super
class to all pieces of the game board. GamePiece should include the
following:
o a protected int called "x". This variable will represent which
column the piece is in. i.e., it's location along the x-axis.
o a protected int called "y". This variable will represent which
row the piece is in. i.e., it's location along the y-axis.
Together these two variables represent the exact location of the
board this particular piece is in. The location 0,0 will be the
upper left hand corner of the game board.
o public accessors for both of the above variables.
o a public method called setPostition that takes in two
parameters: x followed by y and sets the location variables to
these parameters.
o a constructor that takes in two parameters: x followed by y and
sets the location variables to these parameters.
Create a class called FloorPiece. This class will extend GamePiece.
It will also add the functionality of nibbles (The dots that Pacman
eats) Each FloorPiece can have a regular nibble, a special nibble
(one that allows Pacman to chase the ghosts), or neither (but not
both). FloorPiece should have the following:
o a private boolean variable called "hasNibble". This variable
will represent whether or not this FloorPiece has a nibble that
Pacman eats (the regular ones, not the ones that lets Pacman
chase Ghosts)
o a private boolean variable called "hasSpecial". This variable
will represent whether or not this FloorPiece has a special
nibble that allows Pacman to chase Ghosts.
o accessors and modifiers for both of the above
o a constructor that takes in four parameters: the x and y
location and two booleans representing whether or not this FloorPiece
should have a nibble or a special. This constructor should chain
to the super constructor and set hasNibble and hasSpecial
according to the parameters.
Create a class called WallPiece. This class will extend GamePiece.
It will also add the functionality of a wall on the game board.
Neither ghosts nor Pacman can travel on or through walls. They can
only travel on FloorPieces. Your WallPiece class should have the
following:
o a constructor that takes in two parameters: the x and y
locations of this piece. This constructor should chain to the
super constructor.
Create a class called MoveablePiece. This class will be abstract and
extend GamePiece. This class will be the super class of both Ghost
and Pacman. MoveablePiece should have the following:
o a constructor that takes in two ints: the x and y location of
this piece. This constructor should chain to the
super constructor.
o a public method named "move" that returns void and takes in an
int representing a direction. This parameter will be either
NORTH, EAST, SOUTH, or WEST from P6Constants. This constants
will represent up, right, down and left respectively. In this
method you should "move" the piece. This means modify the
piece's x or y location accordingly. Don't forget that (0,0) is
the top left corner of the board.
PHASE II - Ghosts and Pacman - Instant Feedback
====================================================================
These two classes will be model classes for Pacman and an individual ghost.
Create a class called Pacman which extends MoveablePiece. This class
will model the Pacman piece which the user will control. Pacman
should include the following:
o a private int variable named "direction". This variable will
contain one of the four constants from P6Constants: NORTH, EAST,
SOUTH, WEST. This variable will represent the direction Pacman
is currently heading on the board. This variable will be
initialized to EAST.
o a constructor that takes in two ints: the x and y location of
this piece. This constructor should chain to the
super constructor.
Now the Ghosts...
Before we get into the details of implementing Ghost, let's talk
about how the Ghost will chase (or run from) Pacman.
Provided to you is a class called GhostAI. This class has a single
static method:
public static int[] getGhostMove(int ghostX, int ghostY,
int pacmanX, int pacmanY)
Here's what the parameters do
o ghostX: the x location of a ghost
o ghostY: the y location of a ghost
o pacmanX: the x location of Pacman
o pacmanY: the y location of Pacman
The return value will always be an int array of size four. The array
contains each of the four directions from P6Constants in the order of
priority. So:
o index 0: the ghost's first choice of directions to move
o index 1: the ghost's second choice of directions to move
o index 2: the ghost's third choice of directions to move
o index 3: the ghost's fourth (last) choice of directions to
move
So why bother with all this priority stuff? Why not just return the
direction the ghost wants to move. Well what if we have a case like
the following:
Ghost
Wall Wall Wall Wall Wall
Pacman
The ghost's first choice of movement will be SOUTH toward Pacman. But
that's not an option because of the wall. We don't want our Ghosts to
just sit if they can't go somewhere. So we would try our second
choice, which in this case would be either EAST or WEST. The last
choice, in index 3, would be NORTH away from Pacman. Consider the
following case:
Wall Wall
Wall Wall
Wall Ghost Wall
Wall Wall Wall
Pacman
In this case, none of the first three choices will contain viable
moves. So the ghost's only choice is to go up. If this happens,
there will be a gap between the Ghost and the bottom wall. On the
next turn the Ghost can indeed use its first choice and move SOUTH
(Given that Pacman isn't going anywhere for some reason) If Pacman
were to stay put, the Ghost would end up oscillating back and forth
against the bottom wall. What happens if the Ghost is running from
Pacman after Pacman ate a special nibble. The priorities are just
reversed. Logically this makes sense. If a ghost's first priority
was to move SOUTH towards Pacman while chasing Pacman, SOUTH will be
the last priority when Pacman is chasing the ghost. Unfortunately,
the Ghost artificial intelligence algorithm we provide is somewhat
primitive. Consider the following case:
Wall Wall Wall Wall Wall Wall
Wall
Pacman Wall Ghost
Wall Wall Wall
If Pacman were to never move, the Ghost would simply run up against
the West wall over and over. If the Ghost were smart, it would go
around the South wall to get to Pacman but it doesn't. You must use
the Ghost movement algorithm we provide for instant feedback.
However, for the final turn in, you can develop your own, better
movement algorithm if you wish. (Just make sure it works) This would
be worth some juicy extra credit.
Create a class called Ghost that extends MoveablePiece. This class
will represent a Ghost. There will be four instances in your program,
one for each of the four ghosts. Ghost should have the following:
o a private int variable called "ghostNum". This will be the
number of the ghost.
o a private boolean variable called "runAwayFlag". This will be
true if this Ghost is running from Pacman and false if chasing
Pacman.
o a private int variable called "runAwayCount". This will
contain the number of returns remaining for this ghost to run
from Pacman. (Remember that a ghost will run from Pacman for a
fixed number of moves if Pacman eats a special nibble)
o a private int variable called "startX". This will contain the
starting x coordinate for this ghost.
o a private int variable called "startY". This will contain the
starting y coordinate for this ghost.
The startX and startY variables together represent the start
coordinates for the Ghost. The ghost will begin the game at this
location. The ghost will also return to this location if eaten
by pacman when running from him.
o accessors for ghostNum, runAwayFlag, startX and startY
o a public void method named "runAway" which takes in no parameters.
This sets runAwayFlag to true and initializes runAwayCount to
RUN_AWAY_DURATION from P6Constants
o a public void method called "resetGhost" which takes in no
parameters. This method will be invoked if this ghost is eaten
by Pacman. It should turn runAwayFlag to false and return the
ghost to it's start coordinates.
o a public method named "getMove" that returns an int[] and takes
in two parameters: pacman's x and y location. This method will
calculate the array of size four containing this ghost's choices
of movement as described above. Feel free to use the GhostAI
class. Keep in mind however that the getGhostMove method
provided assumes the ghost is chasing pacman. You will need to
modify the array to have the ghost run away from Pacman if this
is the case. If the Ghost is indeed running from Pacman, be sure
to deduct a turn from runAwayCount and check to see if
runAwayCount is zero, in which case you should have the ghost no
longer run from Pacman. This method will not actually set the
location of the ghost based on the GhostAI method. It simply
returns the array of choices. We do this because this ghost has
no clue whether any of its choices will take it into a wall. A
class later in the project will process the choices and decide
which moves are legal for this ghost. The ghost will then be
told which way to move.
o a public constructor that takes in three parameters: an x and y
start location and a ghostNum representing this ghost's number.
You should set the instance variable accordingly.
PHASE III - PacmanFileReader
====================================================================
From this point, you can feel free to ignore the design and do your
own thing if you wish provided you supply all the functionality of the
design we recommend. Remember the warning about grading though.
Even if you choose to use your own design, your program must still
present equivalent capabilities. And if your program doesn't work and
you used a different design, there is less chance of getting partial
credit.
Also realize that from this point there will be less explicit
information on what methods you need or how to implement them. There
are a variety of implementations that fit the suggested design. You
can choose one that suits you. You do not need to ask if you can
create a particular method or field. If it seems like you need method
x to perform some task, by all means, do it.
Onward...
Create a class called PacmanFileReader. This class will be
responsible for reading in a board file like one of the two we
provided you and translating it into an array of GamePiece instances.
If you open up one of the board files, you'll notice several rows of
seemingly random characters. Let's discuss the tokens found in
board_1.txt:
w <==> P6Constants.WALL <==> an instance of WallPiece
f <==> P6Constants.FLOOR <==> an instance of FloorPiece w/out either
kind of nibbles
n <==> P6Constants.NIBBLE <==> an instance of FloorPiece with a
regular nibble
s <==> P6Constants.SPECIAL <==> an instance of FloorPiece with a
special nibble
The first five rows specify the starting locations of Pacman and the
ghosts.
0 7 <-- Pacman's x,y start coordinates
1 1 <-- Ghost #1's startX and startY instance variable values.
13 1 <-- Ghost #2's startX and startY instance variable values.
13 13 <-- Ghost #3's startX and startY instance variable values.
1 13 <-- Ghost #4's startX and startY instance variable values.
The next rows will contain the four tokens discussed above. There
will always be 15x15 tokens. Look at the picture on the project
website under "using board_1.txt". Can you see the relationship
between the text file and the appearance of the board?
In this class, the goal is to translate these tokens into an array of
GamePieces. We recommend your PacmanFileReader have the following:
o a private GamePiece[][] variable named "pieceArray". This
array will model the board seen in the GUI.
o a BufferedReader to read the board file
o instance variables for pacman and four ghosts
o a constructor that takes in the name of a file to read.
o a helper method or series of helper methods called by the
consturctor that does the following:
- instantiates a BufferedReader to read the board file
passed into the constructor
- Reads each of the first five lines of the board file, uses
a StringTokenizer to get the x and y start coordinates and
instantiates Pacman or each of the four Ghosts (depending on
which line you're on)
- for the rest of the fifteen lines: Keep two counters, one
for the x index of the board and one for the y index.
Read in a line and use a StringTokenizer to get each
token. Instantiate each cell of pieceArray to the
appropriate GamePiece subclass passing in the x and y
index as the GamePiece coordinates. After each token
increment the x counter. After each line increment y and
reset x.
PHASE IV - The GUI
====================================================================
In this phase we will code the View portion of our MVC design. There
are two classes: PacmanFrame and GameBoard which will extend JFrame
and JPanel, respectively. The GameBoard will be responsible for
drawing or painting the board according to the GamePiece array you
created in PacmanFileReader. Now it's time for our segway into
painting.
Let's talk a moment about paintComponent:
Every GUI component has a protected method called paintComponent that
is reponsible for making the GUI component look the way it does. The
unoverrided form draws the default appearance for the widget. For a
JPanel this is just huge blank gray area. For JButtons there is some
slight shadowing on the edges of the button. However, you can
override this method in a subclass of a GUI widget. In this overriden
method you can make the widget appear almost anyway you want. You can
draw lines, pictures, shapes, change the widget's color, etc.
The paintComponent() function receives a Graphics object that is
used to draw on the component which owns it (In this case a GameBoard).
It is important to know that you will NEVER call paintComponent directly;
if you would like to update your component, call repaint(). The swing
windowing environment will send the proper Graphics context to
paintComponent(). Familiarize yourself with all of the methods in the
Graphics component from the API so you can draw using your Graphics
object. The Graphics parameter can sort of be thought of as your
brush and the widget where paintComponent is overriden as your canvas.
An example of an overridden paintComponent function:
protected void paintComponent( Graphics g ) {
// I call the super paintComponent to draw the component the regular
//way first
super.paintComponent( g );
//set the Graphics object's current color to blue. This is sort of
like dipping your brush into blue paint
g.setColor(java.awt.Color.blue);
//draw a circle (actually an oval with equal width and height)
//100 pixels in diameter. The result will be an unfilled
//blue circle
g.drawOval( 0, 0, 100, 100 );
}// end of paintComponent( Graphics )
Let's talk a moment about images. Images in java are represented by a
variety of classes. The easiest way to use images is to use the
ImageIcon class. The constructor of this class takes in a String that
is the file name of a jpg, gif, etc. In order to draw images on a GUI
widget, we need to draw an instance of Image not ImageIcon. ImageIcon
provides a method called .getImage which returns an Image instance
representation of the image at the file name you passed in. The
Graphics instance also requires you have an ImageObserver as a
parameter to the drawImage method. ImageIcons come with another
method called .getImageObserver() which will fill this requirement.
Create a class called GameBoard that extends JPanel. This class should have the
following:
o a private GamePiece[][] variable named "pieceArray". This
array will model the board seen in the GUI.
o a constructor that takes in a file name of a board file. This
file name will be passed off to a PacmanFileReader.
o a method called from the constructor that initializes the
provided images of the four ghosts, the image of a ghost in run
away mode, and of pacman.
o a protected method called paintComponent that takes in a
Graphics instance and returns void. This method is fairly
complicated since it has to draw the entire Pacman board
including the Pacman image and the ghost images.
We will be drawing a series of rectangles on the widget. Each
rectangle will represent one value of pieceArray. WallPiece
instances will be drawn blue. FloorPiece instances black.
FloorPiece instances with regular nibbles will have small yellow
rectangles or circles in the center of the black rectangle and
instances with special nibbles will have larger orange
rectangles or circles in the center of the black rectangle.
Pacman and the ghosts will be drawn last over the top of the
board. So how exactly are we supposed to draw one blue or black
or orange rectangle at an exact location on the board. For this
we'll have to do a little arithmetic.
The number of rectangles drawn per row will be the same number of
elements in one dimension of piecesArray and the number of rows
drawn will be the same number in the other dimension of
piecesArray.
The width of one board rectangle will be the width of the whole
board divided by the number of elements in the X dimension of
pieceArray. The height of one board rectangle will be the
height of the whole board divided by the number of elements in
the Y dimension of pieceArray.
The method .fillRect(int, int, int, int) inside Graphics takes in
four parameters: xStart, yStart, width, height. the "pen" starts
at pixel xStart and yStart as the top left corner in the
rectangle and draws a rectangle width wide and height high. So
how do we get to the correct x and y start locations. Since each
board rectangle represents an array of GamePieces, we can draw
the correct GamePiece rectangle in the correct spot by setting
our x start pixel to be the x index of the array multiplied by
the width of one rectangle. Respectivley we can set our y start
pixel to be the y index of the array multiplied by the height of
one rectangle. See the figure on the P6 website under "Drawing a
Rectangle on GameBoard". Now we'll discuss what to do in
paintComponent:
- call super.paintComponent to draw the default widget
first.
- get the width and height of one rectangle
- iterate through pieceArray. If the piece we're at is a
WallPiece instance, draw a blue rectangle. If it's
a FloorPiece with no nibble, draw a black rectangle. If
it has a nibble, draw the nibble accordingly. You may
have to experiment with a centering the nibble in the
middle of the black rectangle. Here's a hint though:
you'll be dividing by two a lot.
- after drawing the GamePieces, draw the pacman image at his
current location.
- draw each of the ghosts at their current location. Don't
forget to draw the ghosts with the correct image. If they
are being chased you need to draw them appropriately.
NOTE: The x and y instance variables in Pacman and Ghost are
the index the GamePiece they reside on. In other words
thore values will always be between 0 and 14. The x and y
values when dealing with the Graphics object are pixels.
Keep this in mind.
Create a class called PacmanFrame which extends JFrame. This class
will contain a GameBoard and a menu. PacmanFrame should have the
following:
o an instance of GameBoard
o a JMenu with two JMenuItems:
- one that activates a new game: This should restart the
game no matter what the state of the current game.
- one that exits the program. This should stop the JVM just
as if we clicked on the X in the top right corner of the
frame.
o a default constructor which sets up the frame with a
BorderLayout, instantiates a new GameBoard and adds it to the
center. There is a constant in P6Constants called BOARD_FILE
containing the name of the file to tokenize into a GamePiece
array.
o We recommend you set the size of the frame to be about 520x520
o helper methods that set up the menus.
o We recommend you have this class be a listener for its own
JMenuItems. You will need to then have this class implement
ActionListener.
o The program should exit gracefully if either the quit menu is
chosen or the X in the top right is clicked.
PHASE V - PacmanEngine
====================================================================
The PacmanEngine class will be our controller in the MVC paradigm for
this project. It will likely be your single biggest class. For lack
of a better description, PacmanEngine will be the arbiter for the
game. It will process user control inputs, decide which movements by
pacman and the ghosts are legal, regulate the rate at which pacman and
the ghosts, move and determine whether a win or loss condition exists.
First let's talk about Swing Timers. The class javax.swing.Timer is a
class that can be set to fire ActionEvents at a specific
interval. (yes the same Events fired by JButtons and JMenuItems) We
will be using two Timers in PacmanEngine. One will regulate Ghost
movement. Every time the Ghost Timer fires, we want all the ghosts to
move one square. Where they move will be determined by the four
element array returned from Ghost's getMove method. A second timer
will regulate Pacman's movement. This timer will fire at a slightly
faster rate because we want Pacman to be able to outrun the ghosts.
Every time the Pacman Timer fires, we want Pacman to move one square
in the direction specified in Pacman's direction variable. You will
need to look at the API for specific methods to use.
Next let's talk about Key Listening. We've worked with ActionEvents
and ChangeEvents. Now you will use a third event/listener group that
listens for events from the keyboard. The game will be controlled by
six different keyboard keys. The four arrow keys will control
Pacman's direction. The 's' key will start the game (start Pacman and
the Ghosts moving) at the beginning of a game. The 'p' key will pause
and unpause the game. It's important to understand how Pacman will be
controlled. Pacman does not move only when a key is pressed. He
progresses in the direction specified by his direction variable at all
times. The arrow key pressed merely changes this direction variable.
There are exceptions to this. If pacman's direction takes him into a
wall, Pacman will halt and wait until an arrow key is pressed to give
him a new direction.
Now let's talk about JOptionPanes. The JOptionPane class provides
simple pre-packaged diaglog boxes. All you need is a JFrame instance
and the message you want to show the user. Here's how we will use one
for this project:
JOptionPane.showMessageDialog(<instance of JFrame>,
<String instance containing message
you want to show to the user>,
<String instance containing message
to be displayed in Dialog Box title bar>,
<int constant representing icon to be displayed in
dialog box along with message>);
This method call will pop up a small dialog box on top of your PacmanFrame.
Your instance of JFrame will be your PacmanFrame instance. Your message
and title should be something meaningful and relevant. You can use any icon
you want. Check out the API for a listing of icons and how to use them.
Included in your dialog box will be an "OK" JButton which will close the box
if pressed. This button is added and handled automatically by the method.
No effort on your part is needed to add or handle the event from the button.
Create a class called PacmanEngine that implements both ActionListener
and KeyListener. PacmanEngine should have the following:
o a javax.swing.Timer called GhostTimer. This variable will fire
an ActionEvent every P6Constants.GHOST_INTERVAL milliseonds
causing all the Ghosts to move one square
o a javax.swing.Timer called PacmanTimer. This variable will fire
an ActionEvent every P6Constants.PACMAN_INTERVAL milliseonds
causing Pacman to move one square.
o a GameBoard instance called board. This will be the GameBoard
instance used to draw the state of the board
o a PacmanFrame instance.
o a Ghost[] variable called ghosts. This array will hold the
four Ghosts in play.
o a Pacman variable called pacman. This will be the Pacman
instance in play.
o a constructor which takes in a PacmanFrame and a GameBoard and
sets the appropriate variables to these parameters. You will
also need to initialize both Timers. (but don't start them yet.)
Also set the Ghost array and the Pacman variable to those
variables initialized by PacmanFileReader.
o a method public void actionPerformed which takes in an
ActionEvent. This method will be called by both Timers at the
appropriate interval.
If this method was called by the PacmanTimer, it is Pacman's turn
to move. You do not need to worry about any keys pressed in this
method. Remember Pacman always moves in the direction specified
by his direction variable every time the Timer fires. Before
moving Pacman to the next square though, you need to first
determine that the move is legal (i.e., Pacman won't be moving on
top of a WallPiece or off the board) You have the GameBoard,
pacman's current x and y locations and his current direction.
From this information you can determine whether or not any given
move is legal. It is recommended that the functionality for
determining whether a given move is legal be abstracted to a
helper method since you will be using the same functionality for
the ghosts. If a given move is found to be legal, call Pacman's
move method (extended from MoveablePiece) passing in the
direction. Do not have PacmanEngine directly set the x and y
location variables.
If this method was called by the GhostTimer, you will need to
iterate through all four ghosts. At each ghost, call the getMove
method to retrieve each ghost's array of move choices. You
should then iterate through this array and move the ghost using the
first legal move you encounter. (Remember the zeroth index holds
the highest choice of movement for a particular ghost)
No matter which Timer called the method, you will need to
determine if the most recent move by either Pacman or the Ghosts
resulted in a state that should end the game. If all of the
FloorPieces are missing nibbles, the player has won the game.
You should display a notificatoin that the player has won using a
JOptionPane message dialog. (That's why we have an instance of
PacmanFrame which extends JFrame) If one of the Ghosts and
Pacman occupies the same square and that Ghost is not running
from Pacman, the player loses. Again display an appropriate
message dialog to the user. If a Ghost and Pacman occupies the
same square but that ghost is in fact running from Pacman, you
should reset that ghost. You also need to process any time
Pacman eats a nibble. If it's a regular simply remove that
nibble from the board by notifying that particular floor piece to
turn it's nibble boolean to false. If it's a special nibble, you
not only need to have the FloorPiece set it's special boolean to
false but you also need to iterate through all four ghosts and
have them go into run away mode. The ghosts should run from
Pacman and begin counting down their runAwayCount variables.
After processing all moves, if no end game condition exists, you
should call repaint() on the GameBoard instance. This will make
the GameBoard display the new locations of the ghosts.
o a method public void keyPressed which takes in a KeyEvent.
This method will be automatically called when any keyboard key is
pressed. There are only six we care about though. If the 's'
key is pressed, you should start both timers if they are not
already running. If the 'p' key is pressed, you should stop the
timers if they are running and start them if stopped. If one of
the four arrow keys is pressed, you should set Pacman's direction
variable to reflect the key pressed. You should only set the
variable, however, if the Timers are running. But how do we
figure out which key was pressed? The KeyEvent class has a
method called getKeyCode() which returns an int that represents a
key. Look through the KeyEvent API to figure out which constant
represents the appropriate keys.
PHASE VI - Testing and Turnin
====================================================================
Create a Driver class called "P6". This class should have a main
method which instantiates PacmanFrame.
Swing GUI components can sometimes throw exceptions without the
program crashing. i.e. you may see a stack trace on the
console but amazingly the program still appears to be
functioning. We consider this no different than if the program
crashed. You should not have any stack traces from exceptions
of any kind. You should catch and handle all exceptions.
This project, again, will require you to look through the API for many
solutions to a given task. Please make an honest effort to figure out
things for yourself before you seek outside help. This is the point
of the exercise.
Make sure you turn in the following files:
o GamePiece.java
o WallPiece.java
o FloorPiece.java
o MoveablePiece.java
o Ghost.java
o Pacman.java
o PacmanFileReader.java
o GameBoard.java
o PacmanFrame.java
o PacmanEngine.java
o P6.java
These may vary if you deviated from the suggested design.
PHASE VII - Extra Credit (Optional)
====================================================================
There will be a modest amount of extra credit given to those students
who go above and beyond the call of duty in the project. Make sure
you do not attempt any extra credit until you can certify that the
core requirements of the project have been satisfied.
Here are some ideas:
o In board #2, allow Pacman and/or the ghosts to go through the
hole on either the left or right side of the board and appear on
the opposite side. (i.e. wrapping around the board)
o Make pacman "chew" as he moves along the board. A second
pacman image with his mouth closed is provided
o Make pacman and the ghosts move smoothly from square to square
rather than abruptly appear in the next square.
o Create a smarter ghost movement algorithm that allows ghosts to
go around walls to get to pacman rather than just run up against
the wall.
o Develop a scoring system and display it somehow in PacmanFrame
o Put fruit on the board like in Ms. Pacman
o Use sound!
o Two player!
====================================================================

View File

@@ -0,0 +1,47 @@
/**
* <PRE>
* CBgLayer.java
*
* Revisions: 1.0 Nov. 24, 2002
* Created the CBgLayer class
*
* </PRE>
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.0, Nov. 24, 2002
*/
import javax.swing.*;
public class CBgLayer extends JPanel{
CEngine cEngine;
public CBgLayer(String fileName){
cEngine = new CEngine(fileName);
}
protected void paintComponent(Graphics g){
super.paintComponent(g);
int w = WIDTH / cEngine.cBgLayer.length;
int h = HEIGHT / cEngine.cBgLayer[0].length;
for(int x=0; x<cEngine.cBgLayer.length; x++){
for(int y=0; y<cEngine.cBgLayer[x].length; y++){
if(cEngine.cBgLayer[x][y].getZ() == 2){
fillrect(
}
/**
* Debugging main for class CBgLayer.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args) {
}// end of main(String[] args)
}// end of class CBgLayer

View File

@@ -0,0 +1,105 @@
/**
* <PRE>
* CCoord.java
*
* Revisions: 1.0 Nov. 23, 2002
* Created the CCoord class, scratched old code
* 1.1 Nov. 23, 2002
* Compiled, FInished, Commented
*
*
* </PRE>
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.1, Nov. 23, 2002
*/
/**
*This class will be used to store Coordinate values relative to the grid
*not the x,y coord relative to the resolution
*/
public class CCoord{
/**
*Stores the x coord
*/
protected int iX;
/**
*Stores the y coord
*/
protected int iY;
/**
*Stores the Height of the ground, ground level = 0
*/
protected int iZ;
////////////////
//Constructors//
////////////////
/**
*Default Constructor, sets values to 1,1,0
*/
public CCoord(){
this(1,1,0);
}
/**
*@param x, the x coord
*@param y, the y coord
*@param z, the z coord
*/
public CCoord(int iX, int iY, int iZ){
this.iX = iX;
this.iY = iY;
this.iZ = iZ;
}
///////////////////////////
//Accessors and Modifiers//
///////////////////////////
/**
*@return, the value of X
*/
public int getX(){
return iX;
}
/**
*@return, the value of Y
*/
public int getY(){
return iY;
}
/**
*@return, the value of Z
*/
public int getZ(){
return iZ;
}
/**
*@param x, the x coord
*@param y, the y coord
*@param z, the z coord
*/
public void setParams(int iX, int iY, int iZ){
this.iX = iX;
this.iY = iY;
this.iZ = iZ;
}
public void setParams(CCoord c){
this.iX = c.iX;
this.iY = c.iY;
this.iZ = c.iZ;
}
public String toString(){
return ("[X: "+iX+" Y: "+iY+" Z: "+iZ+"]");
}
}//end class::CCoord

View File

@@ -0,0 +1,58 @@
/**
* <PRE>
* CEngine.java
*
* Revisions: 1.0 Nov. 17, 2002
* Created the CEngine class
*
* </PRE>
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.0, Nov. 17, 2002
*/
public class CEngine {
public CGhost[] cGhost;
public CPacman[] cPacman;
public CTile[][] cBgGrid;
public CMonster[][] cSpriteLayer;
public CNode[][] cNodeLayer;
public CEngine(String fileName){
CFileReader cTemp= new CFileReader();
Object[] array = cTemp.readMap(fileName);
cBgGrid = (CTile[][])array[5];
CPacman Pacman = new CPacman((CCoord)array[0]);
CGhost Ghost1 = new CGhost((CCoord)array[1]);
CGhost Ghost2 = new CGhost((CCoord)array[2]);
CGhost Ghost3 = new CGhost((CCoord)array[3]);
CGhost Ghost4 = new CGhost((CCoord)array[4]);
cNodeLayer = (CNode[][])array[6];
cSpriteLayer = new CMonster[cBgGrid.length][cBgGrid[0].length];
cSpriteLayer[Pacman.getX()][Pacman.getY()] = Pacman;
cSpriteLayer[Ghost1.getX()][Ghost1.getY()] = Ghost1;
cSpriteLayer[Ghost2.getX()][Ghost2.getY()] = Ghost2;
cSpriteLayer[Ghost3.getX()][Ghost3.getY()] = Ghost3;
cSpriteLayer[Ghost4.getX()][Ghost4.getY()] = Ghost4;
}
/**
* Debugging main for class CEngine.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args) {
}// end of main(String[] args)
}// end of class CEngine

View File

@@ -0,0 +1,247 @@
/**
* <PRE>
* CFileReader.java
*
* Revisions: 1.0 Nov. 24, 2002
* Created the CFileReader class
*
* </PRE>
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.0, Nov. 24, 2002
*/
import java.io.*;
import java.util.*;
public class CFileReader implements Constants{
BufferedReader brReader;
/**
*@return an array with the first 4 slots holding pacman and the ghost
*start locations, slot 5 holding the Background grid, slot 6 holding the
*Node Grid
*/
public Object[] readMap(String mapFile){
Object[] array = new Object[6];
StringTokenizer st;
/////////////////////
//Read Start Points//
/////////////////////
try{
brReader = new BufferedReader(new FileReader(mapFile));
}catch(FileNotFoundException fnfe){
System.err.println("File Not Found Error - CFileReader");
System.exit(0);
}
for(int i=0; i<5; i++){
st = new StringTokenizer("b");
try{
st = new StringTokenizer(brReader.readLine());
}catch(IOException ioe){
System.err.println(ioe);
System.exit(0);
}
array[i] = new CCoord(Integer.parseInt(st.nextToken()),
Integer.parseInt(st.nextToken()),1);
}
/*End Read Start Points*/
/////////////////////////
String strTemp = "";
CTile[][] cBgGrid;
try{
strTemp = brReader.readLine();
}catch(IOException ioe){
System.err.println(ioe);
System.exit(0);
}
////////////////////////////////////////////////////
/*Check whether its standard file or enhanced grid*/
switch(strTemp.charAt(0)){
case 'w': case 'n': case 's': case 'f':
cBgGrid = new CTile[15][15];
break;
case '1':case '2':case '3':case '4': case '5': case '6': case '7':
case '8':case '9':case '0':
st = new StringTokenizer(strTemp);
cBgGrid = new CTile[Integer.parseInt(st.nextToken())]
[Integer.parseInt(st.nextToken())];
try{
strTemp = brReader.readLine();
}catch(IOException ioe){
System.err.println(ioe);
System.exit(0);
}
break;
default:
cBgGrid = new CTile[0][0];
break;
}
/*End Check file type*/
///////////////////////
///////////////
/*Read in map*/
st = new StringTokenizer("");
for(int i=0; i<cBgGrid.length; i++){
try{
if(i==0){
st = new StringTokenizer(strTemp);
}else{
st = new StringTokenizer(brReader.readLine());
}
}catch(IOException ioe){
System.err.println(ioe);
System.exit(0);
}
for(int z=0; z<cBgGrid[i].length; z++){
switch(st.nextToken().charAt(0))
{
case 'f':
cBgGrid[i][z] = new CTile(i,z,1);
break;
case 'n':
cBgGrid[i][z] = new CTile(i,z,1);
cBgGrid[i][z].setItems(true,false);
break;
case 's':
cBgGrid[i][z] = new CTile(i,z,1);
cBgGrid[i][z].setItems(false,true);
break;
default:
case 'w':
cBgGrid[i][z] = new CTile(i,z,2);
break;
}
}
}
/*End map read*/
////////////////
array[5] = cBgGrid;
//////////////
//Init Nodes//
//////////////
CNode[][] cNode= new CNode[cBgGrid.length][cBgGrid[0].length];
for(int i=0; i<cNode.length; i++){
for(int z=0; z<cNode[i].length; z++){
boolean up=false, down=false, left=false, right=false;
//check up
try{
up = cBgGrid[i-1][z].getZ()==1?true:false;
}
catch(IndexOutOfBoundsException iobe){
up = true;
}
catch(Exception e){
up = false;
}
//check down
try{
down = cBgGrid[i+1][z].getZ()==1?true:false;
}
catch(IndexOutOfBoundsException iobe){
down = true;
}
catch(Exception e){
down = false;
}
//check left
try{
left = cBgGrid[i][z-1].getZ()==1?true:false;
}
catch(IndexOutOfBoundsException iobe){
left = true;
}
catch(Exception e){
left = false;
}
//check right
try{
right = cBgGrid[i][z+1].getZ()==1?true:false;
}
catch(IndexOutOfBoundsException iobe){
right = true;
}
catch(Exception e){
right = false;
}
if(cBgGrid[i][z] != null && cBgGrid[i][z].getZ()==1){
cNode[i][z] = new CNode(up,down,left,right,i,z,1);
}
}
}
array[6] = cNode;
try{
brReader.close();
}catch(IOException ioe){
System.err.println(ioe);
System.exit(0);
}
return array;
}
public static void main(String args[]){
CFileReader bob = new CFileReader();
Object[] steve = bob.readMap("board_1.txt");
for(int i=0; i<5; i++){
System.out.println(steve[i]);
}
System.out.println();
CTile[][] crystal = (CTile[][])steve[5];
for(int i=0; i<crystal.length; i++){
for(int z=0; z<crystal.length; z++){
System.out.println(crystal[i][z]);
}
}
CNode[][] julia = (CNode[][])steve[6];
for(int i=0; i<julia.length; i++){
for(int z=0; z<julia.length; z++){
try{
if(julia[i][z] == null){}
else{
System.out.println(julia[i][z]);}
}
catch(Exception e){
//System.out.print("null");
}
}
System.out.println("/*NextLine*/");
}
}
}// end of class CFileReader

View File

@@ -0,0 +1,68 @@
/**
* <PRE>
* CGhost.java
*
* Revisions: 1.0 Nov. 23, 2002
* Created the CGhost class
*
* </PRE>
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.0, Nov. 23, 2002
*/
public class CGhost extends CMonster implements Constants{
private CCoord startLoc;
private CNode cLastNode;
private int iCurrDir;
private boolean bDazed;
public CGhost(CSprite image, CCoord startLoc){
oIntel = new CGhostAI();
imgSprite = image;
this.setParams(startLoc);
this.startLoc = startLoc;
}
public CGhost(CCoord startLoc){
this(new CSprite("Error",".gif",1),startLoc);
}
public int doMove(CCoord cPacPos){
return ((CGhostAI)oIntel).doMove(cLastNode,this,cPacPos);
}
public void setLastNode(CNode cLastNode){
this.cLastNode = cLastNode;
}
public void setDir(int dir){
iCurrDir = dir;
}
public int getDir(){
return iCurrDir;
}
public void setDaze(boolean b){
bDazed = b;
}
public boolean getDaze(){
return bDazed;
}
/**
* Debugging main for class CGhost.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args) {
}// end of main(String[] args)
}// end of class CGhost

View File

@@ -0,0 +1,66 @@
/**
* <PRE>
* CGhostAI.java
*
* Revisions: 1.0 Nov. 23, 2002
* Created the CGhostAI class
*
* </PRE>
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.0, Nov. 23, 2002
*/
import java.util.*;
public class CGhostAI extends CIntelligence implements Constants{
/**
*This GhostAI uses a more classicPacman-like AI system
*Considering the fact that pacman isn't Half-Life, we don't need
*to do any searches to find Pacman, Pacman will eventually run into
*the ghosts.
*
*Basically, if the Ghost "sees" Pacman, that is, Pacman is within the
*Ghost's Line of Sight, the ghost will increase his speed to equal Pacman's
*(in this case I'm setting the speeds to be 3,2,1: 3 = Pacman speed,
*2 = Ghost regular speed, 1 = Ghost zombied speed)
*and the Ghost will head in Pacman's direction at full speed until pacman
*hits a new node (a Pacman hit Node event occurs) where the new direction
*Pacman chooses will be sent back to the Ghost and the Ghost will return to
*moving at normal speed (which is slightly slower than pacman but much faster
*than the speed at which they move when zombied out.
*
*@param CNode, the Ghost's current node
*@param CGhost, the Ghost to be analyzed
*@param CCoord, pacmans coordinate
*/
public int doMove(CNode cLastNode, CGhost cGhost, CCoord cPacPos){
int wayToGo;
if(cGhost.getX() == cPacPos.getX()){
if(cGhost.getY() < cPacPos.getY()){
wayToGo = cLastNode.canMV_DN()?MV_DN:MV_SAMEDIR;
}
else{
wayToGo = cLastNode.canMV_UP()?MV_UP:MV_SAMEDIR;
}
}
else if(cGhost.getY() == cPacPos.getY()){
if(cGhost.getX() < cPacPos.getX()){
wayToGo = cLastNode.canMV_RIGHT()?MV_RIGHT:MV_SAMEDIR;
}
else{
wayToGo = cLastNode.canMV_LEFT()?MV_LEFT:MV_SAMEDIR;
}
}
else {
//if the ghost can't see pacman then
Random rando = new Random();
wayToGo = rando.nextInt(MV_SAMEDIR);
}
return wayToGo;
}//end doMove()
}// end of class CGhostAI

View File

@@ -0,0 +1,55 @@
/**
* <PRE>
* CGrid.java
*
* Revisions: 1.0 Nov. 17, 2002
* Created the CGrid class
*
* </PRE>
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.0, Nov. 17, 2002
*/
import java.io.*;
public class CGrid {
/**
*2D array to store the game data
*/
private CCoord[][] grid;
////////////////
//Constructors//
////////////////
public CGrid(int iLength, int iHeight){
grid = new CCoord[iLength][iHeight];
}
///////////
//Methods//
///////////
public CCoord get(int x, int y){
return grid[x][y];
}
public void set(int x, int y, CCoord c){
grid[x][y] = c;
}
/**
* Debugging main for class CGrid.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args) {
}// end of main(String[] args)
}// end of class CGrid

View File

@@ -0,0 +1,36 @@
/**
* <PRE>
* CIntelligence.java
*
* Revisions: 1.0 Nov. 13, 2002
* Created the CIntelligence class
* 1.1 Nov. 23, 3003
* Created, Compiled, Finished
*
* </PRE>
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.1, Nov. 23, 2002
*/
public abstract class CIntelligence implements Constants{
/**
*Holds who controls the Intelligence
*/
String type;
/**
*Default Constructor, set type to CPU
*/
public CIntelligence(){
type = "CPU";
}
/**
*@param, set type to this
*/
public CIntelligence(String type){
this.type = type;
}
}// end of class CIntelligence

View File

@@ -0,0 +1,27 @@
/**
* <PRE>
* Monster.java
*
* Revisions: 1.0 Nov. 13, 2002
* Created the Monster class
*
* </PRE>
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.0, Nov. 13, 2002
*/
public abstract class CMonster extends CCoord implements Constants{
/**
*Defines the Intelligence of the monster
*whether player controlled or CPU controlled
*/
protected CIntelligence oIntel;
/**
*Define image for monster
*/
protected CSprite imgSprite;
}// end of class Monster

105
CS1322/p6/MyWay2/CNode.java Normal file
View File

@@ -0,0 +1,105 @@
/**
* <PRE>
* CNode.java
*
* Revisions: 1.0 Nov. 17, 2002
* Created the CNode class
* 1.1 Nov. 17, 2002
* Added Primary code, Commented, Finished
*
* </PRE>
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.1, Nov. 17, 2002
*/
/**
*The Engine class (CEngine) can take in a board and turn it into a game map.
*The Engine class then creates another grid which will below the game map
* that holds the nodes for the Intelligence class (CIntelligence).
*The Node classes hold the data for where a ghost can move and are used to
* send ghosts after the player. If pacman is between Node A and Node B and
* a ghost finds itself in Node A, it will turn and head in the direction of
* Node B. These Intelligence specifics are handled in the
* CIntelligence->CIntelGhost class
*/
public class CNode extends CCoord{
/**
*Define where the ghost can move when at this node
*/
private boolean MV_LEFT;
private boolean MV_RIGHT;
private boolean MV_UP;
private boolean MV_DN;
//originally meant to genarilize code to allow increase height nodes
//but removed due to deadline constraints
//mmm, deadlines....mmmm
//private boolean INC_HEIGHT;
///////////////
//Constructor//
///////////////
/**
*@param up, can move up?
*@param down, can move down?
*@param left, can move left?
*@param right, can move right?
*@param x, x-coord
*@param y, y-coord
*@param h, h-coord
*/
public CNode(boolean up, boolean down, boolean left, boolean right,
/*boolean incH,*/ int x, int y, int h){
super(x,y,h);
MV_UP = up;
MV_DN = down;
MV_LEFT = left;
MV_RIGHT = right;
//INC_HEIGHT = incH;
}
///////////
//Methods//
///////////
/**
*@return true if can go up from node
*/
public boolean canMV_UP(){
return MV_UP;
}
/**
*@return true if can go down from node
*/
public boolean canMV_DN(){
return MV_DN;
}
/**
*@return true if can move left from node
*/
public boolean canMV_LEFT(){
return MV_LEFT;
}
/**
*@return true if can move right
*/
public boolean canMV_RIGHT(){
return MV_RIGHT;
}
/**
*@return Coordinates of the Node
*/
public CCoord getNodeCoord(){
return (new CCoord(this.getX(), this.getY(), this.getZ()));
}
public String toString(){
return (super.toString() + MV_UP+MV_DN+MV_LEFT+MV_RIGHT+"*/");
}
}// end of class CNode

View File

@@ -0,0 +1,35 @@
/**
* <PRE>
* CPacman.java
*
* Revisions: 1.0 Nov. 24, 2002
* Created the CPacman class
*
* </PRE>
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.0, Nov. 24, 2002
*/
public class CPacman extends CMonster implements Constants{
private CCoord currLocation;
public CPacman(CCoord startLoc){
this.iX = startLoc.getX();
this.iY = startLoc.getY();
this.iZ = startLoc.getZ();
}
/**
* Debugging main for class CPacman.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args) {
}// end of main(String[] args)
}// end of class CPacman

View File

@@ -0,0 +1,93 @@
/**
* <PRE>
* CSprite.java
*
* Revisions: 1.0 Nov. 23, 2002
* Created the CSprite class
*
* </PRE>
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.0, Nov. 23, 2002
*/
import javax.swing.*;
public class CSprite {
/**
*Holds image value(s)
*/
private ImageIcon[] imgSprite;
/**
*Holds the baseName for the Image Sprite
*(i.e. Imagename000.jpg, where 000 = animation number
*/
private String strImgName;
/**
*Holds value for time (in fps) for animation delay
*/
private int iAnimDelay;
////////////////
//Constructors//
////////////////
/**
*@param imgName, the base name for the image file
* ex:Street.jpg and Street000.jpg would both have imgName of Street
* use / to represent a different folder
*@param strExt, the extension for the file
* Acceptable types: .jpg, .gif, .bmp
*@param animCount, the number of animations
* Acceptable values: 1 or higher
*/
public CSprite(String imgName, String strExt, int animCount){
imgSprite = new ImageIcon[animCount];
this.strImgName = imgName+strExt;
for(int i=0; i<animCount; i++){
String strName;
if(i<10){
strName = imgName + "00" + i + strExt;
}
else if(i<100){//no need to recheck if i<10, already done that and
//skipped else{}
strName = imgName + "0" + i + strExt;
}
else{
strName = imgName + strExt;
}
try{
imgSprite[i] = new ImageIcon(imgName);
}
catch(Exception e){
imgSprite[i] = new ImageIcon("Error.gif");
}
}
}
public void setAnimDelay(int c){
iAnimDelay = c;
}
public int getAnimDelay(){
return iAnimDelay;
}
/**
* Debugging main for class CSprite.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args) {
}// end of main(String[] args)
}// end of class CSprite

125
CS1322/p6/MyWay2/CTile.java Normal file
View File

@@ -0,0 +1,125 @@
/**
* <PRE>
* Tile.java
*
* Revisions: 1.0 Nov. 12, 2002
* Created the Tile class
*
* </PRE>
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.0, Nov. 12, 2002
*/
import javax.swing.*;
/**
*CTile "is-a" Coordinate, however, it is used for both walls and floor
*using the height. The AI will be built specificaly for say level 1, which is
*the ground height of the floor and level 2, the walls, will be left out
*
*Addendum: CTile is pacman specific is not fully generalized, it also removes
* support for animated tiles such as water
*/
public class CTile extends CCoord{
/**
*Defines whether the object is coming from the ground up to a given level
*or whether it is a floating object (i.e. a bridge)
*NOT IMPLEMENTED IN PACMAN
*/
private boolean bIsFloating; //special note, this will NOT be implemented
//in standard Pacman, it is meant for future
//manipulation
/**
*Define whether block has a special nibble
*/
private boolean bHasSpecial;
/**
*Define whether block has a nibble
*/
private boolean bHasNibble;
/**
*Holds the tile picture data
*/
ImageIcon imgTile;
////////////////
//Constructors//
////////////////
/**
*@param x, the x-coord
*@param y, the y-coord
*@param z, the z-coord
*/
public CTile(int x, int y, int z){
this(x,y,z,false);
//imgTile = new ImageIcon(icon);
}
/**
*Same as other constructor but adds
*@param bIsFloating, defines whether the object is floating or not
*/
public CTile(int x, int y, int z, boolean bFloating){
super(x,y,z);
bIsFloating = bFloating;
bHasSpecial = false;
bHasNibble = false;
}
///////////////////////
//Accessors/Modifiers//
///////////////////////
/**
*@return true if object can be passed over
*/
public boolean isPassable(CCoord op){
if(op.getZ() == this.iZ){
return true;
}
return false;
}
public boolean isSpecial(){
return bHasSpecial;
}
public boolean isNibble(){
return bHasNibble;
}
public void setImage(String filename){
imgTile = new ImageIcon(filename);
}
/**
*@param nibble, whether or not it has a nibble
*@param special, whether or not it has a special
*/
public void setItems(boolean nibble, boolean special){
bHasNibble = nibble;
bHasSpecial = special;
}
/**
* Debugging main for class Tile.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args) {
}// end of main(String[] args)
}// end of class Tile

View File

@@ -0,0 +1,28 @@
/**
* <PRE>
* Constants.java
*
* Revisions: 1.0 Nov. 13, 2002
* Created the Constants class
*
* </PRE>
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.0, Nov. 13, 2002
*/
public interface Constants {
/*Directions*/
/**
*Define 4 movement constants: MV_UP, MV_DN, MV_LFT, MV_RGHT
*/
public static final int MV_UP = 0;
public static final int MV_DN = 1;
public static final int MV_LEFT = 2;
public static final int MV_RIGHT = 3;
public static final int MV_SAMEDIR= 4;
}// end of class Constants

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 B

View File

@@ -0,0 +1,20 @@
0 7
1 1
13 1
13 13
1 13
w w w w w w w w w w w w w w w
w s f n n n n w n n n n f s w
w f w w w w n w n w w w w f w
w n w n n n n w n n n n w n w
w n w n w w w w w w w n w n w
w n w n n n n n n n n n w n w
w n w n n n w w w n n n w n w
f n n n n n w f w n n n n n w
w n w n n n w w w n n n w n w
w n w n n n n n n n n n w n w
w n w n w w w w w w w n w n w
w n w n n n n w n n n n w n w
w f w w w w n w n w w w w f w
w s f n n n n w n n n n f s w
w w w w w w w w w w w w w w w

25
CS1322/p6/P6.java Normal file
View File

@@ -0,0 +1,25 @@
/**
* <PRE>
* P6.java
*
* Revisions: 1.0 Nov. 26, 2002
* Created the PacmanFileReader class
* 1.1 Nov. 26, 2002
* Compiled, Finished, Done
*
* </PRE>
*
* Collaboration statement:
* I worked on this assignment with Roland Krystian Alberciak
*
* @author
*<A HREF="mailto:gtg142g@mail.gatech.edu">Roland Krystian Alberciak</A>
*@author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.1, Nov. 25, 2002
*/
public class P6{
public static void main(String args[]){
PacmanFrame pf = new PacmanFrame();
}
}

View File

@@ -0,0 +1,86 @@
/**
* <PRE>
* P6Constants.java
*
* Revisions: 1.0 Aug. 25, 2002
* Created the P6Constants class
*
* </PRE>
*
* @author <A HREF="mailto:bsbeck@cc.gatech.edu">Brandon Beck</A>
* @version Version 1.0, Aug. 25, 2002
*/
public interface P6Constants {
//The color of Walls
public static final java.awt.Color WALL_COLOR = java.awt.Color.blue;
//The color of Floors
public static final java.awt.Color FLOOR_COLOR = java.awt.Color.black;
//The color of a regular nibble
public static final java.awt.Color NIBBLE_COLOR = java.awt.Color.yellow;
//The color of a special nibble
public static final java.awt.Color SPECIAL_COLOR = java.awt.Color.orange;
//The name of the file to parse to obtain the board
public static final String BOARD_FILE = "board_1.txt";
//The image file containing Pacman
public static final String PACMAN = "pacman.gif";
//The four image files containing each of the ghosts while chasing pacman
public static final String GHOST_1 = "gh1.gif";
public static final String GHOST_2 = "gh2.gif";
public static final String GHOST_3 = "gh3.gif";
public static final String GHOST_4 = "gh4.gif";
//The image file applied to all ghosts while running from pacman
public static final String GH_RUN_AWAY = "ghRA.gif";
//The constant representing a WallPiece in a board file
public static final String WALL = "w";
//The constant representing a FloorPiece no nibbles in a board file
public static final String FLOOR = "f";
//The constant indicating a FloorPiece with a special nibble in
//a board file
public static final String SPECIAL = "s";
//The constant indicating a FloorPiece with a regular nibble in
//a board file
public static final String NIBBLE = "n";
//The number of columns (or pieces in one row) on the board
public static final int BOARD_SIZE_X = 15;
//The number of rows (or pieces in one column) on the board
public static final int BOARD_SIZE_Y = 15;
//The constant representing "up"
public static final int NORTH = 0;
//The constant representing "right"
public static final int EAST = 1;
//The constant representing "down"
public static final int SOUTH = 2;
//The constant representing "left"
public static final int WEST = 3;
//The number of moves a Ghost makes while running from Pacman before it
//returns to the state of chasing Pacman
public static final int RUN_AWAY_DURATION = 20;
//The interval between firings of the PacmanTimer controlling Pacman movements
public static final int PACMAN_INTERVAL = 350;
//The interval between firings of the GhostTimer controlling all Ghost movements
public static final int GHOST_INTERVAL = 500;
}// end of interface P6Constants

77
CS1322/p6/Pacman.java Normal file
View File

@@ -0,0 +1,77 @@
/**
* <PRE>
* Pacman.java
*
* Revisions: 1.0 Nov. 12, 2002
* Created the Pacman class
* 1.1 Nov. 12, 2002
* Compiled, Completed, Done
*
* </PRE>
*
* Collaboration Statement:
* I worked on the homework assignment alone, using only
* course materials.
*
* Created with JCreatorLE, some indents are off when viewed through notepad
* or EMACS
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.1, Nov. 12, 2002
*/
public class Pacman extends MoveablePiece{
/**
*holds the direction Pacman be going
*/
private int direction;
///////////////
//Constructor//
///////////////
/**
*Constructor
*@param x, x coordinate
*@param y, y coordinate
*/
public Pacman(int x, int y){
super(x,y);
direction = 1;
}
/**
*@return a String
*/
public String toString(){
return (super.toString() + "Pacman]");
}
/**
*@param i, the new direction
*/
public void setDirection(int i){
this.direction = i;
}
/**
*@return the direction
*/
public int getDirection(){
return direction;
}
/**
* Debugging main for class Pacman.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args) {
}// end of main(String[] args)
}// end of class Pacman

BIN
CS1322/p6/PacmanDown000.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 B

303
CS1322/p6/PacmanEngine.java Normal file
View File

@@ -0,0 +1,303 @@
/**
* <PRE>
* PacmanEngine.java
*
* Revisions: 1.0 Nov. 25, 2002
* Created the PacmanEngine class
* 1.1 Nov. 26, 2002
* Compiled, Finished
* 1.2 Nov. 26, 2002
* Corrected Movement problem, AI still seems wacky, but can't
* find the problem
*
* </PRE>
*
* Collaboration statement:
* I worked on this assignment with Roland Krystian Alberciak
*
* @author
*<A HREF="mailto:gtg142g@mail.gatech.edu">Roland Krystian Alberciak</A>
*@author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.2, Nov. 26, 2002
*/
import javax.swing.*;
import javax.swing.event.*;
import java.awt.event.*;
public class PacmanEngine implements ActionListener, KeyListener{
/**
*Timers to fire every x.ms and do whatever
*/
private Timer GhostTimer;//fire at P6Constants.GHOST_INTERVAL ms
private Timer PacmanTimer;//fire at P6Constants.PACMAN_INTERVAL ms
/**
*globals to hold data for engine use
*/
private GameBoard board;
private PacmanFrame pf;
private Ghost[] ghosts;
private Pacman pacman;
/**
*Constructor
*@param pf, the PacmanFrame instance
*@param gb, the GameBoard instance
*/
public PacmanEngine(PacmanFrame pf, GameBoard gb){
board = gb;
this.pf = pf;
//gb = pf.getGB();
pf.addKeyListener(this);
//PacmanFileReader pfr = new PacmanFileReader(P6Constants.BOARD_FILE);
GhostTimer = new Timer(P6Constants.GHOST_INTERVAL,this);
PacmanTimer = new Timer(P6Constants.PACMAN_INTERVAL,this);
ghosts = board.getGhosts();
pacman = board.getPacman();
}
/**
*@param ae, the action performed
*Handles what ae asks for
*/
public void actionPerformed(ActionEvent ae){
if(ae.getSource() == PacmanTimer){
isLegalMove(pacman,pacman.getDirection());
}
else if(ae.getSource() == GhostTimer){
for(int i=0; i<4; i++){
int[] array = ghosts[i].getMove(pacman.getX(),pacman.getY());
boolean legal = false;
int z=0;
do{
legal = isLegalMove(ghosts[z],array[z]);
z++;
}while(!legal && z<4);
}//end for()
}//end else if()
GamePiece[][] temp = board.getPieceArray();
//check pacman eat nibble
if(temp[pacman.getX()][pacman.getY()] instanceof FloorPiece){
((FloorPiece)temp[pacman.getX()][pacman.getY()]).setNibble(false);
}
if(temp[pacman.getX()][pacman.getY()] instanceof FloorPiece){
if(((FloorPiece)temp[pacman.getX()][pacman.getY()]).getSpecial()){
((FloorPiece)temp[pacman.getX()][pacman.getY()]).setSpecial(false);
for(int i=0; i<4; i++){
ghosts[i].runAway();
}
}
}
//check for game over
boolean isDone = true;
for(int x=0; x<temp.length; x++){
for(int y=0; y<temp[x].length; y++){
if(temp[x][y] instanceof FloorPiece
&& ((FloorPiece)temp[x][y]).getNibble()){
isDone=false;
}
}
}
if(isDone){
GhostTimer.stop();
PacmanTimer.stop();
JOptionPane.showMessageDialog(pf,new String("You win!"),
new String("Congrats"),1);
}
//check ghost and pacman same box
for(int i=0; i<4; i++){
if(pacman.getX() == ghosts[i].getX()
&& pacman.getY() == ghosts[i].getY()){
if(ghosts[i].getRunAwayFlag()){
ghosts[i].resetGhost();
}
else{//game over time
GhostTimer.stop();
PacmanTimer.stop();
JOptionPane.showMessageDialog(pf,new String("You Lose!"),
new String("Game Over"),1);
}
}
}
board.repaint();
}//end actionPerformed()
/**
*check legality of a move and make the move
*@return true if the move is possible
*@param mp, the piece to check
*@param direction, the direction to move
*/
private boolean isLegalMove(MoveablePiece mp, int direction){
try{
switch(direction){
case P6Constants.NORTH:
if(board.getPieceArray()[mp.getX()][mp.getY()-1]
instanceof FloorPiece){
mp.move(P6Constants.NORTH);
return true;
}
break;
case P6Constants.SOUTH:
if(board.getPieceArray()[mp.getX()][mp.getY()+1]
instanceof FloorPiece){
mp.move(P6Constants.SOUTH);
return true;
}
break;
case P6Constants.EAST:
if(board.getPieceArray()[mp.getX()+1][mp.getY()]
instanceof FloorPiece){
mp.move(P6Constants.EAST);
return true;
}
break;
case P6Constants.WEST:
if(board.getPieceArray()[mp.getX()-1][mp.getY()]
instanceof FloorPiece){
mp.move(P6Constants.WEST);
return true;
}
break;
};//end switch()
return false;
}catch(ArrayIndexOutOfBoundsException aiobe){return false;}
catch(NullPointerException npe){return false;}
}
/**
*Java's Pathetic Handler class
*@param ke, the key pressed
*/
public void keyPressed(KeyEvent ke){
switch(ke.getKeyCode()){
case KeyEvent.VK_S:
PacmanTimer.start();
GhostTimer.start();
System.out.println("Pressed s");
break;
case KeyEvent.VK_P:
GhostTimer.stop();
PacmanTimer.stop();
System.out.println("Pressed p");
break;
case KeyEvent.VK_UP:
pacman.setDirection(P6Constants.NORTH);
System.out.println("Pressed up");
break;
case KeyEvent.VK_DOWN:
pacman.setDirection(P6Constants.SOUTH);
System.out.println("Pressed down");
break;
case KeyEvent.VK_LEFT:
pacman.setDirection(P6Constants.WEST);
System.out.println("Pressed left");
break;
case KeyEvent.VK_RIGHT:
pacman.setDirection(P6Constants.EAST);
System.out.println("Pressed right");
break;
}
}//end keyPressed
/**
*Added to satisfy the requirements of the KeyListener
*/
public void keyTyped(KeyEvent ke){
/*switch(ke.getKeyCode()){
case KeyEvent.VK_S:
PacmanTimer.start();
GhostTimer.start();
System.out.println("Pressed s");
break;
case KeyEvent.VK_P:
GhostTimer.stop();
PacmanTimer.stop();
System.out.println("Pressed p");
break;
case KeyEvent.VK_UP:
pacman.setDirection(P6Constants.NORTH);
System.out.println("Pressed up");
break;
case KeyEvent.VK_DOWN:
pacman.setDirection(P6Constants.SOUTH);
System.out.println("Pressed down");
break;
case KeyEvent.VK_LEFT:
pacman.setDirection(P6Constants.WEST);
System.out.println("Pressed left");
break;
case KeyEvent.VK_RIGHT:
pacman.setDirection(P6Constants.EAST);
System.out.println("Pressed right");
break;
}*/
}
/**
*Added to satisfy the requirements of the KeyListener
*/
public void keyReleased(KeyEvent ke){
/*switch(ke.getKeyCode()){
case KeyEvent.VK_S:
PacmanTimer.start();
GhostTimer.start();
System.out.println("Pressed s");
break;
case KeyEvent.VK_P:
GhostTimer.stop();
PacmanTimer.stop();
System.out.println("Pressed p");
break;
case KeyEvent.VK_UP:
pacman.setDirection(P6Constants.NORTH);
System.out.println("Pressed up");
break;
case KeyEvent.VK_DOWN:
pacman.setDirection(P6Constants.SOUTH);
System.out.println("Pressed down");
break;
case KeyEvent.VK_LEFT:
pacman.setDirection(P6Constants.WEST);
System.out.println("Pressed left");
break;
case KeyEvent.VK_RIGHT:
pacman.setDirection(P6Constants.EAST);
System.out.println("Pressed right");
break;
}*/
}
/**
* Debugging main for class PacmanEngine.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args) {
PacmanFrame fs = new PacmanFrame();
PacmanEngine pe =
//new PacmanEngine(new PacmanFrame(),new GameBoard("board_1.txt"));
new PacmanEngine(fs,fs.getGB());
}// end of main(String[] args)
}// end of class PacmanEngine

View File

@@ -0,0 +1,218 @@
/**
* <PRE>
* PacmanFileReader.java
*
* Revisions: 1.0 Nov. 24, 2002
* Created the PacmanFileReader class
* 1.1 Nov. 25, 2002
* Compiled, Finished, Done
*
* </PRE>
*
* Collaboration statement:
* I worked on this assignment with Roland Krystian Alberciak
*
* @author
*<A HREF="mailto:gtg142g@mail.gatech.edu">Roland Krystian Alberciak</A>
*@author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.1, Nov. 25, 2002
*/
import java.util.*;
import java.io.*;
public class PacmanFileReader {
private GamePiece[][] pieceArray;
private BufferedReader brReader;
/**
*Hold Pacman
*/
private Pacman cPacman;
/**
*Hold Ghosts
*/
private Ghost cGhost1;
private Ghost cGhost2;
private Ghost cGhost3;
private Ghost cGhost4;
/**
*Constructor
*@param inFile, the name of the file to read
*/
public PacmanFileReader(String inFile){
readMap(inFile);
}
/**
*Take in the file and create a grid
*@param mapFile, the file to be read
*/
private void readMap(String mapFile){
StringTokenizer st;
/////////////////////
//Read Start Points//
/////////////////////
try{
brReader = new BufferedReader(new FileReader(mapFile));
}catch(FileNotFoundException fnfe){
System.err.println("File Not Found Error - FileReader");
System.exit(0);
}
for(int i=0; i<5; i++){
st = new StringTokenizer("b");
try{
st = new StringTokenizer(brReader.readLine());
}catch(IOException ioe){
System.err.println(ioe);
System.exit(0);
}
switch(i){
case 0:
cPacman = new Pacman(Integer.parseInt(st.nextToken()),
Integer.parseInt(st.nextToken()));
break;
case 1:
cGhost1 = new Ghost(Integer.parseInt(st.nextToken()),
Integer.parseInt(st.nextToken()),1);
break;
case 2:
cGhost2 = new Ghost(Integer.parseInt(st.nextToken()),
Integer.parseInt(st.nextToken()),2);
break;
case 3:
cGhost3 = new Ghost(Integer.parseInt(st.nextToken()),
Integer.parseInt(st.nextToken()),3);
break;
case 4:
cGhost4 = new Ghost(Integer.parseInt(st.nextToken()),
Integer.parseInt(st.nextToken()),4);
break;
}
}
/*End Read Start Points*/
/////////////////////////
String strTemp = "";
pieceArray = new GamePiece[15][15];
//////////////
/*Read in map*/
st = new StringTokenizer("");
for(int i=0; i<pieceArray.length; i++){
try{
st = new StringTokenizer(brReader.readLine());
}catch(IOException ioe){
System.err.println(ioe);
System.exit(0);
}
for(int z=0; z<pieceArray[i].length; z++){
switch(st.nextToken().charAt(0))
{
case 'f':
pieceArray[z][i] = new FloorPiece(z,i,false,false);
break;
case 'n':
pieceArray[z][i] = new FloorPiece(z,i,true,false);
break;
case 's':
pieceArray[z][i] = new FloorPiece(z,i,false,true);
break;
default:
pieceArray[z][i] = new WallPiece(z,i);
break;
case 'w':
pieceArray[z][i] = new WallPiece(z,i);
break;
}
}
}
try{brReader.close();}catch(IOException ioe){}
}//end readMap()
/**
*@return pieceArray
*/
public GamePiece[][] getPieceArray(){
return pieceArray;
}
/**
*@return, pacman
*/
public Pacman getPacman(){
return cPacman;
}
/**
*@return ghost1
*/
public Ghost getGhost1(){
return cGhost1;
}
/**
*@return ghost2
*/
public Ghost getGhost2(){
return cGhost2;
}
/**
*@return ghost3
*/
public Ghost getGhost3(){
return cGhost3;
}
/**
*@return ghost4
*/
public Ghost getGhost4(){
return cGhost4;
}
/**
*@return ghosts[]
*/
public Ghost[] getGhosts(){
return (new Ghost[] {cGhost1,cGhost2,cGhost3,cGhost4});
}
/**
* Debugging main for class PacmanFileReader.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args) {
PacmanFileReader pmfr = new PacmanFileReader("board_1.txt");
for(int i=0; i<15; i++){
for(int z=0; z<15; z++){
System.out.println(pmfr.pieceArray[i][z]);
}
System.out.println("/*Next line*/");
}
}// end of main(String[] args)
}// end of class PacmanFileReader

131
CS1322/p6/PacmanFrame.java Normal file
View File

@@ -0,0 +1,131 @@
/**
* CS1322: Programming Assignment #6 - Fall 2002
*
* <PRE>
* IDBox for: PacmanFrame.java
*
* Revisions: 1.0 Nov. 24, 2002
* Created the PacmanFrame class
* 1.1 Nov. 26, 2002
* Compiled, Finished, Done
*
* </PRE>
*
* Collaboration statement:
* I worked on this assignment with Roland Krystian Alberciak
*
* @author
*<A HREF="mailto:gtg142g@mail.gatech.edu">Roland Krystian Alberciak</A>
*@author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
*@version Version 1.1, Nov. 24, 2002
*/
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
public class PacmanFrame extends JFrame implements ActionListener{
/**
*Stores the gameboard
*/
private GameBoard cGameBoard;
/**
*Variables to hold GUI sh...stuff
*/
private JMenu cGameMenu;
private JMenuItem jNewGame;
private JMenuItem jExitGame; //why the heck would you want to do that!!
private JMenuBar jMenuBar;
/**
*holds the Pacman Engine
*/
private PacmanEngine pacEngine;
////////////////
//Constructors//
////////////////
/**
*PacmanFrame Default Constructor
*Basically sets up the game
*/
public PacmanFrame(){
super("Pacman: the Cheap Way");
super.getContentPane().setLayout(new BorderLayout());
this.cGameBoard = new GameBoard(P6Constants.BOARD_FILE);
super.getContentPane().add(cGameBoard,BorderLayout.CENTER);
this.initGUI();
setSize(520,520);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
super.show();
pacEngine = new PacmanEngine(this,cGameBoard);
//pacEngine.addKeyListener(this);
}
/**
*Initialize GUI
*/
private void initGUI(){
jNewGame = new JMenuItem("New Game");
jExitGame = new JMenuItem("Close");
jMenuBar = new JMenuBar();
cGameMenu = new JMenu("File");
cGameMenu.add(jNewGame);
cGameMenu.add(jExitGame);
jMenuBar.add(cGameMenu);
super.setJMenuBar(jMenuBar);
jNewGame.addActionListener(this);
jExitGame.addActionListener(this);
cGameMenu.addActionListener(this);
}
///////////
//Methods//
///////////
/**
*Action Method
*/
public void actionPerformed(ActionEvent ae){
if(ae.getSource() instanceof JMenuItem){
if(ae.getActionCommand().equals("New Game")){
System.out.println("Restarting Game...");
setVisible(false);
this.dispose();
new PacmanFrame();
}
else if(ae.getActionCommand().equals("Close")){
System.out.println("User Command: Exit...@##&%($");
System.exit(1);
}
}
}//end actionPerformed
/**
*@return the GameBoard
*/
public GameBoard getGB(){
return cGameBoard;
}
public static void main(String args[]){
PacmanFrame pf = new PacmanFrame();
}//end main()
} //end of class PacmanFrame

BIN
CS1322/p6/PacmanLeft000.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

BIN
CS1322/p6/PacmanUp000.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

11
CS1322/p6/README.txt Normal file
View File

@@ -0,0 +1,11 @@
Hey Bill,
I was going to do the code my way but due to time constraints I couldn't :(
Anyways, I did it using the boring way and it works fully and for the first time
I collaborated with a friend. Anyways, you should be able to tell who did the coding on
what since we code so diferently. I did the code for the first parts but everything after phase3
was collaborated.
Also, I stuck in the work I did but couldn't finish in myCode.zip.
Happy Thanksgiving,
Jose

46
CS1322/p6/WallPiece.java Normal file
View File

@@ -0,0 +1,46 @@
/**
* <PRE>
* WallPiece.java
*
* Revisions: 1.0 Nov. 11, 2002
* Created the WallPiece class
* 1.1 Nov. 11, 2002
* Compiled, Commented, Finished
*
* </PRE>
*
* Collaboration Statement:
* I worked on the homework assignment alone, using only
* course materials.
*
* Created with JCreatorLE, some indents are off when viewed through notepad
* or EMACS
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Manuel Caban</A>
* @version Version 1.1, Nov. 11, 2002
*/
public class WallPiece extends GamePiece{
public WallPiece(int x, int y){
super(x,y);
}
public String toString(){
return (super.toString() + "Wall Piece]");
}
/***************************************************/
/**
* Debugging main for class WallPiece.
* This method will rigorously test my code.
*
* <br><br>
* @param args a String array of command line arguments.
*/
public static void main(String[] args) {
}// end of main(String[] args)
}// end of class WallPiece

20
CS1322/p6/board_1.txt Normal file
View File

@@ -0,0 +1,20 @@
0 7
1 1
13 1
13 13
1 13
w w w w w w w w w w w w w w w
w s f n n n n w n n n n f s w
w f w w w w n w n w w w w f w
w n w n n n n w n n n n w n w
w n w n w w w w w w w n w n w
w n w n n n n n n n n n w n w
w n w n n n w w w n n n w n w
f n n n n n w f w n n n n n w
w n w n n n w w w n n n w n w
w n w n n n n n n n n n w n w
w n w n w w w w w w w n w n w
w n w n n n n w n n n n w n w
w f w w w w n w n w w w w f w
w s f n n n n w n n n n f s w
w w w w w w w w w w w w w w w

20
CS1322/p6/board_2.txt Normal file
View File

@@ -0,0 +1,20 @@
0 7
1 1
13 1
13 13
1 13
w w w w w w w w w w w w w w w
w s f n n n n n n n n n f s w
w f w w w w w n w w w w w f w
w n w f f f w n w f f f w n w
w n w w w w w n w w w w w n w
w n w n n n n n n n n n w n w
w n w n w n w w w n w n w n w
f n n n n n w f w n n n n n f
w n w n w n w w w n w n w n w
w n w n n n n n n n n n w n w
w n w w w w w n w w w w w n w
w n w f f f w n w f f f w n w
w f w w w w w n w w w w w f w
w s f n n n n n n n n n f s w
w w w w w w w w w w w w w w w

BIN
CS1322/p6/cs1322-P6.zip Normal file

Binary file not shown.

BIN
CS1322/p6/cs1322-P6ex.zip Normal file

Binary file not shown.

BIN
CS1322/p6/gh1.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

BIN
CS1322/p6/gh2.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 B

BIN
CS1322/p6/gh3.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 B

BIN
CS1322/p6/gh4.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

BIN
CS1322/p6/ghRA.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 B

BIN
CS1322/p6/myCode.zip Normal file

Binary file not shown.

800
CS1322/p6/p6.nfo.txt Normal file
View File

@@ -0,0 +1,800 @@
CS1322: Programming Assignment #6 - Fall 2002.
Assigned: November 11, 2002
Phase I Instant Feedback Due Date: November 21, 2002 11:59:59
Phase II Instant Feedback Due Date: November 25, 2002 11:59:59
DUE Date: November 25, 2002 11:59:59 PM
Program Title: Pacman
Files Provided
====================================================================
o P6.nfo.txt - this file
o board_1.txt - an input file that specifies board #1
o board_2.txt - an input file that specifies board #2
o GhostAI.class - a class that makes decisions on Ghost movement
o P6Constants.java - Interface needed for P6
(You must use these constants when appropriate)
o various image files
Learning Objectives
====================================================================
o Advanced DataStructures
o Advanced GUIs
Other Resources
====================================================================
Website containing screenshots and nfo file with pictures at
http://128.61.63.158/cs1322/P6
PROGRAM OVERVIEW
====================================================================
Welcome to the 6th and final programming assignemnt! A word of
caution: This project will be the most difficult one in this course.
You will be required to utilize all that you have learned in order to
complete this assignment. START EARLY!
This assignment will be very similar to the arcade classic - Pacman.
For those of you who aren't familiar with the game, Pacman is a little
yellow smiley face controlled by you, the user. The goal is to have
Pacman eat all the nibbles (dots on the board). If Pacman completes
this objective, you win the game. However, there are 4 ghosts
pursuing Pacman. If one of the ghosts catches him, the game is over.
Pacman has one defense however: the special nibbles placed on the
board. If Pacman eats a special nibble, the ghosts can be eaten by
Pacman for a time. During this period, the ghosts run away from
Pacman. If a ghost is eaten, it returns to its start location on the
board and resumes it's role of pursing and attempting to catch Pacman
even if the others are still running from Pacman. After a time, all
the ghosts return to the original state of pursuing Pacman.
HEY! guess what! START EARLY!
A Word About Imlementation and Grading
====================================================================
In the past five assignments, the TAs and nfo files have largely
specified exactly which methods, parameters, classes and fields you
would need to complete the assignment. This assignment will be
different. While we will supply a recommended design, the exact means
of implementation in terms of which methods or fields you use is left
ambiguous. With the exception of the Instant Feedback phases, you
will be largely responsible for figuring out which methods you wish to
create to solve a given problem. This assignment will be graded more
in terms of functionality i.e. "does this feature function correctly?"
rather than "is this method present with these exact parameters".
With this in mind, you can feel free to create whatever methods you
wish to solve the problem. In addition, those of you looking for a
challenge or wanting to fight "the man" can feel free to deviate as
much or as little as you want from the design below. (Again, with the
exception of the Instant Feedback phases. You must do what we tell
you there.) Keep in mind, however, that as you deviate from the
recommended design, it becomes difficult to give partial credit if
things don't work correctly. So if you do choose to go your own way,
do so at your own risk. If you are not yet comfortable leaving the
nest, the design below is provided.
<cough>Start Early!
Overall Design
====================================================================
In the MVC (Model, View, Controller) paradigm of GUI programming, we
separate parts of the program into three pieces:
The Model - This class or group of classes stores the state of the
data in the program. It is often a data structure such as a BST or
Heap. The model typically is independent of any GUI widgets. This
allows our program to be more portable. If we wanted to use our
data in some interface other than a GUI, say a text console
interface, there would be little to no recoding of the model.
The View - This gruop of classes is responsible for displaying the
GUI. Often they extend or hold GUI widget instances. We don't
want the view to hold the state of any data. This is the role of
the model.
The Controller - This class or group of classes is responsible for
manipulating the model according to the needs of the program.
Often is the listener of events from GUI widgets (as EventHandler
was in P5)
The UIDelegate paradigm of GUI programming is very similar to MVC.
The only difference is that in UIDelegate we combine the roles of View
and Controller into one class or group of classes.
Now an overview of the classes of Pacman:
Model - GamePiece, WallPiece, FloorPiece, MoveablePiece, Ghost, Pacman
View - GameBoard, PacmanFrame
Controller - PacmanFileReader, PacmanEngine, PacmanFrame
Notice PacmanFrame is both a View and a Controller. This means it
will be a UIDelegate class.
PHASE I - The Pieces - Instant Feedback
====================================================================
The classes in this phase will be model classes that represent the
tiles and pieces on the board. They will be independent of any GUI
widgets. They merely will hold information about the piece such as
where it is on the board.
Create a class called GamePiece. This class will be an abstract super
class to all pieces of the game board. GamePiece should include the
following:
o a protected int called "x". This variable will represent which
column the piece is in. i.e., it's location along the x-axis.
o a protected int called "y". This variable will represent which
row the piece is in. i.e., it's location along the y-axis.
Together these two variables represent the exact location of the
board this particular piece is in. The location 0,0 will be the
upper left hand corner of the game board.
o public accessors for both of the above variables.
o a public method called setPostition that takes in two
parameters: x followed by y and sets the location variables to
these parameters.
o a constructor that takes in two parameters: x followed by y and
sets the location variables to these parameters.
Create a class called FloorPiece. This class will extend GamePiece.
It will also add the functionality of nibbles (The dots that Pacman
eats) Each FloorPiece can have a regular nibble, a special nibble
(one that allows Pacman to chase the ghosts), or neither (but not
both). FloorPiece should have the following:
o a private boolean variable called "hasNibble". This variable
will represent whether or not this FloorPiece has a nibble that
Pacman eats (the regular ones, not the ones that lets Pacman
chase Ghosts)
o a private boolean variable called "hasSpecial". This variable
will represent whether or not this FloorPiece has a special
nibble that allows Pacman to chase Ghosts.
o accessors and modifiers for both of the above
o a constructor that takes in four parameters: the x and y
location and two booleans representing whether or not this FloorPiece
should have a nibble or a special. This constructor should chain
to the super constructor and set hasNibble and hasSpecial
according to the parameters.
Create a class called WallPiece. This class will extend GamePiece.
It will also add the functionality of a wall on the game board.
Neither ghosts nor Pacman can travel on or through walls. They can
only travel on FloorPieces. Your WallPiece class should have the
following:
o a constructor that takes in two parameters: the x and y
locations of this piece. This constructor should chain to the
super constructor.
Create a class called MoveablePiece. This class will be abstract and
extend GamePiece. This class will be the super class of both Ghost
and Pacman. MoveablePiece should have the following:
o a constructor that takes in two ints: the x and y location of
this piece. This constructor should chain to the
super constructor.
o a public method named "move" that returns void and takes in an
int representing a direction. This parameter will be either
NORTH, EAST, SOUTH, or WEST from P6Constants. This constants
will represent up, right, down and left respectively. In this
method you should "move" the piece. This means modify the
piece's x or y location accordingly. Don't forget that (0,0) is
the top left corner of the board.
PHASE II - Ghosts and Pacman - Instant Feedback
====================================================================
These two classes will be model classes for Pacman and an individual ghost.
Create a class called Pacman which extends MoveablePiece. This class
will model the Pacman piece which the user will control. Pacman
should include the following:
o a private int variable named "direction". This variable will
contain one of the four constants from P6Constants: NORTH, EAST,
SOUTH, WEST. This variable will represent the direction Pacman
is currently heading on the board. This variable will be
initialized to EAST.
o a constructor that takes in two ints: the x and y location of
this piece. This constructor should chain to the
super constructor.
Now the Ghosts...
Before we get into the details of implementing Ghost, let's talk
about how the Ghost will chase (or run from) Pacman.
Provided to you is a class called GhostAI. This class has a single
static method:
public static int[] getGhostMove(int ghostX, int ghostY,
int pacmanX, int pacmanY)
Here's what the parameters do
o ghostX: the x location of a ghost
o ghostY: the y location of a ghost
o pacmanX: the x location of Pacman
o pacmanY: the y location of Pacman
The return value will always be an int array of size four. The array
contains each of the four directions from P6Constants in the order of
priority. So:
o index 0: the ghost's first choice of directions to move
o index 1: the ghost's second choice of directions to move
o index 2: the ghost's third choice of directions to move
o index 3: the ghost's fourth (last) choice of directions to
move
So why bother with all this priority stuff? Why not just return the
direction the ghost wants to move. Well what if we have a case like
the following:
Ghost
Wall Wall Wall Wall Wall
Pacman
The ghost's first choice of movement will be SOUTH toward Pacman. But
that's not an option because of the wall. We don't want our Ghosts to
just sit if they can't go somewhere. So we would try our second
choice, which in this case would be either EAST or WEST. The last
choice, in index 3, would be NORTH away from Pacman. Consider the
following case:
Wall Wall
Wall Wall
Wall Ghost Wall
Wall Wall Wall
Pacman
In this case, none of the first three choices will contain viable
moves. So the ghost's only choice is to go up. If this happens,
there will be a gap between the Ghost and the bottom wall. On the
next turn the Ghost can indeed use its first choice and move SOUTH
(Given that Pacman isn't going anywhere for some reason) If Pacman
were to stay put, the Ghost would end up oscillating back and forth
against the bottom wall. What happens if the Ghost is running from
Pacman after Pacman ate a special nibble. The priorities are just
reversed. Logically this makes sense. If a ghost's first priority
was to move SOUTH towards Pacman while chasing Pacman, SOUTH will be
the last priority when Pacman is chasing the ghost. Unfortunately,
the Ghost artificial intelligence algorithm we provide is somewhat
primitive. Consider the following case:
Wall Wall Wall Wall Wall Wall
Wall
Pacman Wall Ghost
Wall Wall Wall
If Pacman were to never move, the Ghost would simply run up against
the West wall over and over. If the Ghost were smart, it would go
around the South wall to get to Pacman but it doesn't. You must use
the Ghost movement algorithm we provide for instant feedback.
However, for the final turn in, you can develop your own, better
movement algorithm if you wish. (Just make sure it works) This would
be worth some juicy extra credit.
Create a class called Ghost that extends MoveablePiece. This class
will represent a Ghost. There will be four instances in your program,
one for each of the four ghosts. Ghost should have the following:
o a private int variable called "ghostNum". This will be the
number of the ghost.
o a private boolean variable called "runAwayFlag". This will be
true if this Ghost is running from Pacman and false if chasing
Pacman.
o a private int variable called "runAwayCount". This will
contain the number of returns remaining for this ghost to run
from Pacman. (Remember that a ghost will run from Pacman for a
fixed number of moves if Pacman eats a special nibble)
o a private int variable called "startX". This will contain the
starting x coordinate for this ghost.
o a private int variable called "startY". This will contain the
starting y coordinate for this ghost.
The startX and startY variables together represent the start
coordinates for the Ghost. The ghost will begin the game at this
location. The ghost will also return to this location if eaten
by pacman when running from him.
o accessors for ghostNum, runAwayFlag, startX and startY
o a public void method named "runAway" which takes in no parameters.
This sets runAwayFlag to true and initializes runAwayCount to
RUN_AWAY_DURATION from P6Constants
o a public void method called "resetGhost" which takes in no
parameters. This method will be invoked if this ghost is eaten
by Pacman. It should turn runAwayFlag to false and return the
ghost to it's start coordinates.
o a public method named "getMove" that returns an int[] and takes
in two parameters: pacman's x and y location. This method will
calculate the array of size four containing this ghost's choices
of movement as described above. Feel free to use the GhostAI
class. Keep in mind however that the getGhostMove method
provided assumes the ghost is chasing pacman. You will need to
modify the array to have the ghost run away from Pacman if this
is the case. If the Ghost is indeed running from Pacman, be sure
to deduct a turn from runAwayCount and check to see if
runAwayCount is zero, in which case you should have the ghost no
longer run from Pacman. This method will not actually set the
location of the ghost based on the GhostAI method. It simply
returns the array of choices. We do this because this ghost has
no clue whether any of its choices will take it into a wall. A
class later in the project will process the choices and decide
which moves are legal for this ghost. The ghost will then be
told which way to move.
o a public constructor that takes in three parameters: an x and y
start location and a ghostNum representing this ghost's number.
You should set the instance variable accordingly.
PHASE III - PacmanFileReader
====================================================================
From this point, you can feel free to ignore the design and do your
own thing if you wish provided you supply all the functionality of the
design we recommend. Remember the warning about grading though.
Even if you choose to use your own design, your program must still
present equivalent capabilities. And if your program doesn't work and
you used a different design, there is less chance of getting partial
credit.
Also realize that from this point there will be less explicit
information on what methods you need or how to implement them. There
are a variety of implementations that fit the suggested design. You
can choose one that suits you. You do not need to ask if you can
create a particular method or field. If it seems like you need method
x to perform some task, by all means, do it.
Onward...
Create a class called PacmanFileReader. This class will be
responsible for reading in a board file like one of the two we
provided you and translating it into an array of GamePiece instances.
If you open up one of the board files, you'll notice several rows of
seemingly random characters. Let's discuss the tokens found in
board_1.txt:
w <==> P6Constants.WALL <==> an instance of WallPiece
f <==> P6Constants.FLOOR <==> an instance of FloorPiece w/out either
kind of nibbles
n <==> P6Constants.NIBBLE <==> an instance of FloorPiece with a
regular nibble
s <==> P6Constants.SPECIAL <==> an instance of FloorPiece with a
special nibble
The first five rows specify the starting locations of Pacman and the
ghosts.
0 7 <-- Pacman's x,y start coordinates
1 1 <-- Ghost #1's startX and startY instance variable values.
13 1 <-- Ghost #2's startX and startY instance variable values.
13 13 <-- Ghost #3's startX and startY instance variable values.
1 13 <-- Ghost #4's startX and startY instance variable values.
The next rows will contain the four tokens discussed above. There
will always be 15x15 tokens. Look at the picture on the project
website under "using board_1.txt". Can you see the relationship
between the text file and the appearance of the board?
In this class, the goal is to translate these tokens into an array of
GamePieces. We recommend your PacmanFileReader have the following:
o a private GamePiece[][] variable named "pieceArray". This
array will model the board seen in the GUI.
o a BufferedReader to read the board file
o instance variables for pacman and four ghosts
o a constructor that takes in the name of a file to read.
o a helper method or series of helper methods called by the
consturctor that does the following:
- instantiates a BufferedReader to read the board file
passed into the constructor
- Reads each of the first five lines of the board file, uses
a StringTokenizer to get the x and y start coordinates and
instantiates Pacman or each of the four Ghosts (depending on
which line you're on)
- for the rest of the fifteen lines: Keep two counters, one
for the x index of the board and one for the y index.
Read in a line and use a StringTokenizer to get each
token. Instantiate each cell of pieceArray to the
appropriate GamePiece subclass passing in the x and y
index as the GamePiece coordinates. After each token
increment the x counter. After each line increment y and
reset x.
PHASE IV - The GUI
====================================================================
In this phase we will code the View portion of our MVC design. There
are two classes: PacmanFrame and GameBoard which will extend JFrame
and JPanel, respectively. The GameBoard will be responsible for
drawing or painting the board according to the GamePiece array you
created in PacmanFileReader. Now it's time for our segway into
painting.
Let's talk a moment about paintComponent:
Every GUI component has a protected method called paintComponent that
is reponsible for making the GUI component look the way it does. The
unoverrided form draws the default appearance for the widget. For a
JPanel this is just huge blank gray area. For JButtons there is some
slight shadowing on the edges of the button. However, you can
override this method in a subclass of a GUI widget. In this overriden
method you can make the widget appear almost anyway you want. You can
draw lines, pictures, shapes, change the widget's color, etc.
The paintComponent() function receives a Graphics object that is
used to draw on the component which owns it (In this case a GameBoard).
It is important to know that you will NEVER call paintComponent directly;
if you would like to update your component, call repaint(). The swing
windowing environment will send the proper Graphics context to
paintComponent(). Familiarize yourself with all of the methods in the
Graphics component from the API so you can draw using your Graphics
object. The Graphics parameter can sort of be thought of as your
brush and the widget where paintComponent is overriden as your canvas.
An example of an overridden paintComponent function:
protected void paintComponent( Graphics g ) {
// I call the super paintComponent to draw the component the regular
//way first
super.paintComponent( g );
//set the Graphics object's current color to blue. This is sort of
like dipping your brush into blue paint
g.setColor(java.awt.Color.blue);
//draw a circle (actually an oval with equal width and height)
//100 pixels in diameter. The result will be an unfilled
//blue circle
g.drawOval( 0, 0, 100, 100 );
}// end of paintComponent( Graphics )
Let's talk a moment about images. Images in java are represented by a
variety of classes. The easiest way to use images is to use the
ImageIcon class. The constructor of this class takes in a String that
is the file name of a jpg, gif, etc. In order to draw images on a GUI
widget, we need to draw an instance of Image not ImageIcon. ImageIcon
provides a method called .getImage which returns an Image instance
representation of the image at the file name you passed in. The
Graphics instance also requires you have an ImageObserver as a
parameter to the drawImage method. ImageIcons come with another
method called .getImageObserver() which will fill this requirement.
Create a class called GameBoard that extends JPanel. This class should have the
following:
o a private GamePiece[][] variable named "pieceArray". This
array will model the board seen in the GUI.
o a constructor that takes in a file name of a board file. This
file name will be passed off to a PacmanFileReader.
o a method called from the constructor that initializes the
provided images of the four ghosts, the image of a ghost in run
away mode, and of pacman.
o a protected method called paintComponent that takes in a
Graphics instance and returns void. This method is fairly
complicated since it has to draw the entire Pacman board
including the Pacman image and the ghost images.
We will be drawing a series of rectangles on the widget. Each
rectangle will represent one value of pieceArray. WallPiece
instances will be drawn blue. FloorPiece instances black.
FloorPiece instances with regular nibbles will have small yellow
rectangles or circles in the center of the black rectangle and
instances with special nibbles will have larger orange
rectangles or circles in the center of the black rectangle.
Pacman and the ghosts will be drawn last over the top of the
board. So how exactly are we supposed to draw one blue or black
or orange rectangle at an exact location on the board. For this
we'll have to do a little arithmetic.
The number of rectangles drawn per row will be the same number of
elements in one dimension of piecesArray and the number of rows
drawn will be the same number in the other dimension of
piecesArray.
The width of one board rectangle will be the width of the whole
board divided by the number of elements in the X dimension of
pieceArray. The height of one board rectangle will be the
height of the whole board divided by the number of elements in
the Y dimension of pieceArray.
The method .fillRect(int, int, int, int) inside Graphics takes in
four parameters: xStart, yStart, width, height. the "pen" starts
at pixel xStart and yStart as the top left corner in the
rectangle and draws a rectangle width wide and height high. So
how do we get to the correct x and y start locations. Since each
board rectangle represents an array of GamePieces, we can draw
the correct GamePiece rectangle in the correct spot by setting
our x start pixel to be the x index of the array multiplied by
the width of one rectangle. Respectivley we can set our y start
pixel to be the y index of the array multiplied by the height of
one rectangle. See the figure on the P6 website under "Drawing a
Rectangle on GameBoard". Now we'll discuss what to do in
paintComponent:
- call super.paintComponent to draw the default widget
first.
- get the width and height of one rectangle
- iterate through pieceArray. If the piece we're at is a
WallPiece instance, draw a blue rectangle. If it's
a FloorPiece with no nibble, draw a black rectangle. If
it has a nibble, draw the nibble accordingly. You may
have to experiment with a centering the nibble in the
middle of the black rectangle. Here's a hint though:
you'll be dividing by two a lot.
- after drawing the GamePieces, draw the pacman image at his
current location.
- draw each of the ghosts at their current location. Don't
forget to draw the ghosts with the correct image. If they
are being chased you need to draw them appropriately.
NOTE: The x and y instance variables in Pacman and Ghost are
the index the GamePiece they reside on. In other words
thore values will always be between 0 and 14. The x and y
values when dealing with the Graphics object are pixels.
Keep this in mind.
Create a class called PacmanFrame which extends JFrame. This class
will contain a GameBoard and a menu. PacmanFrame should have the
following:
o an instance of GameBoard
o a JMenu with two JMenuItems:
- one that activates a new game: This should restart the
game no matter what the state of the current game.
- one that exits the program. This should stop the JVM just
as if we clicked on the X in the top right corner of the
frame.
o a default constructor which sets up the frame with a
BorderLayout, instantiates a new GameBoard and adds it to the
center. There is a constant in P6Constants called BOARD_FILE
containing the name of the file to tokenize into a GamePiece
array.
o We recommend you set the size of the frame to be about 520x520
o helper methods that set up the menus.
o We recommend you have this class be a listener for its own
JMenuItems. You will need to then have this class implement
ActionListener.
o The program should exit gracefully if either the quit menu is
chosen or the X in the top right is clicked.
PHASE V - PacmanEngine
====================================================================
The PacmanEngine class will be our controller in the MVC paradigm for
this project. It will likely be your single biggest class. For lack
of a better description, PacmanEngine will be the arbiter for the
game. It will process user control inputs, decide which movements by
pacman and the ghosts are legal, regulate the rate at which pacman and
the ghosts, move and determine whether a win or loss condition exists.
First let's talk about Swing Timers. The class javax.swing.Timer is a
class that can be set to fire ActionEvents at a specific
interval. (yes the same Events fired by JButtons and JMenuItems) We
will be using two Timers in PacmanEngine. One will regulate Ghost
movement. Every time the Ghost Timer fires, we want all the ghosts to
move one square. Where they move will be determined by the four
element array returned from Ghost's getMove method. A second timer
will regulate Pacman's movement. This timer will fire at a slightly
faster rate because we want Pacman to be able to outrun the ghosts.
Every time the Pacman Timer fires, we want Pacman to move one square
in the direction specified in Pacman's direction variable. You will
need to look at the API for specific methods to use.
Next let's talk about Key Listening. We've worked with ActionEvents
and ChangeEvents. Now you will use a third event/listener group that
listens for events from the keyboard. The game will be controlled by
six different keyboard keys. The four arrow keys will control
Pacman's direction. The 's' key will start the game (start Pacman and
the Ghosts moving) at the beginning of a game. The 'p' key will pause
and unpause the game. It's important to understand how Pacman will be
controlled. Pacman does not move only when a key is pressed. He
progresses in the direction specified by his direction variable at all
times. The arrow key pressed merely changes this direction variable.
There are exceptions to this. If pacman's direction takes him into a
wall, Pacman will halt and wait until an arrow key is pressed to give
him a new direction.
Now let's talk about JOptionPanes. The JOptionPane class provides
simple pre-packaged diaglog boxes. All you need is a JFrame instance
and the message you want to show the user. Here's how we will use one
for this project:
JOptionPane.showMessageDialog(<instance of JFrame>,
<String instance containing message
you want to show to the user>,
<String instance containing message
to be displayed in Dialog Box title bar>,
<int constant representing icon to be displayed in
dialog box along with message>);
This method call will pop up a small dialog box on top of your PacmanFrame.
Your instance of JFrame will be your PacmanFrame instance. Your message
and title should be something meaningful and relevant. You can use any icon
you want. Check out the API for a listing of icons and how to use them.
Included in your dialog box will be an "OK" JButton which will close the box
if pressed. This button is added and handled automatically by the method.
No effort on your part is needed to add or handle the event from the button.
Create a class called PacmanEngine that implements both ActionListener
and KeyListener. PacmanEngine should have the following:
o a javax.swing.Timer called GhostTimer. This variable will fire
an ActionEvent every P6Constants.GHOST_INTERVAL milliseonds
causing all the Ghosts to move one square
o a javax.swing.Timer called PacmanTimer. This variable will fire
an ActionEvent every P6Constants.PACMAN_INTERVAL milliseonds
causing Pacman to move one square.
o a GameBoard instance called board. This will be the GameBoard
instance used to draw the state of the board
o a PacmanFrame instance.
o a Ghost[] variable called ghosts. This array will hold the
four Ghosts in play.
o a Pacman variable called pacman. This will be the Pacman
instance in play.
o a constructor which takes in a PacmanFrame and a GameBoard and
sets the appropriate variables to these parameters. You will
also need to initialize both Timers. (but don't start them yet.)
Also set the Ghost array and the Pacman variable to those
variables initialized by PacmanFileReader.
o a method public void actionPerformed which takes in an
ActionEvent. This method will be called by both Timers at the
appropriate interval.
If this method was called by the PacmanTimer, it is Pacman's turn
to move. You do not need to worry about any keys pressed in this
method. Remember Pacman always moves in the direction specified
by his direction variable every time the Timer fires. Before
moving Pacman to the next square though, you need to first
determine that the move is legal (i.e., Pacman won't be moving on
top of a WallPiece or off the board) You have the GameBoard,
pacman's current x and y locations and his current direction.
From this information you can determine whether or not any given
move is legal. It is recommended that the functionality for
determining whether a given move is legal be abstracted to a
helper method since you will be using the same functionality for
the ghosts. If a given move is found to be legal, call Pacman's
move method (extended from MoveablePiece) passing in the
direction. Do not have PacmanEngine directly set the x and y
location variables.
If this method was called by the GhostTimer, you will need to
iterate through all four ghosts. At each ghost, call the getMove
method to retrieve each ghost's array of move choices. You
should then iterate through this array and move the ghost using the
first legal move you encounter. (Remember the zeroth index holds
the highest choice of movement for a particular ghost)
No matter which Timer called the method, you will need to
determine if the most recent move by either Pacman or the Ghosts
resulted in a state that should end the game. If all of the
FloorPieces are missing nibbles, the player has won the game.
You should display a notificatoin that the player has won using a
JOptionPane message dialog. (That's why we have an instance of
PacmanFrame which extends JFrame) If one of the Ghosts and
Pacman occupies the same square and that Ghost is not running
from Pacman, the player loses. Again display an appropriate
message dialog to the user. If a Ghost and Pacman occupies the
same square but that ghost is in fact running from Pacman, you
should reset that ghost. You also need to process any time
Pacman eats a nibble. If it's a regular simply remove that
nibble from the board by notifying that particular floor piece to
turn it's nibble boolean to false. If it's a special nibble, you
not only need to have the FloorPiece set it's special boolean to
false but you also need to iterate through all four ghosts and
have them go into run away mode. The ghosts should run from
Pacman and begin counting down their runAwayCount variables.
After processing all moves, if no end game condition exists, you
should call repaint() on the GameBoard instance. This will make
the GameBoard display the new locations of the ghosts.
o a method public void keyPressed which takes in a KeyEvent.
This method will be automatically called when any keyboard key is
pressed. There are only six we care about though. If the 's'
key is pressed, you should start both timers if they are not
already running. If the 'p' key is pressed, you should stop the
timers if they are running and start them if stopped. If one of
the four arrow keys is pressed, you should set Pacman's direction
variable to reflect the key pressed. You should only set the
variable, however, if the Timers are running. But how do we
figure out which key was pressed? The KeyEvent class has a
method called getKeyCode() which returns an int that represents a
key. Look through the KeyEvent API to figure out which constant
represents the appropriate keys.
PHASE VI - Testing and Turnin
====================================================================
Create a Driver class called "P6". This class should have a main
method which instantiates PacmanFrame.
Swing GUI components can sometimes throw exceptions without the
program crashing. i.e. you may see a stack trace on the
console but amazingly the program still appears to be
functioning. We consider this no different than if the program
crashed. You should not have any stack traces from exceptions
of any kind. You should catch and handle all exceptions.
This project, again, will require you to look through the API for many
solutions to a given task. Please make an honest effort to figure out
things for yourself before you seek outside help. This is the point
of the exercise.
Make sure you turn in the following files:
o GamePiece.java
o WallPiece.java
o FloorPiece.java
o MoveablePiece.java
o Ghost.java
o Pacman.java
o PacmanFileReader.java
o GameBoard.java
o PacmanFrame.java
o PacmanEngine.java
o P6.java
These may vary if you deviated from the suggested design.
PHASE VII - Extra Credit (Optional)
====================================================================
There will be a modest amount of extra credit given to those students
who go above and beyond the call of duty in the project. Make sure
you do not attempt any extra credit until you can certify that the
core requirements of the project have been satisfied.
Here are some ideas:
o In board #2, allow Pacman and/or the ghosts to go through the
hole on either the left or right side of the board and appear on
the opposite side. (i.e. wrapping around the board)
o Make pacman "chew" as he moves along the board. A second
pacman image with his mouth closed is provided
o Make pacman and the ghosts move smoothly from square to square
rather than abruptly appear in the next square.
o Create a smarter ghost movement algorithm that allows ghosts to
go around walls to get to pacman rather than just run up against
the wall.
o Develop a scoring system and display it somehow in PacmanFrame
o Put fruit on the board like in Ms. Pacman
o Use sound!
o Two player!
====================================================================

BIN
CS1322/p6/p6.zip Normal file

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More