diff --git a/src/Player.java b/src/Player.java
index dbbb79fb78d67a4aa03dd2438ac49821819a4c92..40de50a0afe2cfaaeba03a223a8994e94b2d2e68 100644
--- a/src/Player.java
+++ b/src/Player.java
@@ -64,6 +64,16 @@ public class Player {
         Y = (int) p.y;
     }
 
+    public int IntoHole() {
+        /*Life handling and system output for players falling into sinkholes*/
+        Life -= 30;
+        if (Life < 0) {
+            Life = 0;
+        }
+        System.out.println("Sinkhole inflicts 30 damage points on Fae.  Fae's current health:  " + Life + "/" + LIFE_MAX);
+        return Life;
+    }
+
     public Rectangle GetRectangle() {
         /*Get Rectangle of player*/
         return Img.getBoundingBoxAt(GetPos());
diff --git a/src/ShadowDimension.java b/src/ShadowDimension.java
index f4be1ddcfad2ebe5658a29cc420d5255b8b4a2cc..a865494f356a1cedd6e1455c787c18b4fff39ca0 100644
--- a/src/ShadowDimension.java
+++ b/src/ShadowDimension.java
@@ -86,6 +86,25 @@ public class ShadowDimension extends AbstractGame {
         }
     }
 
+    private void GameOver(boolean win) {
+        /*Modify the game state at the end of the game*/
+        if (win) {
+            game_state = 255;
+        } else {
+            game_state = 254;
+        }
+
+    }
+
+    private void InHoleCheck() {
+        /*Check if the player falls into a sinkhole.
+        If the player runs out of health, the game fails.*/
+        if (hole.InHoldCheck(player.GetRectangle())) {
+            if (player.IntoHole() <= 0) {
+                GameOver(false);
+            }
+        }
+    }
 
     private void ImgRefresh() {
         /*Draw the world, walls, sinkholes, players.*/
@@ -99,6 +118,7 @@ public class ShadowDimension extends AbstractGame {
         /*Init for new turn.*/
         player.Clear();
         wall.Clear();
+        hole.Clear();
     }
 
     /**
@@ -111,6 +131,8 @@ public class ShadowDimension extends AbstractGame {
          * 0:Init and show welcom page
          * 1:First show play page
          * 2:Play
+         * 254:Show failure page
+         * 255:Show win page
          * */
         switch (game_state) {
             case 0: {
@@ -159,10 +181,53 @@ public class ShadowDimension extends AbstractGame {
                     player.SetPos(old_p);
                 }
 
+                /*Win check*/
+                if ((player.X >= 950) && (player.Y >= 670)) {
+                    GameOver(true);
+                }
+
+                /*Check if the player has fallen into a sinkhole*/
+                InHoleCheck();
+				
 				/*Show image*/
                 ImgRefresh();
                 break;
             }
+
+            case 254: {
+                /*Draw the failure of the game.*/
+                Drawing.drawRectangle(0, 0, 1024, 768,
+                        new Colour(103.0 / 256, 153.0 / 256, 231.0 / 256));
+                title.drawString("GAME OVER!", (Window.getWidth() - title.getWidth("GAME OVER!")) / 2,
+                        Window.getHeight() / 2);
+
+                /*Press the space key to back welcome page.*/
+                if (input.wasPressed(Keys.SPACE)) {
+                    game_state = 0;
+                    readCSV();
+                }
+                break;
+            }
+
+            case 255: {
+                /*Draw a winning picture of the game.*/
+                Drawing.drawRectangle(0, 0, 1024, 768,
+                        new Colour(103.0 / 256, 153.0 / 256, 231.0 / 256));
+                title.drawString("CONGRATULATIONS!",
+                        (Window.getWidth() - title.getWidth("CONGRATULATIONS!")) / 2,
+                        Window.getHeight() / 2);
+
+                /*Press the space key to back welcome page.*/
+                if (input.wasPressed(Keys.SPACE)) {
+                    game_state = 0;
+                    readCSV();
+                }
+                break;
+            }
+            default: {
+
+                break;
+            }
         }
 
         /*Game exit*/
diff --git a/src/Sinkhole.java b/src/Sinkhole.java
index d8b4bcacc01e675045ec8c131a85682a0166f37a..c129e97339eaf113e622bfa23849cb752c044190 100644
--- a/src/Sinkhole.java
+++ b/src/Sinkhole.java
@@ -16,19 +16,43 @@ import java.util.ArrayList;
 public class Sinkhole {
     private final Image Img = new Image("res/sinkhole.png");
     private final ArrayList Pos = new ArrayList();
+    private final ArrayList rect = new ArrayList();
 
     public void Sinkhole() {
     }
 
+    public void Clear() {
+        /*Clear all position and Rectangle list*/
+        Pos.clear();
+        rect.clear();
+    }
 
     public void Update() {
+        /*Sinkholes will decrease after the player crashes,
+        so you need to clear the boundary record and re-add the ones that exist.*/
+        rect.clear();
+
         /*Gets all the hole position of the ArrayList and draw*/
         for (int i = 0; i < Pos.size(); i++) {
             bagel.util.Point p = (bagel.util.Point) Pos.get(i);
             Img.drawFromTopLeft(p.x, p.y);
+
+            /*Record all sinkhole Rectangle for overlaps checking.*/
+            rect.add(Img.getBoundingBoxAt(p));
         }
     }
 
+    public boolean InHoldCheck(Rectangle r) {
+        /*Check that each hole overlaps the r(player) position*/
+        for (int i = 0; i < Pos.size(); i++) {
+            if (r.intersects((Rectangle) rect.get(i))) {
+                /*Remove sinkholes that players fall into.*/
+                Pos.remove(i);
+                return true;
+            }
+        }
+        return false;
+    }
 
     public void Add(int x, int y) {
         /*Add the hole position to arraylist*/