Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

PLEASE HELP, THIS IS DUE BY TONIGHT!! CSC 142 Media Mash-Up! Please submit either a .zip or .jar file. We've got a mash-up! Different species

PLEASE HELP, THIS IS DUE BY TONIGHT!!

CSC 142

Media Mash-Up!

Please submit either a .zip or .jar file.

We've got a mash-up! Different species from different media (books, movies, tv, etc) are all together, moving around and fighting. Your task is to implement a set of classes that define the behavior of these different species in this environment.

You are given starter code that, when complete, runs the simulation with many objects moving around in it. The different objects will behave in different ways; you code is defining those differences.

Objectives

Inheritance

Background

As with previous assignments, there is starter code for you to download here. These files must be in the same folder as the files you create.

The class MashUpPlayer is the super class for the other objects in our simulation. It has one method that must be overridden, getMove(). There are public methods as well as protected methods that your subclasses will inherit and you'll be able to use (protected means that they are available to the subclass implementation, but not to clients).

There are also useful enum definitions in MashUpPlayer.

On each round of the simulation, each object is asked what action it wants to perform. There are four possible responses, each with a constant associated with it.

Constant

Description

Action.MOVE

Move forward one square in its current direction

Action.LEFT

Turn left (rotate 90 degrees counter-clockwise)

Action.RIGHT

Turn right (rotate 90 degrees clockwise)

Action.FIGHT

Fight the object in front of you

getMove() is passed an object of type MashUpPlayerInfo. This is an object that provides information about the current status of the object. It includes four methods for asking about surrounding neighbors, plus a method to find out the current direction this object is facing as well as a method to find out how many other objects this object has successfully fought.

Method

Description

public Neighbor getFront()

returns neighbor in front of you

public Neighbor getBack()

returns neighbor in back of you

public Neighbor getLeft()

returns neighbor to your left

public Neighbor getRight()

returns neighbor to your right

public Direction getDirection()

returns direction you are facing

public int getFightCount()

returns # of objects you have fought

The return type for the first four methods is Neighbor. There are four different constants for the different kind of neighbors you might encounter:

Constant

Description

Neighbor.WALL

The neighbor in that direction is a wall

Neighbor.EMPTY

The neighbor in that direction an empty square

Neighbor.SAME

The neighbor in that direction is the same type

Neighbor.OTHER

The neighbor in that direction is some other type

Notice that you are only told whether a neighbor is of your type or some other type. You don't know exactly what type it is.

getDirection() returns what direction this object is facing. There are four direction constants:

Constant

Description

Direction.NORTH

facing north

Direction.SOUTH

facing south

Direction.EAST

facing east

Direction.WEST

facing west

Specification

You are to implement four subclasses of MashUpPlayer. Three are specified for you:

