teaching machines

CS 330 Lecture 29 – Modeling a Program

April 11, 2014 by . Filed under cs330, lectures, spring 2014.

Agenda

Model This

Express the following in superfast-to-process tree form:

$a = 5 * ($a + 7)
move 10
rotate 45
move 5
repeat 4
  move 10
  rotate 90
end

Code

Block.java

package logo330;

import java.util.ArrayList;

public class Block {
  private ArrayList<Command> commands = new ArrayList<Command>();

  public void execute(Environment env) {
    for (Command command : commands) {
      command.execute(env);
    }
  }
  
  public void add(Command command) {
    commands.add(command);
  }
}

Command.java

package logo330;

public abstract class Command {
  public abstract void execute(Environment env);
}

CommandListener.java

package logo330;
public interface CommandListener {
  public void onPostCommand();
}

CommandMove.java

package logo330;

import java.awt.geom.Line2D;


public class CommandMove extends Command {
  private Expression expr;
  
  public CommandMove(Expression expr) {
    this.expr = expr;
  }
  
  @Override
  public void execute(Environment env) {
    double newX = env.x + Math.cos(env.theta) * expr.evaluate(env);
    double newY = env.y + Math.sin(env.theta) * expr.evaluate(env);
    
    synchronized (env.segments) {
      env.segments.add(new Line2D.Double(env.x, env.y, newX, newY));
    }
    
    env.x = newX;
    env.y = newY;
    
    env.listener.onPostCommand();
  }
}

CommandRotate.java

package logo330;

import java.awt.geom.Line2D;


public class CommandRotate extends Command {
  private Expression expr;
  
  public CommandRotate(Expression expr) {
    this.expr = expr;
  }
  
  @Override
  public void execute(Environment env) {
    env.theta += Math.toRadians(expr.evaluate(env));
    env.listener.onPostCommand();
  }
}

Environment.java

package logo330;

import java.awt.geom.Line2D;
import java.util.ArrayList;

public class Environment {
  public double x = 0.0;
  public double y = 0.0;
  public double theta = 0.0;
  
  public ArrayList<Line2D.Double> segments = new ArrayList<Line2D.Double>();
  public CommandListener listener = null;
}

Expression.java

package logo330;

public abstract class Expression {
  public abstract double evaluate(Environment env);
}

ExpressionLiteral.java

package logo330;

public class ExpressionLiteral extends Expression {
  private double value;
  
  public ExpressionLiteral(double value) {
    this.value = value;
  }
  
  public double evaluate(Environment env) {
    return value;
  }
}

LogoVirtualMachine.java

package logo330;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class LogoVirtualMachine implements CommandListener {
  public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
    new LogoVirtualMachine();
  }

  private JFrame display;
  private JPanel panel;
  private int delay = 500;

  public LogoVirtualMachine() {
    Environment env = new Environment();
    env.listener = this;

    panel = new LogoDisplay(env);
    display = new JFrame("Logo");
    display.setContentPane(panel);

    display.setSize(1200, 700);
    display.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    display.setVisible(true);

    try {
      Thread.sleep(100);
    } catch (InterruptedException e) {
    }

    Block main = new Block();
    main.add(new CommandMove(new ExpressionLiteral(24.0)));
    main.add(new CommandRotate(new ExpressionLiteral(90.0)));
    main.add(new CommandMove(new ExpressionLiteral(24.0)));
    main.add(new CommandRotate(new ExpressionLiteral(90.0)));
    main.add(new CommandMove(new ExpressionLiteral(24.0)));
    main.add(new CommandRotate(new ExpressionLiteral(90.0)));
    main.add(new CommandMove(new ExpressionLiteral(24.0)));
    main.add(new CommandRotate(new ExpressionLiteral(90.0)));
    
    main.execute(env);
  }

  public void onPostCommand() {
    pause();
    panel.paintImmediately(0, 0, panel.getWidth(), panel.getHeight());
  }

  private void pause() {
    try {
      Thread.sleep(delay);
    } catch (InterruptedException e) {
    }
  }

  class LogoDisplay extends JPanel {
    private Line2D.Double arrowTop;
    private Line2D.Double arrowBottom;
    private Environment env;

    public LogoDisplay(Environment env) {
      this.env = env;
      arrowTop = new Line2D.Double(-10.0f, -5.0f, 0.0f, 0.0f);
      arrowBottom = new Line2D.Double(-10.0f, 5.0f, 0.0f, 0.0f);
    }

    public void paintComponent(Graphics g) {
      super.paintComponent(g);

      Graphics2D g2 = (Graphics2D) g;
      AffineTransform xform = g2.getTransform();

      g2.translate(getWidth() / 2, getHeight() / 2);

      synchronized (env.segments) {
        for (Line2D.Double segment : env.segments) {
          g2.draw(segment);
        }
      }

      g2.translate(env.x, env.y);
      g2.rotate(env.theta);
      g2.draw(arrowTop);
      g2.draw(arrowBottom);

      g2.setTransform(xform);
    }
  }
}

Haiku

Propaganda talks
The more languages we have
The smaller the mobs