Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

In this lab, we\'ll be writing a class hierarchy of Emoji. Here is a UML diagram

ID: 3784930 • Letter: I

Question

In this lab, we'll be writing a class hierarchy of Emoji. Here is a UML diagram of the classes we'll be writing:

Emoji and Face Emoji are abstract classes because they don't have enough information to be useful on their own.

Here's a description of what each class should contain:

Emoji (abstract class):

member variables for position and size of the emoji

constructor taking x, y, size

abstract void draw(). We can't implement this method yet, so it's abstract, but all emoji that inherit from it must have a draw method

FaceEmoji (abstract class):

constructor

void draw() //this will draw the yellow circle and black eyes of the face, but it doesn't have enough information to draw the mouth

SmileyFaceEmoji:

constructor

void draw() //use StdDraw.arc to draw the smiling face

FrowningFaceEmoji:

constructor

void draw() //like smiley face, but sadder

ClockEmoji:

constructor (taking an extra int param for the hour the clock is set to)

void draw() //draw a circle around the border and an "hour hand" line out from the center that shows the correct time

Driver (with main)

In main, read from the emojiInputs.txt file. The file contains information about a grid of emoji. The file starts with the number of rows, then the number of columns.

Then, it lists the emoji that should fill in the grid. "smile" means the emoji should be a SmileyFaceEmoji, "frown" means a FrowningFaceEmoji, and "clock" means ClockEmoji and will always be followed by an integer representing the hour hand of the clock.

Each emoji should be 100 pixels x 100 pixels.

Test your code with a text file containing "4
4
smile
frown
smile
clock 4
clock 8
frown
smile
clock 3
clock 12
clock 10
smile
smile
smile
frown
frown
frown"

Your program should produce output similar to this:

Once you have that working, we're going to add a couple of additional methods and test them.

Add a tick() method to the ClockEmoji class that adds one to the hour (it should wrap around at 12).'

Add an additional boolean to the FaceEmoji class named winking. Set it to false in the constructor.

Modify the draw method of your FaceEmoji class so that if it is winking, one of the eyes is drawn as a line instead of a circle.

Add a wink() method to the FaceEmoji class to toggle (flip the value) of your winking member variable.

In main, animate your emoji by calling wink() on the faces and tick() on the clocks and then drawing them. You'll need to use instanceof and typecasts to accomplish this. You should call StdDraw.show(500) inside your animation loop so that they don't update too quickly.

Hopefully you can tell that this isn't the best way to implement animated emoji. We're going to "refactor" our code in order to improve it.

Add a new abstract method named animate() to the Emoji class, then override it in the FaceEmoji and ClockEmoji classes to call the appropriate methods (wink and tick). Comment out the code in main that calls tick() and wink(), and then add code to use the new animate() method. By modifying our program design to add a new abstract method, we've significantly simplified the code.

UML:

Output:

Explanation / Answer

EmojiDriver.java


import java.io.FileInputStream;
import java.util.Scanner;
import edu.princeton.cs.introcs.StdDraw;

public class EmojiDriver {

   public static void main(String[] args) throws Exception{
       //Read the file
       Scanner file = new Scanner( new FileInputStream("emoji1.txt"));
       int rows = file.nextInt();
       int columns = file.nextInt();
      
       //Create the array
       Emoji[][] emoji = new Emoji[rows][columns];
       String scan;
              
       //Set the canvas
       int size = 125;
       int xScale = columns*size;
       int yScale = rows*size;
       double radius;
      
       if (columns > rows) {
           radius = (0.5*xScale)/columns;
       } else {
           radius = (0.5*yScale)/rows;
       }
      
       StdDraw.setCanvasSize(xScale, yScale);
       StdDraw.setXscale(0, xScale);
       StdDraw.setYscale(yScale, 0);
      
       //Fill the array from text file
       for (int r = 0; r < rows; r++){
           for (int c = 0; c < columns; c++){
               scan = file.next();
               if (scan.equals("clock")) {
                   String word = file.next();
                   String m = file.next();
                   int hour = Integer.parseInt(word);
                   int min = Integer.parseInt(m);
                   emoji[r][c] = new ClockEmoji(radius + 2*c*radius, radius + 2*r*radius, radius, hour, min);
               } else if (scan.equals("smile")) {
                   emoji[r][c] = new SmileyFaceEmoji(radius + 2*c*radius, radius + 2*r*radius, radius, true);
               } else if (scan.equals("frown")) {
                   emoji[r][c] = new FrowningFaceEmoji(radius + 2*c*radius, radius + 2*r*radius, radius, true);
               }
           }
       }
      
       //Draw and animate the array
       while(true) {
           StdDraw.clear();
           for (int r = 0; r < rows; r++) {
               for (int c = 0; c < columns; c++) {  
                   emoji[r][c].draw();
                   emoji[r][c].animate();
               }
           }
           StdDraw.show(500);  
       }
   }
}