class Minion
Color yellow String M
getMove(MashUpPlayerInfo) behavior: If a Minion faces an OTHER, it FIGHTs. Otherwise, it has equal probability to turn RIGHT or LEFT.
class Cylon
Color red String //
getMove(MashUpPlayerInfo) behavior: If a Cylon faces an OTHER, it FIGHTs. Otherwise, a Cylon moves in a zig zag (MOVE, turn LEFT, MOVE, turn RIGHT). If it runs into a wall or another Cylon it turnsaround, and start the sequence over. (Note, there is no constant for turning around. You have to implement this algorithm) If a Cylon ever finds itself with two or more OTHER neighbors, it becomes very aggressive and changes its color to black. It is in its regular state otherwise.
class Ogre
Color green String O
getMove(MashUpPlayerInfo) behavior: If an Ogre faces an OTHER, it FIGHTS. Otherwise, an Ogre walks around its domain: four MOVES in one direction, then turn LEFT, four MOVES in this new direction, then turn LEFT, repeatedly. If it runs into a wall or another Ogre, turn LEFT and start the sequence over again. If an Ogre is facing EAST, it is happy, so its String changes to :). When facing WEST, it is sad, so its String changes to :(

The 4th MashUpPlayer. is one you design. Have fun with this: deciding what character to model, and determining its state and its behavior. The only restriction is to not make it similar to the other three. Part of your score will reflect how interesting and unique you make the behavior. It's also critical that your documentation is accurate.

More Details

The constructors for these specialized classes must have no parameters. The client code won't be able to compile otherwise. Note - this is different than the constructor of MashUpPlayer.

You must override the getMove() method from MashUpPlayer.

You can add any private members (instance variables or methods) to these classes that are necessary for your design.That is your implementation choice. Be wise though about choices; not all variables should be instance variables.

You do not need to define any additional public methods for these classes.

Be smart when it comes to inheritance. Don't rewrite code that you don't have to.

To run the program, use the main() method in MashUpMain. You'll notice that there is a line in this method for each specialized object type. Uncomment each line once you've defined that class. Then you can observe the behavior and test if it is correct.

The simulator has a debug button that makes it easier to see the direction that objects are facing. When you request debug mode, your objects will be displayed as arrow characters that indicate the direction they are facing.

Each of your MashUpPlayer. classes has a pattern to it and at first all of your objects will be in synch with each other. But as the simulation runs they will get out of synch.

When an object loses a FIGHT, it is replaced by a new MashUpPlayer of the other type, but that new object retains some properties of the old one. It will be at the same location, facing in the same direction, and with the same fight count as the one it is replacing.

Documentation

You need to write complete documentation for your classes, both JavaDoc and internal.It's important that your documentation for the last class is accurate and specific.

Grading

/15 execution and design /5 documentation, style Good Luck!

PLEASE, THE FOLLOWING STARTER CLASSES:

1)/**

* Class MashUpFrame provides the user interface for a simple simulation * program. * * Stuart Reges and Marty Stepp */

import javax.swing.*; import java.awt.*; import java.awt.event.*; import javax.swing.event.*; import java.util.*;

public class MashUpFrame extends JFrame { private MashUpModel myModel; private MashUpPanel myPicture; private javax.swing.Timer myTimer; private JButton[] counts; private JButton countButton; private boolean started; private static boolean created; public MashUpFrame(int width, int height) { // this prevents someone from trying to create their own copy of // the GUI components if (created) throw new RuntimeException("Only one world allowed"); created = true;

// create frame and model setTitle("CSC142 MashUp simulation"); setDefaultCloseOperation(EXIT_ON_CLOSE); myModel = new MashUpModel(width, height);

// set up player picture panel myPicture = new MashUpPanel(myModel); add(myPicture, BorderLayout.CENTER);

addTimer();

constructSouth();

// initially it has not started started = false; }

// construct the controls and label for the southern panel private void constructSouth() { // add timer controls to the south JPanel p = new JPanel();

final JSlider slider = new JSlider(); slider.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { double ratio = 1000.0 / (1 + Math.pow(slider.getValue(), 0.3)); myTimer.setDelay((int) (ratio - 180)); } }); slider.setValue(20); p.add(new JLabel("slow")); p.add(slider); p.add(new JLabel("fast"));

JButton b1 = new JButton("start"); b1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { myTimer.start(); } }); p.add(b1); JButton b2 = new JButton("stop"); b2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { myTimer.stop(); } }); p.add(b2); JButton b3 = new JButton("step"); b3.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { doOneStep(); } }); p.add(b3); // add debug button JButton b4 = new JButton("debug"); b4.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { myModel.toggleDebug(); myPicture.repaint(); } }); p.add(b4);

// add 100 button JButton b5 = new JButton("next 100"); b5.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { multistep(100); } }); p.add(b5);

add(p, BorderLayout.SOUTH); }

// starts the simulation...assumes all Players have already been added public void start() { // don't let anyone start a second time and remember if we have started if (started) { return; } // if they didn't add any players, then nothing to do if (myModel.getCounts().isEmpty()) { System.out.println("nothing to simulate--no Players"); return; } started = true; addClassCounts(); pack(); setVisible(true); }

