diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..082896b1a32f37c562f3b2c09bbab8b3ad6b7e2d
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Encoding">
+    <file url="file://$PROJECT_DIR$/res/IO/environment.csv" charset="GBK" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index c0572aa051d2673266994b9b207ed32cfbc44f9d..aa972b5370966522021bf2d64c67b87416a07fb6 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -7,5 +7,7 @@
       </list>
     </option>
   </component>
-  <component name="ProjectRootManager" version="2" languageLevel="JDK_14" project-jdk-name="14" project-jdk-type="JavaSDK" />
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_15" default="true" project-jdk-name="openjdk-15" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/out" />
+  </component>
 </project>
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index 58125d335058c2e294563929b453534bb79cb1d0..94a25f7f4cb416c083d265558da75d457237d671 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -1,8 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
   <component name="VcsDirectoryMappings">
-    <mapping directory="$USER_HOME$" vcs="Git" />
-    <mapping directory="$PROJECT_DIR$/../../.." vcs="Git" />
     <mapping directory="$PROJECT_DIR$" vcs="Git" />
   </component>
 </project>
\ No newline at end of file
diff --git a/bagel.iml b/bagel.iml
index 5528a8c1e3d3839305551618bb67906e16d64071..bb67b4e1de0124283d12a2911f01ac2b569e3b23 100644
--- a/bagel.iml
+++ b/bagel.iml
@@ -4,6 +4,7 @@
     <output url="file://$MODULE_DIR$/target/classes" />
     <output-test url="file://$MODULE_DIR$/target/test-classes" />
     <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/res" type="java-resource" />
       <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
       <excludeFolder url="file://$MODULE_DIR$/target" />
     </content>
diff --git a/res/IO/environment.csv b/res/IO/environment.csv
index 79fea88a9ab126ee1e10f0828bcff2047ec182f7..99f4061217923093bbeec74f5304f5a141c714f1 100644
--- a/res/IO/environment.csv
+++ b/res/IO/environment.csv
@@ -1,3 +1,3 @@
-Player,650,100,2
+Player,650,100,2
 Zombie,300,200
 Sandwich,500,400
\ No newline at end of file
diff --git a/src/Energy.java b/src/Energy.java
new file mode 100644
index 0000000000000000000000000000000000000000..3278b00592500739c67893d19cd4102770e2521b
--- /dev/null
+++ b/src/Energy.java
@@ -0,0 +1,15 @@
+public class Energy {
+    private int value;
+
+    protected Energy(int energy) {
+        this.value = energy;
+    }
+
+    protected int getEnergy() {
+        return this.value;
+    }
+
+    protected void add(int amount) {
+        this.value += amount;
+    }
+}
diff --git a/src/Entity.java b/src/Entity.java
new file mode 100644
index 0000000000000000000000000000000000000000..8d6968f703ad59ee00c2b112799ad775135c24a8
--- /dev/null
+++ b/src/Entity.java
@@ -0,0 +1,32 @@
+import bagel.Image;
+import bagel.util.Point;
+
+public abstract class Entity extends Image {
+    private double x, y;
+
+    protected Entity(String filename, double x, double y) {
+        super(filename);
+        this.x = x;
+        this.y = y;
+    }
+
+    protected Point getPosition() {
+        return new Point(this.x, this.y);
+    }
+
+    protected double getX() {
+        return x;
+    }
+
+    protected void setX(double x) {
+        this.x = x;
+    }
+
+    protected double getY() {
+        return y;
+    }
+
+    protected void setY(double y) {
+        this.y = y;
+    }
+}
\ No newline at end of file
diff --git a/src/Player.java b/src/Player.java
new file mode 100644
index 0000000000000000000000000000000000000000..1161b2e4218250ae12e0686b179b4011d8d7f34c
--- /dev/null
+++ b/src/Player.java
@@ -0,0 +1,22 @@
+import bagel.Window;
+
+public class Player extends Entity{
+    private Energy energy;
+
+    protected Player(String filename, double x, double y, int energy) {
+        super(filename, x, y);
+        this.energy = new Energy(energy);
+    }
+
+    protected int getEnergy() {
+        return energy.getEnergy();
+    }
+
+    protected void updateEnergy(int amount) {
+        energy.add(amount);
+    }
+
+    protected void eat(Sandwich sandwich) {
+        sandwich.eaten();
+    }
+}
diff --git a/src/Sandwich.java b/src/Sandwich.java
new file mode 100644
index 0000000000000000000000000000000000000000..52fc084c511c741073eac9b04905bbe19fc5718f
--- /dev/null
+++ b/src/Sandwich.java
@@ -0,0 +1,15 @@
+public class Sandwich extends Entity{
+    private boolean eaten = false;
+
+    protected Sandwich(String filename, double x, double y) {
+        super(filename, x, y);
+    }
+
+    protected void eaten() {
+        this.eaten = true;
+    }
+
+    protected boolean isEaten() {
+        return eaten;
+    }
+}
\ No newline at end of file
diff --git a/src/ShadowTreasure.java b/src/ShadowTreasure.java
index f9c1058a0a5a1a7fc8d5398d931b6ba23b690d34..1f01ca33beac48f412f4b725bb36d2814fc65395 100644
--- a/src/ShadowTreasure.java
+++ b/src/ShadowTreasure.java
@@ -1,15 +1,22 @@
 import bagel.*;
