diff --git a/.classpath b/.classpath deleted file mode 100644 index f00af9b..0000000 --- a/.classpath +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/.gitHooks/pre-commit b/.gitHooks/pre-commit new file mode 100755 index 0000000..caa3bf8 --- /dev/null +++ b/.gitHooks/pre-commit @@ -0,0 +1,18 @@ +#!/bin/bash + +# First: git config core.hooksPath `pwd`/.gitHooks + +# Copy jar file to repo root +# JAR_FILE=Turtle-Interpreter/target/Turtle-Interpreter-0.1.0.jar + +# cp ${JAR_FILE} . +# EXIT_CODES=( $? ) +# git add -A +# EXIT_CODES+=( $? ) + +# for e in ${EXIT_CODES[@]}; do +# if [[ $e -gt 0 ]] +# then +# exit 1 +# fi +# done diff --git a/.gitignore b/.gitignore index ae3c172..f4ceea7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -/bin/ +**/target/ diff --git a/.project b/.project deleted file mode 100644 index e813fb4..0000000 --- a/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - TurtleInterpreter - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/README.md b/README.md index baa4868..7830c78 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,24 @@ # Turtle-Interpreter -Simple Turtle Interpter. -To build: import in Eclipse. -Run TurtleInterpreter. -A window should appear with button "Open File", click on button and a dialog box should appear. -Select from folder TurtlePrograms any sample program. +Simple Turtle Interpreter. + +To run: `$ cd Turtle-Interpreter && make run` + +A window should appear with button "Open Program File": +- Click on button and a dialog box should appear. +- Select from folder Programs any sample program. + The interpreter will go through the commands in file and move Turtles. -You can select more input files. -You can also write your input file using an editor of your choice and see how it behaves. + +You can select more input files. You can also write your input file using an editor of your choice and see how it behaves. + +``` Language commands: -turtle name - create a new turtle identified by the given name -move name x - moves the named turtle forward by x units -left name x - rotate the turtle anticlockwise by x degrees -right name x - rotate the turtle clockwise by x degrees -pen name up - lift the pen off the “paper” -pen name down - put the pen down so that subsequent moves draw of the screen -colour name c - set the drawing colour of the turtle appropriately -Possible colours: red, blue, cyan, orange and green. Default is black or argument is unspecified colour. +- turtle name -> create a new turtle identified by the given name +- move name x -> moves the named turtle forward by x units +- left name x -> rotate the turtle anticlockwise by x degrees +- right name x -> rotate the turtle clockwise by x degrees +- pen name up -> lift the pen off the “paper” +- pen name down -> put the pen down so that subsequent moves draw of the screen +- color name c -> set the drawing color of the turtle appropriately + - Possible colors: red, blue, cyan, orange and green. Default is black or argument is unspecified color. +``` \ No newline at end of file diff --git a/Turtle-Interpreter/.vscode/settings.json b/Turtle-Interpreter/.vscode/settings.json new file mode 100644 index 0000000..a8bf9bc --- /dev/null +++ b/Turtle-Interpreter/.vscode/settings.json @@ -0,0 +1,10 @@ +{ + "cSpell.language": "en", + "cSpell.enabledLanguageIds": [ + "markdown" + ], + "files.exclude": { + "**/target": true + }, + "java.configuration.updateBuildConfiguration": "automatic" +} \ No newline at end of file diff --git a/Turtle-Interpreter/Makefile b/Turtle-Interpreter/Makefile new file mode 100644 index 0000000..940dbab --- /dev/null +++ b/Turtle-Interpreter/Makefile @@ -0,0 +1,9 @@ +test: + @mvn test + +run: + @mvn compile && mvn package && java -jar -XX:+UseZGC -XX:+ZGenerational target/Turtle-Interpreter-0.1.0.jar + +upgrade: + @mvn release:update-versions + @mvn versions:use-latest-releases diff --git a/TurtlePrograms/colouredbox b/Turtle-Interpreter/Programs/colouredbox similarity index 100% rename from TurtlePrograms/colouredbox rename to Turtle-Interpreter/Programs/colouredbox diff --git a/TurtlePrograms/commandError b/Turtle-Interpreter/Programs/commandError similarity index 100% rename from TurtlePrograms/commandError rename to Turtle-Interpreter/Programs/commandError diff --git a/TurtlePrograms/lozenge b/Turtle-Interpreter/Programs/lozenge similarity index 100% rename from TurtlePrograms/lozenge rename to Turtle-Interpreter/Programs/lozenge diff --git a/TurtlePrograms/redbox b/Turtle-Interpreter/Programs/redbox similarity index 100% rename from TurtlePrograms/redbox rename to Turtle-Interpreter/Programs/redbox diff --git a/TurtlePrograms/ThreeTurtles b/Turtle-Interpreter/Programs/threeTurtles similarity index 100% rename from TurtlePrograms/ThreeTurtles rename to Turtle-Interpreter/Programs/threeTurtles diff --git a/TurtlePrograms/twolines b/Turtle-Interpreter/Programs/twolines similarity index 100% rename from TurtlePrograms/twolines rename to Turtle-Interpreter/Programs/twolines diff --git a/Turtle-Interpreter/dependency-reduced-pom.xml b/Turtle-Interpreter/dependency-reduced-pom.xml new file mode 100644 index 0000000..950c151 --- /dev/null +++ b/Turtle-Interpreter/dependency-reduced-pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + TurtleInterpreter + Turtle-Interpreter + Turtle-Interpreter + 0.1.0 + Turtle-Interpreter. + https://turtle.interpreter + + + + maven-clean-plugin + 3.1.0 + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + maven-shade-plugin + 3.2.4 + + + package + + shade + + + + + TurtleInterpreter.App + + + + + + + + + + + + maven-project-info-reports-plugin + + + + + 17 + 17 + UTF-8 + + diff --git a/Turtle-Interpreter/pom.xml b/Turtle-Interpreter/pom.xml new file mode 100644 index 0000000..fd434b0 --- /dev/null +++ b/Turtle-Interpreter/pom.xml @@ -0,0 +1,77 @@ + + + + 4.0.0 + + TurtleInterpreter + Turtle-Interpreter + 0.1.0 + + Turtle-Interpreter + Turtle-Interpreter. + https://turtle.interpreter + + + UTF-8 + 17 + 17 + + + + + junit + junit + 4.13.2 + + + + + + + + maven-clean-plugin + 3.1.0 + + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + package + + shade + + + + + TurtleInterpreter.App + + + + + + + + + + + + + + maven-project-info-reports-plugin + + + + diff --git a/Turtle-Interpreter/pom.xml.versionsBackup b/Turtle-Interpreter/pom.xml.versionsBackup new file mode 100644 index 0000000..a27f9a4 --- /dev/null +++ b/Turtle-Interpreter/pom.xml.versionsBackup @@ -0,0 +1,77 @@ + + + + 4.0.0 + + TurtleInterpreter + Turtle-Interpreter + 0.1.1-SNAPSHOT + + Turtle-Interpreter + Turtle-Interpreter. + https://turtle.interpreter + + + UTF-8 + 17 + 17 + + + + + junit + junit + 3.8.1 + + + + + + + + maven-clean-plugin + 3.1.0 + + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + package + + shade + + + + + TurtleInterpreter.App + + + + + + + + + + + + + + maven-project-info-reports-plugin + + + + diff --git a/Turtle-Interpreter/src/main/java/TurtleInterpreter/App.java b/Turtle-Interpreter/src/main/java/TurtleInterpreter/App.java new file mode 100644 index 0000000..5936bd1 --- /dev/null +++ b/Turtle-Interpreter/src/main/java/TurtleInterpreter/App.java @@ -0,0 +1,21 @@ +package TurtleInterpreter; + +import java.io.IOException; +import TurtleInterpreter.domain.Interpreter; + +/** + * Turtle Interpreter + */ +public class App { + + public static void main(String[] args){ + Interpreter p = new Interpreter(); + try { + p.run(); + } catch (IOException e) { + System.err.println(e.getMessage()); + } + + } + +} diff --git a/Turtle-Interpreter/src/main/java/TurtleInterpreter/domain/Interpreter.java b/Turtle-Interpreter/src/main/java/TurtleInterpreter/domain/Interpreter.java new file mode 100644 index 0000000..095d676 --- /dev/null +++ b/Turtle-Interpreter/src/main/java/TurtleInterpreter/domain/Interpreter.java @@ -0,0 +1,234 @@ +package TurtleInterpreter.domain; + +import TurtleInterpreter.userInterface.Turtle; + +import java.awt.Graphics; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.event.*; +import javax.swing.*; +import java.io.File; +import java.io.FileNotFoundException; +import java.awt.image.BufferedImage; +import java.util.*; +import java.io.IOException; + +public class Interpreter extends JPanel implements ActionListener { + private static final int FrameWidth = 800; + private static final int FrameHeight = 800; + private LinkedList turtleList; + private final BufferedImage image; + private Scanner in = null; + private boolean redraw; + private javax.swing.Timer timer; + private String[] currentCommand; + private Iterator commandIterator; + + public Interpreter() { + turtleList = new LinkedList<>(); + setPreferredSize(new Dimension(FrameWidth, FrameHeight)); + image = new BufferedImage(FrameWidth, FrameHeight, BufferedImage.TYPE_INT_RGB); + setMaximumSize(new Dimension(image.getWidth(), image.getHeight())); + redraw = false; + clear(); + } + + public void clear() { + Graphics g = image.getGraphics(); + g.setColor(Color.LIGHT_GRAY); + g.fillRect(0, 0, image.getWidth(), image.getHeight()); + } + + public void drawLine(Turtle t, int x1, int y1, int x2, int y2) { + Graphics g = image.getGraphics(); + g.setColor(t.getColor()); + g.drawLine(x1, y1, x2, y2); + } + + public void paintComponent(Graphics g) { + super.paintComponent(g); + g.drawImage(image, 0, 0, null); + if (!turtleList.isEmpty()) { + for (Turtle t : turtleList) { + g.drawImage(t.getImage(), (t.getLocX2() - 15) + FrameWidth / 2, -(t.getLocY2() + 15) + FrameHeight / 2, + 30, 30, this); + } + } + } + + @Override + public void actionPerformed(ActionEvent event) { + String s = event.getActionCommand(); + if (s.equals("Open Program File")) { // read input commands from a text file + JFileChooser chooser = new JFileChooser(); + if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { + File selectedFile = chooser.getSelectedFile(); + try { + in = new Scanner(selectedFile); + } catch (FileNotFoundException e1) { + System.err.println(e1.getMessage()); + } + } + // start over, clear screen and initialize Turtle List + clear(); + turtleList = new LinkedList<>(); + processFile(in); + } + } + + public Color toColor(String s) { + // Only five colors are allowed + return switch (s) { + case "red" -> Color.RED; + case "blue" -> Color.BLUE; + case "cyan" -> Color.CYAN; + case "green" -> Color.GREEN; + case "orange" -> Color.ORANGE; + default -> Color.BLACK; + }; + } + + void processFile(Scanner in) { + int lineNumber = 1; + final int MAX_LINES = 100; // maximum number of command lines + LinkedList commands = new LinkedList<>(); + + while (in.hasNextLine() && lineNumber < MAX_LINES) { + String[] line = in.nextLine().split(" "); + if (line.length < 2 || line.length >= 4) { + JOptionPane.showMessageDialog(this, "Line : " + lineNumber + " : Invalid command, Program Terminated"); + return; + } else { + commands.add(line); + } + lineNumber++; + } + + commandIterator = commands.iterator(); + timer = new javax.swing.Timer(377, new TimerActionListener()); + timer.start(); + } + + private class TimerActionListener implements ActionListener { + public void actionPerformed(ActionEvent e) { + if (commandIterator.hasNext()) { + currentCommand = commandIterator.next(); + executeCommand(currentCommand); + if (redraw) { + repaint(); + } + } else { + timer.stop(); + } + } + } + + private void executeCommand(String[] line) { + Iterator itr = turtleList.iterator(); + boolean done; + switch (line[0]) { + case "turtle": + Turtle turtle = new Turtle(line[1], 0, 0); // New Turtle in Turtle coordinates at center + turtleList.add(turtle); + redraw = true; + break; + + case "move": + done = false; + while (itr.hasNext() & !done) { + Turtle t = itr.next(); + String name = t.getName(); + if (name.equals(line[1])) { + done = true; + t.setDelta(Integer.parseInt(line[2])); + t.MoveForward(t.getDelta(), FrameWidth / 2, FrameHeight / 2); + if (t.getWriting()) { + drawLine(t, t.getLocX1() + FrameWidth / 2, -t.getLocY1() + FrameHeight / 2, + t.getLocX2() + FrameWidth / 2, -t.getLocY2() + FrameHeight / 2); + } + t.setLocX1(t.getLocX2()); // update Turtle position + t.setLocY1(t.getLocY2()); + } + } + redraw = true; + break; + + case "left": + done = false; + while (itr.hasNext() & !done) { + Turtle t = itr.next(); + String name = t.getName(); + if (name.equals(line[1])) { + done = true; + t.TurnLeft(Math.abs(Double.parseDouble(line[2]))); + t.rotateTurtle(); + } + } + redraw = true; + break; + + case "right": + done = false; + while (itr.hasNext() & !done) { + Turtle t = itr.next(); + String name = t.getName(); + if (name.equals(line[1])) { + done = true; + t.TurnRight(Math.abs(Double.parseDouble(line[2]))); + t.rotateTurtle(); + } + } + redraw = true; + break; + + case "pen": + done = false; + while (itr.hasNext() & !done) { + Turtle t = itr.next(); + String name = t.getName(); + if (name.equals(line[1])) { + done = true; + if ((line[2]).equals("up")) + t.penUp(); + else if ((line[2]).equals("down")) + t.penDown(); + } + } + redraw = false; + break; + + case "colour": + done = false; + while (itr.hasNext() & !done) { + Turtle t = itr.next(); + String name = t.getName(); + if (name.equals(line[1])) { + done = true; + t.setColor(toColor(line[2])); // change color + } + } + redraw = false; + break; + + default: + JOptionPane.showMessageDialog(this, "Invalid command, Program Terminated"); + timer.stop(); + } + } + + public void run() throws IOException { + JFrame f = new JFrame(); + JButton b = new JButton("Open Program File"); + + Interpreter p = new Interpreter(); + + p.add(b); + b.addActionListener(p); + f.add(p); + f.setSize(FrameWidth, FrameHeight); + f.setResizable(false); + f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + f.setVisible(true); + } +} diff --git a/Turtle-Interpreter/src/main/java/TurtleInterpreter/userInterface/Turtle.java b/Turtle-Interpreter/src/main/java/TurtleInterpreter/userInterface/Turtle.java new file mode 100644 index 0000000..9d85e3a --- /dev/null +++ b/Turtle-Interpreter/src/main/java/TurtleInterpreter/userInterface/Turtle.java @@ -0,0 +1,169 @@ +package TurtleInterpreter.userInterface; + +import javax.imageio.ImageIO; +import javax.swing.*; +import java.awt.*; +import java.awt.geom.AffineTransform; +import java.awt.image.AffineTransformOp; +import java.awt.image.BufferedImage; +import java.io.InputStream; + +// Need a separate class for Turtle to separate the logic/data from graphics and animation + +public class Turtle extends JComponent { + private String name; + private int LocX1, LocY1, LocX2, LocY2; + boolean writing; + boolean draw; + private Color color; + private double heading; + double angle; // rotation angle + private int delta; + private BufferedImage bufferedImage = null; // our PNG image of turtle + + public Turtle(String name, int x, int y) { + this.name = name; + LocX1 = 0; + LocY1 = 0; + LocX2 = x; + LocY2 = y; + angle = 0; // rotation angle + writing = true; // default pen down + color = Color.BLACK; // default color + heading = 90; // default facing north, 90 degrees + delta = 0; + draw = true; + + String imagePath = "Images/TurtleBlue.png"; + try (InputStream imageStream = getClass().getClassLoader().getResourceAsStream(imagePath)) { + if (imageStream == null) { + throw new IllegalArgumentException(imagePath + " not found."); + } + bufferedImage = ImageIO.read(imageStream); + } catch (Exception e) { + System.err.println(e.getMessage()); + } + } + + public String getName() { + return name; + } + + public boolean getdraw() { + return draw; + } + + public void setDraw(boolean b) { + draw = b; + } + + public BufferedImage getImage() { + return bufferedImage; + } + + public void setDelta(int d) { + delta = d; + } + + public int getDelta() { + return delta; + } + + public void rotateTurtle() { + AffineTransformOp op; + AffineTransform tx; + + float w = bufferedImage.getWidth(); + float h = bufferedImage.getHeight(); + + tx = new AffineTransform(); + tx.rotate(Math.toRadians(angle), w / 2, h / 2);// + + op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR); + bufferedImage = op.filter(bufferedImage, null); // (source, destination) + + } + + public boolean getWriting() { + + return writing; + } + + public void setLocX1(int x) { + LocX1 = x; + } + + public int getLocX1() { + return LocX1; + } + + public void setLocY1(int y) { + LocY1 = y; + } + + public int getLocY1() { + return LocY1; + } + + public void setLocX2(int x) { + LocX2 = x; + } + + public int getLocX2() { + return LocX2; + } + + public void setLocY2(int y) { + LocY2 = y; + } + + public int getLocY2() { + return LocY2; + } + + public void TurnLeft(double angle) { + this.angle = -angle; + heading += angle; + heading = heading % 360; + } + + public void TurnRight(double angle) { + this.angle = angle; + heading -= angle; + if (heading < 0) + heading = heading + 360; + } + + public void MoveForward(int delta, int FrameW, int FrameH) { + LocX2 = LocX1 + (int) (delta * Math.cos(Math.toRadians(heading))); + LocY2 = LocY1 + (int) (delta * Math.sin(Math.toRadians(heading))); + + if (LocX2 > FrameW) // Boundary checks and clipping + LocX2 = FrameW; + if (LocX2 < -FrameW) + LocX2 = -FrameW; + + if (LocY2 > FrameH) // Boundary checks and clipping + LocY2 = FrameH; + if (LocY2 < -FrameH) + LocY2 = -FrameH; + + } + + public void penDown() { + writing = true; + } + + public void penUp() { + writing = false; + } + + public void setColor(Color c) { + color = c; + } + + public Color getColor() { + return color; + } + +} \ No newline at end of file diff --git a/Images/TurtleBlue.png b/Turtle-Interpreter/src/main/resources/Images/TurtleBlue.png similarity index 100% rename from Images/TurtleBlue.png rename to Turtle-Interpreter/src/main/resources/Images/TurtleBlue.png diff --git a/Turtle-Interpreter/src/site/site.xml b/Turtle-Interpreter/src/site/site.xml new file mode 100644 index 0000000..0435b60 --- /dev/null +++ b/Turtle-Interpreter/src/site/site.xml @@ -0,0 +1,26 @@ + + + + + Turtle-Interpreter + https://maven.apache.org/images/apache-maven-project.png + https://www.apache.org/ + + + + https://maven.apache.org/images/maven-logo-black-on-white.png + https://maven.apache.org/ + + + + org.apache.maven.skins + maven-fluido-skin + 1.7 + + + + + + + \ No newline at end of file diff --git a/Turtle-Interpreter/src/test/java/TurtleInterpreter/AppTest.java b/Turtle-Interpreter/src/test/java/TurtleInterpreter/AppTest.java new file mode 100644 index 0000000..9611b6e --- /dev/null +++ b/Turtle-Interpreter/src/test/java/TurtleInterpreter/AppTest.java @@ -0,0 +1,34 @@ +package TurtleInterpreter; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase { + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest(String testName) { + super(testName); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() { + return new TestSuite(AppTest.class); + } + + /** + * Rigourous Test :-) + */ + public void testApp() { + assertTrue(true); + } +} diff --git a/src/Turtle.java b/src/Turtle.java deleted file mode 100644 index a866905..0000000 --- a/src/Turtle.java +++ /dev/null @@ -1,182 +0,0 @@ -import java.awt.Color; -import java.awt.geom.AffineTransform; -import java.awt.image.AffineTransformOp; -import java.awt.image.BufferedImage; -import java.io.File; -import javax.swing.*; - -import javax.imageio.ImageIO; - -// Need a separate class for Turtle to separate the logic/data from graphics and animation - -public class Turtle extends JComponent{ -private String name; -private int LocX1, LocY1, LocX2, LocY2; -boolean writing; -boolean draw; -private Color color; -private double heading; -double angle; // rotation angle -private int delta; -private BufferedImage bimg = null; // our PNG image of turtle - - -public Turtle(String name, int x, int y) { - this.name= name; - LocX1 = 0; - LocY1 = 0; - LocX2 = 0; - LocY2 = 0; - angle = 0; // rotation angle - writing = true; // default pen down - color = Color.BLACK; // default color - heading = 90; // default facing north, 90 degrees - delta = 0; - draw = true; - try { - bimg = ImageIO.read(new File("./Images/TurtleBlue.png")); - } catch (Exception e) { - e.printStackTrace(); - } -} - - -public String getName() -{ - return name; -} - -public boolean getdraw() -{ - return draw; -} - -public void setDraw(boolean b) -{ - draw = b; -} - -public BufferedImage getImage() -{ - return bimg; -} - - - -public void setDelta(int d) -{ - delta = d; -} - -public int getDelta() -{ - return delta; -} - -void rotateTurtle() -{ - AffineTransformOp op; - AffineTransform tx; - - int w= bimg.getWidth(); - int h= bimg.getHeight(); - - tx = new AffineTransform(); - tx.rotate(Math.toRadians(angle), w/2, h/2);// - - op = new AffineTransformOp(tx,AffineTransformOp.TYPE_BILINEAR); - bimg=op.filter(bimg,null); //(sourse,destination) -} - -public boolean getWriting() { - - return writing; -} - -public void setLocX1(int x) { - LocX1 = x; -} - -public int getLocX1() -{ - return LocX1; -} - - -public void setLocY1(int y) { - LocY1 = y; -} - -public int getLocY1() -{ - return LocY1; -} - -public void setLocX2(int x) { - LocX2 = x; -} - -public int getLocX2() -{ - return LocX2; -} - - -public void setLocY2(int y) { - LocY2 = y; -} - -public int getLocY2() -{ - return LocY2; -} - -public void TurnLeft(double angle) { - this.angle = -angle; - heading += angle; - heading = heading % 360; -} - -public void TurnRight(double angle) { - this.angle = angle; - heading -= angle; - if (heading < 0) heading = heading + 360; -} - -public void MoveForward(int delta, int FrameW, int FrameH) { - LocX2 = LocX1 + (int) (delta * Math.cos(Math.toRadians(heading))); - LocY2 = LocY1 + (int) (delta * Math.sin(Math.toRadians(heading))); - - if (LocX2 > FrameW) // Boundary checks and clipping - LocX2 = FrameW; - if (LocX2 < -FrameW) - LocX2 = -FrameW; - - if (LocY2 > FrameH) // Boundary checks and clipping - LocY2 = FrameH; - if (LocY2 < -FrameH) - LocY2 = -FrameH; - -} - -public void penDown() -{ - writing = true; -} - -public void penUp() -{ - writing = false; -} - -public void setColor(Color c) -{ - color = c; -} - -public Color getColor() -{ -return color; -} - -} \ No newline at end of file diff --git a/src/TurtleInterpreter.java b/src/TurtleInterpreter.java deleted file mode 100644 index 8056f26..0000000 --- a/src/TurtleInterpreter.java +++ /dev/null @@ -1,217 +0,0 @@ -/* Simple Turtle Interpreter - * @ M. Hamdan (m.hamdan@hw.ac.uk) - * Feb 2019 - * - */ - -import java.awt.Graphics; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.event.*; -import javax.swing.*; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.awt.image.BufferedImage; -import java.util.*; - -public class TurtleInterpreter extends JPanel implements ActionListener { - - private static final int FrameWidth = 800; - private static final int FrameHeight = 800; - private List TurtleList; - private BufferedImage image; - Scanner in = null; - boolean redraw; - // private JTextField console = new JTextField(); - - public TurtleInterpreter() { - //add(console); - TurtleList = new LinkedList(); - setPreferredSize(new Dimension(FrameHeight, FrameWidth)); - image = new BufferedImage(FrameWidth, FrameHeight, BufferedImage.TYPE_INT_RGB); - setMaximumSize(new Dimension(image.getWidth(), image.getHeight())); - redraw = false; - clear(); - } - - public void clear() { - - Graphics g = image.getGraphics(); - - g.setColor(Color.LIGHT_GRAY); - g.fillRect(0, 0, image.getWidth(), image.getHeight()); - } - - public void drawLine(Turtle t, int x1, int y1, int x2, int y2) { - - Graphics g = image.getGraphics(); - - g.setColor(t.getColor()); - g.drawLine(x1, y1, x2, y2); - } - - public void paintComponent(Graphics g) { - super.paintComponent(g); - // render the image on the panel. - g.drawImage(image, 0, 0, null); - if (TurtleList.size() != 0) { - for (Turtle t: TurtleList) { - g.drawImage(t.getImage(), (t.getLocX2()-15) + FrameWidth/2, -(t.getLocY2()+15) + FrameHeight/2, 30,30, this); - } - } - } - - -public void actionPerformed(ActionEvent e) - { - String s = e.getActionCommand(); - if (s.equals("Open File")) { // read input commands from a text file - JFileChooser chooser = new JFileChooser(); - if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { - File selectedFile = chooser.getSelectedFile(); - try { - in = new Scanner(selectedFile); - } catch (FileNotFoundException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - } - // start over, clear screen and initialise Turtle List - clear(); - TurtleList = new LinkedList(); - processfile(in); - } - } - -public Color ToColor(String s) - { // only five colors are allowed - if (s.equals("red") == true) return Color.RED; - else if (s.equals("blue") == true) return Color.BLUE; - else if (s.equals("cyan") == true) return Color.CYAN; - else if (s.equals("green") == true) return Color.GREEN; - else if (s.equals("orange") == true) return Color.ORANGE; - return Color.BLACK; //default - } - -void processfile(Scanner in) { - int lineNumber = 1; - boolean terminate = false; - boolean done; - final int MAX_LINES = 100; // maximum number of command lines - while (in.hasNextLine() && lineNumber= 4) { - JOptionPane.showMessageDialog(this, "Line : " + lineNumber + " : Invalid command, Program Terminated"); - - terminate = true; - } else { - Iterator itr = TurtleList.iterator(); - - switch (line[0]) { - case "turtle": - Turtle turtle = new Turtle(line[1], 0, 0); // New Turtle in Turtle coordinates at center - TurtleList.add(turtle); - redraw = true; - break; - - case "move": - done = false; - while (itr.hasNext() & !done) { - Turtle t = (Turtle) itr.next(); - String name = t.getName(); - if (name.equals(line[1])) { - done = true; - t.setDelta(Integer.parseInt(line[2])); - t.MoveForward(t.getDelta(), FrameWidth/2, FrameHeight/2); - if (t.getWriting() == true) { - drawLine(t, t.getLocX1() + FrameWidth/2, -t.getLocY1() + FrameHeight/2, t.getLocX2() + FrameWidth/2, -t.getLocY2() + FrameHeight/2); - } - t.setLocX1(t.getLocX2()); // update Turtle position - t.setLocY1(t.getLocY2()); - } - } - redraw = true; - break; - - case "left": - done = false; - while (itr.hasNext() & !done) { - Turtle t = (Turtle) itr.next(); - String name = t.getName(); - if (name.equals(line[1])) { - done = true; - t.TurnLeft(Math.abs(Double.parseDouble(line[2]))); - t.rotateTurtle(); - } - } - redraw = true; - break; - - case "right": - done = false; - while (itr.hasNext() & !done) { - Turtle t = (Turtle) itr.next(); - String name = t.getName(); - if (name.equals(line[1])) { - done = true; - t.TurnRight(Math.abs(Double.parseDouble(line[2]))); - t.rotateTurtle(); - } - } - redraw = true; - break; - - case "pen": - done = false; - while (itr.hasNext() & !done) { - Turtle t = (Turtle) itr.next(); - String name = t.getName(); - if (name.equals(line[1]) == true) { - done = true; - if ((line[2]).equals("up") == true) - t.penUp(); - else if ((line[2]).equals("down") == true) - t.penDown(); - } - } - redraw = false; - break; - - case "colour": - done = false; - while (itr.hasNext() & !done) { - Turtle t = (Turtle) itr.next(); - String name = t.getName(); - if (name.equals(line[1])) { - done = true; - t.setColor(ToColor(line[2])); // change color - } - } - redraw = false; - break; - - default: - JOptionPane.showMessageDialog(this, "Line " + lineNumber + " : Invalid command, Program Terminated"); - terminate = true; - } - } - - if (redraw) repaint(); - lineNumber++; - } - } - -public static void main(String args[]) throws IOException { - JFrame f = new JFrame(); - TurtleInterpreter p = new TurtleInterpreter(); - JButton b = new JButton("Open File"); - p.add(b); - b.addActionListener(p); - f.add(p); - f.setVisible(true); - f.setSize(FrameHeight,FrameWidth); - f.setResizable(false); - f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - } -} \ No newline at end of file