// add right-hand column showing how many of each player are alive private void addClassCounts() { Set> entries = myModel.getCounts(); JPanel p = new JPanel(new GridLayout(entries.size() + 1, 1)); counts = new JButton[entries.size()]; for (int i = 0; i < counts.length; i++) { counts[i] = new JButton(); p.add(counts[i]); }

// add simulation count countButton = new JButton(); countButton.setForeground(Color.BLUE); p.add(countButton);

add(p, BorderLayout.EAST); setCounts(); }

private void setCounts() { Set> entries = myModel.getCounts(); int i = 0; int max = 0; int maxI = 0; for (Map.Entry entry: myModel.getCounts()) { String s = String.format("%s =%4d", entry.getKey(), (int) entry.getValue()); counts[i].setText(s); counts[i].setForeground(Color.BLACK); if (entry.getValue() > max) { max = entry.getValue(); maxI = i; } i++; } counts[maxI].setForeground(Color.RED); String s = String.format("step =%5d", myModel.getSimulationCount()); countButton.setText(s); }

// add a certain number of players of a particular class to the simulation public void add(int number, Class c) { // don't let anyone add players after simulation starts if (started) { return; } // temporarily turning on started flag prevents player constructors // from calling add started = true; myModel.add(number, c); started = false; }

// post: creates a timer that calls the model's update // method and repaints the display private void addTimer() { ActionListener updater = new ActionListener() { public void actionPerformed(ActionEvent e) { doOneStep(); } }; myTimer = new javax.swing.Timer(0, updater); myTimer.setCoalesce(true); }

// one step of the simulation private void doOneStep() { myModel.update(); setCounts(); myPicture.repaint(); }

// advance the simulation until step % n is 0 private void multistep(int n) { myTimer.stop(); do { myModel.update(); } while (myModel.getSimulationCount() % n != 0); setCounts(); myPicture.repaint(); } }

================================================================

2)/**

* Class Panel displays a grid of MashUpPlayer objects * * Stuart Reges and Marty Stepp */

import javax.swing.*; import java.awt.Point; import java.awt.*; import java.awt.event.*; import java.util.*;

public class MashUpPanel extends JPanel { private MashUpModel myModel; private Font myFont; private static boolean created;

public static final int FONT_SIZE = 12;

public MashUpPanel(MashUpModel model) { // this prevents someone from trying to create their own copy of // the GUI components if (created) throw new RuntimeException("Only one world allowed"); created = true;

myModel = model; // construct font and compute char width once in constructor // for efficiency myFont = new Font("Monospaced", Font.BOLD, FONT_SIZE + 4); setBackground(Color.CYAN); setPreferredSize(new Dimension(FONT_SIZE * model.getWidth() + 20, FONT_SIZE * model.getHeight() + 20)); }

public void paintComponent(Graphics g) { super.paintComponent(g); g.setFont(myFont); Iterator i = myModel.iterator(); while (i.hasNext()) { MashUpPlayer next = i.next(); Point p = myModel.getPoint(next); String appearance = myModel.getAppearance(next); g.setColor(Color.BLACK); g.drawString("" + appearance, p.x * FONT_SIZE + 11, p.y * FONT_SIZE + 21); g.setColor(myModel.getColor(next)); g.drawString("" + appearance, p.x * FONT_SIZE + 10, p.y * FONT_SIZE + 20); } } }

================================================================

3)/**

*Class SpaceModel keeps track of the state of the MashUpPlayer simulation. * *Stuart Reges and Marty Stepp */

import java.util.*; import java.awt.Point; import java.awt.Color; import java.lang.reflect.*;

