diff --git a/pom.xml b/pom.xml
index 387dbbab8dc2b78f6cf7919d8c1c3afbbfae99ee..5292ef3be7574e6eb2c66cf9be1175fba38d5387 100644
--- a/pom.xml
+++ b/pom.xml
@@ -29,6 +29,11 @@
     </properties>
 
     <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-thymeleaf</artifactId>
+        </dependency>
+
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
diff --git a/src/main/java/sk/tuke/gamestudio/entity/Score.java b/src/main/java/sk/tuke/gamestudio/entity/Score.java
index b707a5fc07a296f87b55bdf533c3e57da1a7732c..311070ecd98b4c65d483cf43345c584deae7390a 100644
--- a/src/main/java/sk/tuke/gamestudio/entity/Score.java
+++ b/src/main/java/sk/tuke/gamestudio/entity/Score.java
@@ -9,7 +9,7 @@ import java.util.Date;
 import java.util.Objects;
 
 @Entity
-@NamedQuery(name = "Score.selectToScores", query = "select s from Score s where s.game=:game order by s.points desc")
+@NamedQuery(name = "Score.selectTopScores", query = "select s from Score s where s.game=:game order by s.points desc")
 public class Score implements Comparable<Score>, Serializable {
     @Id
     @GeneratedValue
diff --git a/src/main/java/sk/tuke/gamestudio/server/controller/MinesController.java b/src/main/java/sk/tuke/gamestudio/server/controller/MinesController.java
new file mode 100644
index 0000000000000000000000000000000000000000..d4ff56f04a75f699170bebcecaa6a8ec817d7613
--- /dev/null
+++ b/src/main/java/sk/tuke/gamestudio/server/controller/MinesController.java
@@ -0,0 +1,129 @@
+package sk.tuke.gamestudio.server.controller;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.context.WebApplicationContext;
+import sk.tuke.gamestudio.entity.Score;
+import sk.tuke.gamestudio.game.mines.core.Clue;
+import sk.tuke.gamestudio.game.mines.core.Field;
+import sk.tuke.gamestudio.game.mines.core.GameState;
+import sk.tuke.gamestudio.game.mines.core.Tile;
+import sk.tuke.gamestudio.service.ScoreService;
+
+import java.util.Date;
+
+@Controller
+@Scope(WebApplicationContext.SCOPE_SESSION)
+@RequestMapping("/mines")
+public class MinesController {
+    @Autowired
+    private ScoreService scoreService;
+
+    @Autowired
+    private UserController userController;
+
+    private Field field;
+
+    private boolean marking;
+
+    @RequestMapping
+    public String mines(String row, String column, Model model) {
+        if (field == null)
+            newGame();
+        try {
+            if (marking)
+                field.markTile(Integer.parseInt(row), Integer.parseInt(column));
+            else {
+                if (field.getState() == GameState.PLAYING) {
+                    field.openTile(Integer.parseInt(row), Integer.parseInt(column));
+                    if (userController.isLogged() && field.getState() == GameState.SOLVED) {
+                        scoreService.addScore(new Score(
+                                userController.getLoggedUser(),
+                                field.getScore(),
+                                "mines",
+                                new Date()
+                        ));
+                    }
+                }
+            }
+        } catch (NumberFormatException e) {
+            //Jaro: Zle poslane nic sa nedeje
+            e.printStackTrace();
+        }
+        prepareModel(model);
+        return "mines";
+    }
+
+    @RequestMapping("/new")
+    public String newGame(Model model) {
+        newGame();
+        prepareModel(model);
+        return "mines";
+    }
+
+    @RequestMapping("/mark")
+    public String changeMark(Model model) {
+        marking = !marking;
+        prepareModel(model);
+        return "mines";
+    }
+
+    public boolean isMarking() {
+        return marking;
+    }
+
+    public GameState getGameState() {
+        return field.getState();
+    }
+
+    //Tento pristup sice nie je idealny, ale pre zaciatok je najjednoduchsi
+    public String getHtmlField() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("<table class='field'>\n");
+        for (int row = 0; row < field.getRowCount(); row++) {
+            sb.append("<tr>\n");
+            for (int column = 0; column < field.getColumnCount(); column++) {
+                Tile tile = field.getTile(row, column);
+                sb.append("<td>\n");
+                if (field.equals(this.field))
+                    sb.append("<a href='" +
+                            String.format("/mines?row=%s&column=%s", row, column)
+                            + "'>\n");
+                sb.append("<img src='/images/mines/" + getImageName(tile) + ".png'>");
+                if (field.equals(this.field))
+                    sb.append("</a>\n");
+                sb.append("</td>\n");
+            }
+            sb.append("</tr>\n");
+        }
+        sb.append("</table>\n");
+
+        return sb.toString();
+    }
+
+    private String getImageName(Tile tile) {
+        switch (tile.getState()) {
+            case CLOSED:
+                return "closed";
+            case MARKED:
+                return "marked";
+            case OPEN:
+                if (tile instanceof Clue)
+                    return "open" + ((Clue) tile).getValue();
+                else
+                    return "mine";
+        }
+        throw new IllegalArgumentException("State is not supported " + tile.getState());
+    }
+
+    private void prepareModel(Model model) {
+        model.addAttribute("scores", scoreService.getTopScores("mines"));
+    }
+
+    private void newGame() {
+        field = new Field(9, 9, 2);
+    }
+}
diff --git a/src/main/java/sk/tuke/gamestudio/server/controller/UserController.java b/src/main/java/sk/tuke/gamestudio/server/controller/UserController.java
new file mode 100644
index 0000000000000000000000000000000000000000..9d07bb022b6afc18387f40fed88aff4099fa09d8
--- /dev/null
+++ b/src/main/java/sk/tuke/gamestudio/server/controller/UserController.java
@@ -0,0 +1,39 @@
+package sk.tuke.gamestudio.server.controller;
+
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.context.WebApplicationContext;
+
+@Controller
+@Scope(WebApplicationContext.SCOPE_SESSION)
+@RequestMapping("/user")
+public class UserController {
+    private String loggedUser;
+
+    @RequestMapping("/")
+    public String index() {
+        return "index";
+    }
+
+    @RequestMapping("/login")
+    public String login(String login, Model model) {
+        loggedUser = login;
+        return "redirect:/";
+    }
+
+    @RequestMapping("/logout")
+    public String logout(Model model) {
+        loggedUser = null;
+        return "redirect:/";
+    }
+
+    public String getLoggedUser() {
+        return loggedUser;
+    }
+
+    public boolean isLogged() {
+        return loggedUser != null;
+    }
+}
diff --git a/src/main/java/sk/tuke/gamestudio/service/ScoreServiceJPA.java b/src/main/java/sk/tuke/gamestudio/service/ScoreServiceJPA.java
index 016c985947ab373391073715c091ad17bc5c52a1..b60f3e83e5add3a1b4f6c585b1d1f7688c7ed35b 100644
--- a/src/main/java/sk/tuke/gamestudio/service/ScoreServiceJPA.java
+++ b/src/main/java/sk/tuke/gamestudio/service/ScoreServiceJPA.java
@@ -19,7 +19,7 @@ public class ScoreServiceJPA implements ScoreService {
 
     @Override
     public List<Score> getTopScores(String gameName) {
-        return entityManager.createNamedQuery("Score.selectToScores")
+        return entityManager.createNamedQuery("Score.selectTopScores")
                 .setParameter("game", gameName)
                 .setMaxResults(10).getResultList();
     }
diff --git a/src/main/resources/static/css/stylesheet.css b/src/main/resources/static/css/stylesheet.css
new file mode 100644
index 0000000000000000000000000000000000000000..5462bfd59a33f73f4cc49015a9b94893afe2d092
--- /dev/null
+++ b/src/main/resources/static/css/stylesheet.css
@@ -0,0 +1,131 @@
+/**
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ *
+ * You may not modify, use, reproduce, or distribute this software except in
+ * compliance with  the terms of the License at:
+ * http://java.net/projects/javaeetutorial/pages/BerkeleyLicense
+ */
+#top {
+    position: relative;
+    background-color: #036fab;
+    color: white;
+    padding: 5px;
+    margin: 0px 0px 10px 0px;
+}
+body {
+    background-color: #ffffff;
+    font-size: 12px;
+    font-family: Verdana, "Verdana CE",  Arial, "Arial CE", "Helvetica CE", sans-serif;
+    color: #000000;  
+    margin: 10px;
+}
+
+h1 {
+    font-family: Arial, "Arial CE", "Helvetica CE", sans-serif;
+    font-size:  28px;
+    font-weight: bold;
+    margin: 0px;
+    padding: 0px;
+    color: #045491;
+}
+
+h2 {
+    font-family: Arial, "Arial CE", "Helvetica CE", sans-serif;
+    font-size:  16px;
+    font-weight: bold;
+    margin: 0px;
+    padding: 0px;
+    color: #045491;
+}
+
+a:link, a:visited {
+  color: #045491;
+  font-weight : bold;
+  text-decoration: none;
+}
+
+a:link:hover, a:visited:hover  {
+  color: #045491;
+  font-weight : bold;
+  text-decoration : underline;
+}
+
+.center_content {
+    position: relative;
+    background-color: #e0e0e0;
+    padding: 5px;
+}
+
+.error-message {
+  color: #d20005;
+  font-family: 'New Century Schoolbook', serif;
+  font-style: oblique;
+  text-decoration: overline;
+}
+
+.list-background { 
+  background-color: #ffffff;
+  font-family: sans-serif;
+  font-size: 12pt;
+  padding: 10px;
+  width: 100%;
+}
+
+.list-caption {
+  font-family: sans-serif;
+  font-size: 12pt;
+  font-weight: bold;
+  padding: 5px;
+  text-align: center;
+}
+
+.list-column-center { 
+  text-align: center;
+  width: 15%;
+}
+
+.list-column-left {
+  text-align: left;
+  width: 70%;
+}
+
+.list-column-right {
+  text-align: right;
+  width: 15%;
+}
+
+.list-footer { 
+  background-color: #A5A5A5;
+  color: #000000;
+  font-weight: bold;
+  text-align: center;
+}
+
+.list-header { 
+  background-color: #ffffff;
+  color: #000000;
+  text-align: center;
+}
+
+.list-row-even { 
+}
+
+.list-row-odd { 
+  background-color: #eaf1f8;
+}
+
+.special-offer { 
+  font-family: sans-serif;
+  font-size: 12pt;
+  text-align: left;
+  padding: 10px;
+}
+
+table {
+    border-collapse: collapse;
+    border: none;
+}
+
+td {
+    padding: 0;
+}
\ No newline at end of file
diff --git a/src/main/resources/static/images/mines/closed.png b/src/main/resources/static/images/mines/closed.png
new file mode 100644
index 0000000000000000000000000000000000000000..7f233bfdccf0b1d65488a0feef1a0e64d7392eb5
Binary files /dev/null and b/src/main/resources/static/images/mines/closed.png differ
diff --git a/src/main/resources/static/images/mines/marked.png b/src/main/resources/static/images/mines/marked.png
new file mode 100644
index 0000000000000000000000000000000000000000..ffcb92b69c266ec94c4bb47a14926a3318aea51b
Binary files /dev/null and b/src/main/resources/static/images/mines/marked.png differ
diff --git a/src/main/resources/static/images/mines/mine.png b/src/main/resources/static/images/mines/mine.png
new file mode 100644
index 0000000000000000000000000000000000000000..b82db4720dc70a20b6b145d748bf830e87c10263
Binary files /dev/null and b/src/main/resources/static/images/mines/mine.png differ
diff --git a/src/main/resources/static/images/mines/open0.png b/src/main/resources/static/images/mines/open0.png
new file mode 100644
index 0000000000000000000000000000000000000000..7c648fc494886f27d833b13558e4dc49e952f332
Binary files /dev/null and b/src/main/resources/static/images/mines/open0.png differ
diff --git a/src/main/resources/static/images/mines/open1.png b/src/main/resources/static/images/mines/open1.png
new file mode 100644
index 0000000000000000000000000000000000000000..80cfc457a2cb0a87a13f232c6709801d4fac86ee
Binary files /dev/null and b/src/main/resources/static/images/mines/open1.png differ
diff --git a/src/main/resources/static/images/mines/open2.png b/src/main/resources/static/images/mines/open2.png
new file mode 100644
index 0000000000000000000000000000000000000000..42d5290ac750f35ee1dbd9e92d0de38f391a0399
Binary files /dev/null and b/src/main/resources/static/images/mines/open2.png differ
diff --git a/src/main/resources/static/images/mines/open3.png b/src/main/resources/static/images/mines/open3.png
new file mode 100644
index 0000000000000000000000000000000000000000..c8c3441a3df905c4afdb99b2ea7a9fad04daac79
Binary files /dev/null and b/src/main/resources/static/images/mines/open3.png differ
diff --git a/src/main/resources/static/images/mines/open4.png b/src/main/resources/static/images/mines/open4.png
new file mode 100644
index 0000000000000000000000000000000000000000..a2c6b9e0c4109bad740436f4a8d4ee80ec58e54b
Binary files /dev/null and b/src/main/resources/static/images/mines/open4.png differ
diff --git a/src/main/resources/static/images/mines/open5.png b/src/main/resources/static/images/mines/open5.png
new file mode 100644
index 0000000000000000000000000000000000000000..e136bf9d8716e91c0b61296cfa7fac0df94092a6
Binary files /dev/null and b/src/main/resources/static/images/mines/open5.png differ
diff --git a/src/main/resources/static/images/mines/open6.png b/src/main/resources/static/images/mines/open6.png
new file mode 100644
index 0000000000000000000000000000000000000000..67616304aaed076be9c77c296c11252a5fdee839
Binary files /dev/null and b/src/main/resources/static/images/mines/open6.png differ
diff --git a/src/main/resources/static/images/mines/open7.png b/src/main/resources/static/images/mines/open7.png
new file mode 100644
index 0000000000000000000000000000000000000000..d13368a9d487b8266a291d541b9af44820dcb3cc
Binary files /dev/null and b/src/main/resources/static/images/mines/open7.png differ
diff --git a/src/main/resources/static/images/mines/open8.png b/src/main/resources/static/images/mines/open8.png
new file mode 100644
index 0000000000000000000000000000000000000000..ab1729dba483a192eff1ba808cd56fa2801786a9
Binary files /dev/null and b/src/main/resources/static/images/mines/open8.png differ
diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..397ae8c2d6a1882306927dcda2971ec0666919ff
--- /dev/null
+++ b/src/main/resources/templates/index.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html xmlns:th="http://www.thymeleaf.org">
+<head>
+    <title>Gamestudio</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+    <link rel="stylesheet" href="/css/stylesheet.css"/>
+</head>
+<body>
+<h1>Welcome to Gamestudio!</h1>
+
+<div th:if="${@userController.logged}">
+    You are logged as <span th:text="${@userController.loggedUser}"/>.
+    <a href="/user/logout">Logout</a>
+</div>
+
+<div th:if="${not @userController.logged}">
+    <form method="get" action="/user/login">
+        Login: <input name="login" type="text"/>
+        <input type="submit" value="Login">
+    </form>
+</div>
+
+<div>
+    Our favorite games:
+    <ul>
+        <li><a href="/mines">Minesweeper</a></li>
+    </ul>
+</div>
+</body>
+</html>
diff --git a/src/main/resources/templates/mines.html b/src/main/resources/templates/mines.html
new file mode 100644
index 0000000000000000000000000000000000000000..d45941f68b678e651044b14172f9bc139119dff5
--- /dev/null
+++ b/src/main/resources/templates/mines.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html xmlns:th="http://www.thymeleaf.org">
+<head>
+    <title>Minesweeper</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+    <link rel="stylesheet" href="/css/stylesheet.css"/>
+</head>
+<body>
+
+<h1>Welcome to <a href="/">Gamestudio</a>!</h1>
+<h1>Minesweeper</h1>
+
+<a href="/mines/new">New game</a><br/>
+<a href="/mines/mark" th:text='${@minesController.marking ? "Mark" : "Open"}'/><br/>
+
+<div th:text="${@minesController.gameState}"/>
+<div th:utext="${@minesController.htmlField}"/>
+
+<h2>Scores</h2>
+<ol>
+    <li th:each="score : ${scores}">
+        <span th:text="${score.player}"/>
+        <span th:text="${score.points}"/>
+    </li>
+</ol>
+
+</body>
+</html>