+import bagel.util.Vector2;
 
-import java.io.BufferedReader;
-import java.io.FileReader;
-import java.io.IOException;
+import java.io.*;
 import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Scanner;
 
 
 /**
  * An example Bagel game.
  */
 public class ShadowTreasure extends AbstractGame {
+    private final Image background;
+    private Player player;
+    private Zombie zombie;
+    private Sandwich sandwich;
+    private final Font energyLevel = new Font("res/font/DejaVuSans-Bold.ttf", 20);
 
     // for rounding double number; use this to print the location of the player
     private static DecimalFormat df = new DecimalFormat("0.00");
@@ -17,17 +24,41 @@ public class ShadowTreasure extends AbstractGame {
     public static void printInfo(double x, double y, int e) {
         System.out.println(df.format(x) + "," + df.format(y) + "," + e);
     }
-    
+
     public ShadowTreasure() throws IOException {
         this.loadEnvironment("res/IO/environment.csv");
         // Add code to initialize other attributes as needed
+        background = new Image("res/images/background.png");
     }
 
     /**
      * Load from input file
      */
-    private void loadEnvironment(String filename){
+    private void loadEnvironment(String filename) throws FileNotFoundException {
         // Code here to read from the file and set up the environment
+        Scanner scan = new Scanner(new File(filename));
+        String[] row;
+        while (scan.hasNext()) {
+            row = scan.next().split(",",4);
+            switch (row[0]) {
+                case "Player" :
+                    this.player = new Player("res/images/player.png",
+                                            Double.parseDouble(row[1]),
+                                            Double.parseDouble(row[2]),
+                                            Integer.parseInt(row[3]));
+                    break;
+                case "Zombie" :
+                    this.zombie = new Zombie("res/images/zombie.png",
+                                             Double.parseDouble(row[1]),
+                                             Double.parseDouble(row[2]));
+                    break;
+                case "Sandwich" :
+                    this.sandwich = new Sandwich("res/images/sandwich.png",
+                                                 Double.parseDouble(row[1]),
+                                                 Double.parseDouble(row[2]));
+                    break;
+            }
+        }
     }
 
     /**
@@ -36,6 +67,47 @@ public class ShadowTreasure extends AbstractGame {
     @Override
     public void update(Input input) {
         // Logic to update the game, as per specification must go here
+        double speed = 10, x, y;
+        double playerToZombie = player.getPosition().distanceTo(zombie.getPosition());
+        double playerToSandwich = player.getPosition().distanceTo(sandwich.getPosition());
+        double distDiff = playerToZombie - playerToSandwich;
+        int energy = player.getEnergy();
+        Vector2 direction;
+
+        if (input.wasPressed(Keys.ESCAPE)) {
+            Window.close();
+
+        } else if (playerToZombie <= 50) {
+            player.updateEnergy(-3);
+            Window.close();          // terminate game if player meets zombie
+
+        } else if (playerToSandwich <= 50 && !sandwich.isEaten()) {
+            player.eat(sandwich);
+            player.updateEnergy(+5);
+
+        } else if (sandwich.isEaten() || (distDiff < 0 && energy >= 3)) {
+            // player move to zombie
+            direction = zombie.getPosition().asVector().sub(player.getPosition().asVector());
+            direction = direction.normalised();
+            player.setX(player.getX() + speed * direction.x);
+            player.setY(player.getY() + speed * direction.y);
+        } else if (distDiff >= 0 || player.getEnergy() < 3) {
+            // player move to sandwich
+            direction = sandwich.getPosition().asVector().sub(player.getPosition().asVector());
+            direction = direction.normalised();
+            player.setX(player.getX() + speed * direction.x);
+            player.setY(player.getY() + speed * direction.y);
+        }
+
+        background.draw(Window.getWidth() / 2.0, Window.getHeight() / 2.0);
+        energyLevel.drawString("energy: " + Integer.toString(player.getEnergy()),
+                                20, 760);
+        player.draw(player.getX(), player.getY());
+        zombie.draw(zombie.getX(), zombie.getY());
+        if (!sandwich.isEaten()) {
+            sandwich.draw(sandwich.getX(), sandwich.getY());
+        }
+
     }
 
 
diff --git a/src/Zombie.java b/src/Zombie.java
new file mode 100644
index 0000000000000000000000000000000000000000..43246a11a760bf078266310ff646140ed1a4b8bd
--- /dev/null
+++ b/src/Zombie.java
@@ -0,0 +1,5 @@
+public class Zombie extends Entity{
+    protected Zombie(String filename, double x, double y) {
+        super(filename, x, y);
+    }
+}
\ No newline at end of file
diff --git a/target/classes/Energy.class b/target/classes/Energy.class
new file mode 100644
index 0000000000000000000000000000000000000000..cd528fe588963f4fbbefc7ad9c0ed8e1b93183d5
Binary files /dev/null and b/target/classes/Energy.class differ
diff --git a/target/classes/Entity.class b/target/classes/Entity.class
new file mode 100644
index 0000000000000000000000000000000000000000..b659342fa1efcd1e7edc6f3b2adbeba8372fc7fa
Binary files /dev/null and b/target/classes/Entity.class differ
diff --git a/target/classes/IO/environment.csv b/target/classes/IO/environment.csv
new file mode 100644
index 0000000000000000000000000000000000000000..99f4061217923093bbeec74f5304f5a141c714f1
--- /dev/null
+++ b/target/classes/IO/environment.csv
@@ -0,0 +1,3 @@
+Player,650,100,2
+Zombie,300,200
+Sandwich,500,400
\ No newline at end of file
diff --git a/target/classes/Player.class b/target/classes/Player.class
new file mode 100644
index 0000000000000000000000000000000000000000..f73a38e0a46071064afac16b858a2daf947e5336
Binary files /dev/null and b/target/classes/Player.class differ
diff --git a/target/classes/Sandwich.class b/target/classes/Sandwich.class
new file mode 100644
index 0000000000000000000000000000000000000000..152212ccb1361ab8e959bac9157f5b6758698d39
Binary files /dev/null and b/target/classes/Sandwich.class differ
diff --git a/target/classes/ShadowTreasure.class b/target/classes/ShadowTreasure.class
new file mode 100644
index 0000000000000000000000000000000000000000..9302a6e71f79cb6282827b663cb98188e068aee7
Binary files /dev/null and b/target/classes/ShadowTreasure.class differ
diff --git a/target/classes/Zombie.class b/target/classes/Zombie.class
new file mode 100644
index 0000000000000000000000000000000000000000..171b44e2235df4233e585060cbd3ffc7bafd4d4d
Binary files /dev/null and b/target/classes/Zombie.class differ
diff --git a/target/classes/font/DejaVuSans-Bold.ttf b/target/classes/font/DejaVuSans-Bold.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..c0d8e5e462df7f268efba09f6931e37daad151e1
Binary files /dev/null and b/target/classes/font/DejaVuSans-Bold.ttf differ
diff --git a/target/classes/images/background.png b/target/classes/images/background.png
new file mode 100644
index 0000000000000000000000000000000000000000..a6601996a24eebf1b568ad8e05d2e137a030b52e
Binary files /dev/null and b/target/classes/images/background.png differ
diff --git a/target/classes/images/player.png b/target/classes/images/player.png
new file mode 100644
index 0000000000000000000000000000000000000000..103a2ff1c64ccd5bf18b9ef8b2ca444dbdf204d1
Binary files /dev/null and b/target/classes/images/player.png differ
diff --git a/target/classes/images/sandwich.png b/target/classes/images/sandwich.png
new file mode 100644
index 0000000000000000000000000000000000000000..87e12ec3db6704914262fd359822407fb9ecd172
Binary files /dev/null and b/target/classes/images/sandwich.png differ
diff --git a/target/classes/images/zombie.png b/target/classes/images/zombie.png
new file mode 100644
index 0000000000000000000000000000000000000000..41519c41828d76f5cdfbd9493025d3867347d926
Binary files /dev/null and b/target/classes/images/zombie.png differ