public class MashUpModel { private int height; private int width; private MashUpPlayer[][] grid; private Map info; private SortedMapthingCount; private boolean debugView; private int simulationCount; private static boolean created; public MashUpModel(int width, int height) { // this prevents someone from trying to create their own copy of // the GUI components if (created) throw new RuntimeException("Only one world allowed"); created = true;

this.width = width; this.height = height; grid = new MashUpPlayer[width][height]; info = new HashMap(); thingCount = new TreeMap(); this.debugView = false; }

public Iterator iterator() { return info.keySet().iterator(); }

public Point getPoint(MashUpPlayer c) { return info.get(c).p; }

public Color getColor(MashUpPlayer c) { return info.get(c).color; }

public String getString(MashUpPlayer c) { return info.get(c).string; }

public void add(int number, Class thing) { Random r = new Random(); MashUpPlayer.Direction[] directions = MashUpPlayer.Direction.values(); if (info.size() + number > width * height) throw new RuntimeException("adding too many critters"); for (int i = 0; i < number; i++) { MashUpPlayer next; try { next = makeMashUpPlayer(thing); } catch (Exception e) { System.out.println("ERROR: " + thing + " does not have" + " the appropriate constructor."); System.exit(1); return; } int x, y; do { x = r.nextInt(width); y = r.nextInt(height); } while (grid[x][y] != null); grid[x][y] = next; MashUpPlayer.Direction d = directions[r.nextInt(directions.length)]; info.put(next, new PrivateData(new Point(x, y), d, 0, next.getColor(), next.toString())); } String name = thing.getName(); if (!thingCount.containsKey(name)) thingCount.put(name, number); else thingCount.put(name, thingCount.get(name) + number); }

@SuppressWarnings("unchecked") private MashUpPlayer makeMashUpPlayer(Class thing) throws Exception { Constructor c = thing.getConstructors()[0]; return (MashUpPlayer) c.newInstance(); }

public int getWidth() { return width; }

public int getHeight() { return height; }

public String getAppearance(MashUpPlayer c) { // Override specified toString if debug flag is true if (!debugView) return info.get(c).string; else { PrivateData data = info.get(c); if (data.direction == MashUpPlayer.Direction.NORTH) return "^"; else if (data.direction == MashUpPlayer.Direction.SOUTH) return "v"; else if (data.direction == MashUpPlayer.Direction.EAST) return ">"; else return "<"; } } public void toggleDebug() { this.debugView = !this.debugView; }

private boolean inBounds(int x, int y) { return (x >= 0 && x < width && y >= 0 && y < height); }

private boolean inBounds(Point p) { return inBounds(p.x, p.y); }

// returns the result of rotating the given direction clockwise private MashUpPlayer.Direction rotate(MashUpPlayer.Direction d) { if (d == MashUpPlayer.Direction.NORTH) return MashUpPlayer.Direction.EAST; else if (d == MashUpPlayer.Direction.SOUTH) return MashUpPlayer.Direction.WEST; else if (d == MashUpPlayer.Direction.EAST) return MashUpPlayer.Direction.SOUTH; else return MashUpPlayer.Direction.NORTH; }

private Point pointAt(Point p, MashUpPlayer.Direction d) { if (d == MashUpPlayer.Direction.NORTH) return new Point(p.x, p.y - 1); else if (d == MashUpPlayer.Direction.SOUTH) return new Point(p.x, p.y + 1); else if (d == MashUpPlayer.Direction.EAST) return new Point(p.x + 1, p.y); else return new Point(p.x - 1, p.y); }

private Info getInfo(PrivateData data, Class original) { MashUpPlayer.Neighbor[] neighbors = new MashUpPlayer.Neighbor[4]; MashUpPlayer.Direction d = data.direction; for (int i = 0; i < 4; i++) { neighbors[i] = getStatus(pointAt(data.p, d), original); d = rotate(d); } return new Info(neighbors, data.direction, data.fightCount); }

private MashUpPlayer.Neighbor getStatus(Point p, Class original) { if (!inBounds(p)) return MashUpPlayer.Neighbor.WALL; else if (grid[p.x][p.y] == null) return MashUpPlayer.Neighbor.EMPTY; else if (grid[p.x][p.y].getClass() == original) return MashUpPlayer.Neighbor.SAME; else return MashUpPlayer.Neighbor.OTHER; }

@SuppressWarnings("unchecked") public void update() { simulationCount++; Object[] list = info.keySet().toArray(); Collections.shuffle(Arrays.asList(list)); Arrays.sort(list, new Comparator() { public int compare(Object x, Object y) { return Math.min(10, info.get(x).fightCount) - Math.min(10, info.get(y).fightCount); } }); for (int i = 0; i < list.length; i++) { MashUpPlayer next = (MashUpPlayer)list[i]; PrivateData data = info.get(next); if (data == null) { // happens when creature was infected earlier in this round continue; } Point p = data.p; Point p2 = pointAt(p, data.direction); MashUpPlayer.Action move = next.getMove(getInfo(data, next.getClass())); data.color = next.getColor(); data.string = next.toString(); if (move == MashUpPlayer.Action.LEFT) data.direction = rotate(rotate(rotate(data.direction))); else if (move == MashUpPlayer.Action.RIGHT) data.direction = rotate(data.direction); else if (move == MashUpPlayer.Action.MOVE) { if (inBounds(p2) && grid[p2.x][p2.y] == null) { grid[p2.x][p2.y] = grid[p.x][p.y]; grid[p.x][p.y] = null; data.p = p2; } } else if (move == MashUpPlayer.Action.FIGHT) { if (inBounds(p2) && grid[p2.x][p2.y] != null && grid[p2.x][p2.y].getClass() != next.getClass()) { MashUpPlayer other = grid[p2.x][p2.y]; // remember the old MashUpPlayer's private data PrivateData oldData = info.get(other); // then remove that old MashUpPlayer String c1 = other.getClass().getName(); thingCount.put(c1, thingCount.get(c1) - 1); String c2 = next.getClass().getName(); thingCount.put(c2, thingCount.get(c2) + 1); info.remove(other); // and add a new one to the grid try { grid[p2.x][p2.y] = makeMashUpPlayer(next.getClass()); } catch (Exception e) { throw new RuntimeException("" + e); } // and add to the map info.put(grid[p2.x][p2.y], oldData); // and update oldData for new critter's color/string oldData.color = grid[p2.x][p2.y].getColor(); oldData.string = grid[p2.x][p2.y].toString(); // and remember that we fought a critter data.fightCount++; } } } }

public Set> getCounts() { return Collections.unmodifiableSet(thingCount.entrySet()); }

public int getSimulationCount() { return simulationCount; }

private class PrivateData { public Point p; public MashUpPlayer.Direction direction; public int fightCount; public Color color; public String string;

public PrivateData(Point p, MashUpPlayer.Direction d, int fightCount, Color color, String string) { this.p = p; this.direction = d; this.fightCount = fightCount; this.color = color; this.string = string; }

public String toString() { return p + " " + direction + " " + fightCount; } }

// an object used to query a critter's state (neighbors, direction) private static class Info implements MashUpPlayerInfo { private MashUpPlayer.Neighbor[] neighbors; private MashUpPlayer.Direction direction; private int fightCount;

public Info(MashUpPlayer.Neighbor[] neighbors, MashUpPlayer.Direction d, int fightCount) { this.neighbors = neighbors; this.direction = d; this.fightCount = fightCount; }

public MashUpPlayer.Neighbor getFront() { return neighbors[0]; }

public MashUpPlayer.Neighbor getBack() { return neighbors[2]; }

public MashUpPlayer.Neighbor getLeft() { return neighbors[3]; }

public MashUpPlayer.Neighbor getRight() { return neighbors[1]; }

public MashUpPlayer.Direction getDirection() { return direction; }

public int getFightCount() { return fightCount; } } }

==================================================================

4)/**

* MashUpMain provides the main method for a simple simulation program. Alter * the number of each entity added to the simulation if you want to experiment * with different scenarios. You can also alter the width and height passed to * the MashUpFrame constructor.

* by Stuart Reges and Marty Stepp */

public class MashUpMain { public static int COUNT = 30; public static void main(String[] args) { MashUpFrame frame = new MashUpFrame(60, 40);

// uncomment each of these lines as you complete these classes // frame.add(COUNT, Minion.class); // frame.add(COUNT, Cylon.class); // frame.add(COUNT, Ogre.class); // ADD AN ADDITIONAL LINE FOR YOUR NEW CLASS

frame.start(); } }

=================================================================

5)

import java.awt.*;

/** * This is the superclass of all of the MashUpPlayer classes. It keeps track of color * String representation. Some methods must be overriden. * * The class provides several kinds of constants:

* type Neighbor : WALL, EMPTY, SAME, OTHER * type Action : MOVE, LEFT, RIGHT, FIGHT * type Direction : NORTH, SOUTH, EAST, WEST

* * Based on work by Stuart Reges and Marty Stepp */

public abstract class MashUpPlayer {

private String myDisplay; private Color myColor; /** * Initializes this MashUpPlayer's state * @param s this MashUpPlayer's initial String representation * @param c this MashUpPlayer's starting color */ public MashUpPlayer(String s, Color c){ myDisplay = s; myColor = c; } /** * This method answers this MashUpPlayer's color * @return the current color */ public Color getColor(){ return myColor; }

/** * This method answers this MashUpPlayer's String representation * @return the current string */ public String toString(){ return myDisplay; } /** * This method allows subclasses only to change this MashUpPlayer's color * @param c the new color */ protected void setColor(Color c){ myColor = c; } /** * This method allows subclasses only to change this MashUpPlayer's String display * @param s the new display */ protected void setDisplay(String s){ myDisplay = s; }

/** * This method answers this MashUpPlayer's Action * MUST BE OVERRIDDEN IN SUBCLASSES * * @param info information about this MashUpPlayer in the simulation * @return the current Action */ public abstract Action getMove(MashUpPlayerInfo info);

/** *

* WALL: against the wall of the simulation world * EMPTY: the neighboring spot is empty * SAME: an MashUpPlayer of the same species * OTHER: an MashUpPlayer of another species
*/ public static enum Neighbor { WALL, EMPTY, SAME, OTHER };

/** *

* MOVE: move one space in the current direction * LEFT: turn left by rotating 90 degrees counter-clockwise * RIGHT: turn right by rotating 90 degrees clockwise * FIGHT: fight the MashUpPlayer in front of you
*/ public static enum Action { MOVE, LEFT, RIGHT, FIGHT };

/** *

* NORTH * SOUTH * EAST * WEST
*/ public static enum Direction { NORTH, SOUTH, EAST, WEST }; // This prevents any MashUpPlayer from trying to redefine the definition of // object equality, which is important for the simulator to work properly. public final boolean equals(Object other) { return this == other; } }

=================================================================

6)

/** * The MashUpPlayerInfo interface defines a set of methods for querying the * state of a MashUpPlayer object in the simulation. * * Based on work by Stuart Reges and Marty Stepp */

public interface MashUpPlayerInfo { /** * returns the neighbor in front of a specific MashUpPlayer */ public MashUpPlayer.Neighbor getFront(); /** * returns the neighbor behind of a specific MashUpPlayer */ public MashUpPlayer.Neighbor getBack(); /** * returns the neighbor to the left of a specific MashUpPlayer */ public MashUpPlayer.Neighbor getLeft(); /** * returns the neighbor to the right of a specific MashUpPlayer */ public MashUpPlayer.Neighbor getRight(); /** * returns the direction a specific MashUpPlayer is facing in the simulation */ public MashUpPlayer.Direction getDirection(); /** * returns the number of entities a specific MashUpPlayer has infected */ public int getFightCount(); }

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

More Books

Students also viewed these Databases questions

Question

3. What are the current trends in computer hardware platforms?

Answered: 1 week ago