ClockEmoji.java


import edu.princeton.cs.introcs.StdDraw;

public class ClockEmoji extends Emoji{
   //Instance Variables
   private int hour;
   private int minute;
  
   public ClockEmoji(double x, double y, double r, int hr, int min) {
       super(x, y, r);
       hour = hr;
       minute = min;
   }
  
   public void draw() {
       StdDraw.setPenRadius(0.005);
       StdDraw.circle(getCenterX(), getCenterY(), getRadius());
       StdDraw.line(getCenterX(), getCenterY(), getCenterX() + getRadius()*0.9*Math.cos((minute-15)*Math.PI/30), getCenterY() + getRadius()*0.9*Math.sin((minute-15)*Math.PI/30));
       StdDraw.line(getCenterX(), getCenterY(), getCenterX() + getRadius()*0.7*Math.cos((hour-3)*Math.PI/6), getCenterY() + getRadius()*0.7*Math.sin((hour-3)*Math.PI/6));
   }
  
   public void animate() {
       if (minute == 59) {
           minute = 0;
           hour++;
       } else {
           minute++;
       }
   }

}

Emoji.java

public abstract class Emoji {
   //Instance Variables
   private double centerX;
   private double centerY;
   private double radius;
  
   //Constructor
   public Emoji(double x, double y, double r) {
       centerX = x;
       centerY = y;
       radius = r;
   }
  
   //Accessor Methods
   public double getCenterX() {
       return centerX;
   }
  
   public double getCenterY() {
       return centerY;
   }
  
   public double getRadius() {
       return radius;
   }
  
   //Abstract Methods
   public abstract void draw();
   public abstract void animate();
  
}

SmileyFaceEmoji.java


import edu.princeton.cs.introcs.StdDraw;

public class SmileyFaceEmoji extends FaceEmoji {
   //Constructor
   public SmileyFaceEmoji(double x, double y, double r, boolean wink) {
       super(x, y, r, wink);
   }
  
   //Call FaceEmoji draw method and add a smile
   public void draw(){
       super.draw();
       StdDraw.arc(getCenterX(), getCenterY() + (0.2)*getRadius(), getRadius() * 0.4, 180, 0);
   }
}

FaceEmoji.java


import edu.princeton.cs.introcs.StdDraw;

public abstract class FaceEmoji extends Emoji{
   //Instance Variables
   private boolean isWinking;
  
   //Constructor
   public FaceEmoji(double x, double y, double r, boolean wink) {
       super(x, y, r);
       isWinking = wink;
   }
  
   //Draw a face with two eyes
   public void draw(){
       StdDraw.setPenColor(StdDraw.YELLOW);
       StdDraw.filledCircle(getCenterX(), getCenterY(), getRadius());
       StdDraw.setPenColor(StdDraw.BLACK);
       StdDraw.setPenRadius((0.00013)*getRadius());
       StdDraw.filledCircle(getCenterX() + (0.25)* getRadius(), getCenterY() - (0.25)*getRadius(), getRadius()*(0.1));
      
       if (isWinking){
           StdDraw.arc(getCenterX() - (0.25)* getRadius(), getCenterY() - (0.25)*getRadius(), getRadius()*(0.1), 0, 180);
       } else {
           StdDraw.filledCircle(getCenterX() - (0.25)* getRadius(), getCenterY() - (0.25)*getRadius(), getRadius()*(0.1));
       }
   }
  
   //Make one eye wink and unwink
   public void animate() {
       if (isWinking) {
           isWinking = false;
       } else {
           isWinking = true;
       }
   }
  
}

FrowningFaceEmoji.java


import edu.princeton.cs.introcs.StdDraw;

public class FrowningFaceEmoji extends FaceEmoji{
   //Constructor
   public FrowningFaceEmoji(double x, double y, double r, boolean wink) {
       super(x, y, r, wink);
   }
  
   //Call FaceEmoji draw method and add a frown
   public void draw() {
       super.draw();
       StdDraw.arc(getCenterX(), getCenterY() + (0.5)*getRadius(), getRadius() * 0.4, 0, 180);
   }
}

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote