diff --git a/src/main/java/com/small/tictactoe/App.java b/src/main/java/com/small/tictactoe/App.java
index cf2fb3ebf6dae5cf53080ef5e2c4454a07754818..fb8697e1594b829ab1f4523811d0a8766a2bd0bf 100644
--- a/src/main/java/com/small/tictactoe/App.java
+++ b/src/main/java/com/small/tictactoe/App.java
@@ -1,43 +1,51 @@
 package com.small.tictactoe;
 
 import javax.swing.*;
+import java.awt.*;
 
 public class App extends JFrame {
-    private final GameBoardPanel gameBoardPanel = new GameBoardPanel();
+    private transient TicTacToeGamePlayer player = new TicTacToeGame();
+    private final GameBoardPanel gameBoardPanel = new GameBoardPanel(player);
+    private final JTextArea textScore = new JTextArea();
+
     App() {
         initGUI();
     }
 
+    public static void main(String[] args) {
+        new App();
+    }
+
     private void initGUI() {
         setTitle("Tic-Tac-Toe");
         setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
-        setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
+        setLayout(new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS));
 
         add(gameBoardPanel);
         JPanel buttonPanel = new JPanel();
         JButton buttonNewGame = new JButton("New Game");
         buttonNewGame.addActionListener(e -> newGame());
-        JButton buttonGetScore = new JButton ("Get Score");
-        buttonGetScore.addActionListener(e -> getScore());
         buttonPanel.add(buttonNewGame);
-        buttonPanel.add(buttonGetScore);
+
         add(buttonPanel);
+        Dimension d = new Dimension(600, 100);
+        textScore.setSize(d);
+        textScore.setMaximumSize(d);
+        textScore.setMinimumSize(d);
+        add(textScore);
         pack();
-        setSize(600, 600);
+        setSize(600, 700);
         setLocationRelativeTo(null);
         setVisible(true);
     }
+
     private void newGame() {
         gameBoardPanel.newGame();
+        textScore.setText("");
     }
-    private void getScore() {
-        TicTacToeGame game = new TicTacToeGame();
-        game.setBoard(gameBoardPanel.getBoard());
-        System.out.println(game.getScore());
 
+    public void getScore() {
+        TicTacToeGame game = (TicTacToeGame) player;
+        textScore.setText(game.getScore());
     }
-    public static void main(String[] args) {
-        new App();
-    }
-
 }
diff --git a/src/main/java/com/small/tictactoe/GameBoardPanel.java b/src/main/java/com/small/tictactoe/GameBoardPanel.java
index ea0b9724e71bd80d29ae518ad33a20c7019a64fd..0ef5ddf366f5742c611b8f1976c2fe472e60055f 100644
--- a/src/main/java/com/small/tictactoe/GameBoardPanel.java
+++ b/src/main/java/com/small/tictactoe/GameBoardPanel.java
@@ -6,49 +6,29 @@ import java.awt.event.MouseEvent;
 import java.awt.event.MouseListener;
 
 public class GameBoardPanel extends JPanel implements MouseListener {
-    Character [][] board;
     private final GameTile[][] gameTiles = new GameTile[3][3];
-    private char nextPiece = 'x';
+     private  final transient TicTacToeGamePlayer player;
 
-    GameBoardPanel() {
+    GameBoardPanel(TicTacToeGamePlayer player) {
+        this.player = player;
         initGUI();
-    }
-    Character[][] getBoard() {
-        Character [][]  board = new Character[3][3];
-        for (int row = 0; row < 3; ++row) {
-            for (int column = 0; column < 3; ++column) {
-                board[row][column] = gameTiles[row][column].getCurrentValue();
-            }
-        }
-        return board;
-    }
-    public void placePiece(char xOrO, int row, int col) {
-        gameTiles[row][col].setCurrentValue(xOrO);
+        newGame();
     }
 
     public void newGame() {
-        nextPiece = 'x';
+        player.newGame();
+        clearTable();
+        repaint();
+    }
 
+    private void clearTable() {
         for (int row = 0; row < 3; ++row) {
             for (int column = 0; column < 3; ++column) {
-                placePiece(' ', row, column);
+                gameTiles[row][column].setCurrentValue(' ');
             }
         }
-        repaint();
-    }
-
-    public char getNextPiece() {
-        char returnValue = nextPiece;
-
-        if (nextPiece == 'x') {
-            nextPiece = 'o';
-        } else if (nextPiece == 'o') {
-            nextPiece = 'x';
-        }
-        return returnValue;
     }
 
-
     @Override
     protected void paintComponent(Graphics g) {
         super.paintComponent(g);
@@ -65,10 +45,9 @@ public class GameBoardPanel extends JPanel implements MouseListener {
         g.fillRect(0 + 20, (getHeight()) / 3 * 2 - 10, getWidth() - 40, 20);
     }
 
-    void initGUI() {
-        GridBagLayout gbl = new GridBagLayout();
+    private void initGUI() {
         setBackground(Color.BLACK);
-        setLayout(gbl);
+        setLayout(new GridBagLayout());
         GridBagConstraints gridBagConstraints = new GridBagConstraints();
 
         gridBagConstraints.fill = GridBagConstraints.BOTH;
@@ -86,23 +65,37 @@ public class GameBoardPanel extends JPanel implements MouseListener {
                 gameTiles[row][column] = new GameTile();
                 gameTiles[row][column].addMouseListener(this);
                 add(gameTiles[row][column], gridBagConstraints);
-
             }
         }
     }
 
+    private void playSquare(int row, int column) {
+        Character xOrO = player.playSquare(row, column);
+        if (xOrO == null) {
+            return;
+        }
+        if (xOrO == 'x' || xOrO == 'o' || xOrO == ' ') {
+            gameTiles[row][column].setCurrentValue(xOrO);
+            repaint();
+
+            App app = (App)getRootPane().getParent();
+
+            app.getScore();
+        }
+    }
+
     @Override
     public void mouseClicked(MouseEvent e) {
-        GameTile tile = (GameTile) e.getSource();
-
         if (e.getButton() == 1) {
-            if (tile.getCurrentValue() == ' ') {
-                tile.setCurrentValue(getNextPiece());
+            GameTile tile = (GameTile) e.getSource();
+            for (int row = 0; row < 3; ++row) {
+                for (int column = 0; column < 3; ++column) {
+                    if (gameTiles[row][column] == tile) {
+                        playSquare(row, column);
+                    }
+                }
             }
-        } else {
-            tile.setCurrentValue(' ');
         }
-        repaint();
     }
 
     @Override
diff --git a/src/main/java/com/small/tictactoe/GameTile.java b/src/main/java/com/small/tictactoe/GameTile.java
index 25add2921090812e7cf12f67ee67ebdbb24ca6a1..1612c550e65a1c9897ca42c9a3d58c2f871bfb3a 100644
--- a/src/main/java/com/small/tictactoe/GameTile.java
+++ b/src/main/java/com/small/tictactoe/GameTile.java
@@ -19,25 +19,25 @@ public class GameTile extends JPanel {
 
     private void clearBackground(Graphics g) {
         g.setColor(Color.BLACK);
-        g.fillRect(0,0, getWidth(), getHeight());
+        g.fillRect(0, 0, getWidth(), getHeight());
         repaint();
     }
 
     private void drawCross(Graphics g) {
-        g.setColor(Color.RED );
-        int [] x = {10,30,getWidth()-10,getWidth()-30};
-        int [] y = {30,10,getHeight() - 30, getHeight()-10};
+        g.setColor(Color.RED);
+        int[] x = {10, 30, getWidth() - 10, getWidth() - 30};
+        int[] y = {30, 10, getHeight() - 30, getHeight() - 10};
         g.fillPolygon(new Polygon(x, y, 4));
-        int [] x1 = {10,30,getWidth()-10,getWidth()-30};
-        int [] y1 = {getHeight()-30, getHeight()-10,   30,10};
+        int[] x1 = {10, 30, getWidth() - 10, getWidth() - 30};
+        int[] y1 = {getHeight() - 30, getHeight() - 10, 30, 10};
         g.fillPolygon(new Polygon(x1, y1, 4));
     }
 
     private void drawNaught(Graphics g) {
-        g.setColor(Color.GREEN );
-        g.fillOval(0,0, getWidth(), getHeight());
-        g.setColor(Color.BLACK );
-        g.fillOval(20,20, getWidth() - 40, getHeight()- 40);
+        g.setColor(Color.GREEN);
+        g.fillOval(0, 0, getWidth(), getHeight());
+        g.setColor(Color.BLACK);
+        g.fillOval(20, 20, getWidth() - 40, getHeight() - 40);
     }
 
     public char getCurrentValue() {
diff --git a/src/main/java/com/small/tictactoe/TicTacToe.java b/src/main/java/com/small/tictactoe/TicTacToe.java
deleted file mode 100644
index 9e15ca8074d89d5a8a8f879cb7395b60eec46e2d..0000000000000000000000000000000000000000
--- a/src/main/java/com/small/tictactoe/TicTacToe.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package com.small.tictactoe;
-
-import java.util.Arrays;
-
-public class TicTacToe {
-    public static final String PLAYER_S_WINS = "Player %s wins.";
-    private final Character [][] board = {{' ',' ',' '},{' ',' ',' '},{' ',' ',' '}};
-    private String score = "";
-
-    public void newGame() {
-        for (int row = 0; row < 3; ++row) {
-            for (int column=0; column < 3 ; ++column){
-                board[row][column] = ' ';
-            }
-        }
-
-        score = "";
-    }
-    public void placePiece(char xOrO, int row, int column) {
-        board[row][column] = xOrO;
-    }
-    void showBoard() {
-        System.out.println(Arrays.deepToString(board[0]));
-        System.out.println(Arrays.deepToString(board[1]));
-        System.out.println(Arrays.deepToString(board[2]));
-    }
-    public String getScore() {
-        for (int i = 0; i < 3; ++i) {
-            if (winByRow(i)) return score;
-        }
-        for (int i = 0; i < 3; ++i){
-            if (winByColumn(i)) return score;
-        }
-        if (winByCrisCross()) {
-            return score;
-        }
-
-        score = "Tie Game";
-        return score;
-    }
-
-    private boolean allSame(Character... row) {
-        return Arrays.stream(row).allMatch(e->e=='O') || Arrays.stream(row).allMatch(e->e=='X');
-    }
-
-    private boolean winByCrisCross() {
-        if (allSame(board[0][0], board[1][1], board[2][2]) ||
-            allSame(board[0][2], board[1][1], board[2][0])) {
-            score = String.format(PLAYER_S_WINS, board[1][1]);
-            return true;
-        }
-        return false;
-    }
-
-    private boolean winByColumn(int column) {
-        if (allSame(board[0][column], board[1][column], board[2][column])) {
-            score = String.format(PLAYER_S_WINS, board[0][column]);
-            return true;
-        }
-        return false;
-    }
-
-    private boolean winByRow(int row) {
-        if (allSame(board[row])) {
-            score = String.format(PLAYER_S_WINS, board[row][0]);
-            return true;
-        }
-        return false;
-    }
-}
diff --git a/src/main/java/com/small/tictactoe/TicTacToeGame.java b/src/main/java/com/small/tictactoe/TicTacToeGame.java
index 8cfbce8c8a7dd4c4754fafa357e0eb56c6a0c273..4edeecb93f0a47bf57205aeebaa196af4a1ef2ef 100644
--- a/src/main/java/com/small/tictactoe/TicTacToeGame.java
+++ b/src/main/java/com/small/tictactoe/TicTacToeGame.java
@@ -2,42 +2,115 @@ package com.small.tictactoe;
 
 import java.util.Arrays;
 
-public class TicTacToeGame {
+public class TicTacToeGame implements TicTacToeGamePlayer {
     public static final String PLAYER_S_WINS = "Player %s wins.";
-    private Character [][] board;
-    private String score;
+    private Character[][] board;
+    private Character nextCharacter = 'x';
+    private Character winPiece = ' ';
+    private Character winDirection = ' ';
+    private int winRow = -1;
+    private int winColumn = -1;
+
+    public TicTacToeGame() {
+        board = new Character[3][3];
+        newGame();
+    }
+
+    private void resetBoardValues() {
+        for (int row = 0; row < 3; ++row) {
+            for (int column = 0; column < 3; ++column) {
+                board[row][column] = ' ';
+            }
+        }
+    }
+
+    private void resetGameState() {
+        nextCharacter = 'x';
+        winPiece = ' ';
+        winDirection = ' ';
+        winRow = -1;
+        winColumn = -1;
+    }
 
     public String getScore() {
+        if (winPiece != ' ') {
+            return String.format(PLAYER_S_WINS, winPiece);
+        }
+        if (noneLeft()) {
+            return "Tie Game";
+        }
+        return "";
+    }
+
+    private void updateGameState() {
         for (int i = 0; i < 3; ++i) {
-            if (winByRow(i)) return score;
+            if (winByRow(i)) {
+                return;
+            }
         }
-        for (int i = 0; i < 3; ++i){
-            if (winByColumn(i)) return score;
+        for (int i = 0; i < 3; ++i) {
+            if (winByColumn(i)) {
+                return;
+            }
         }
-        if (winByCrisCross()) {
-            return score;
+        winByCrisCross();
+    }
+
+    @Override
+    public void newGame() {
+        resetBoardValues();
+        resetGameState();
+    }
+
+    @Override
+    public Character playSquare(int row, int column) {
+        if (winPiece == ' '  && board[row][column] == ' ') {
+            board[row][column] = getNextPiece();
+            updateGameState();
+            return board[row][column];
         }
+        return null;
+    }
 
-        score = "Tie Game";
-        return score;
+    @Override
+    public Character getNextPiece() {
+        Character currentCharacter = nextCharacter;
+        nextCharacter = nextCharacter == 'x' ? 'o' : 'x';
+        return currentCharacter;
     }
 
     private boolean allSame(Character... row) {
-        return Arrays.stream(row).allMatch(e->e=='o') || Arrays.stream(row).allMatch(e->e=='x');
+        return Arrays.stream(row).allMatch(e -> e == 'o') || Arrays.stream(row).allMatch(e -> e == 'x');
     }
+    private boolean noneLeft() {
+        return Arrays.stream(board[0]).noneMatch(e -> e == ' ') &&
+                Arrays.stream(board[1]).noneMatch(e -> e == ' ') &&
+                Arrays.stream(board[2]).noneMatch(e -> e == ' ');
 
+    }
     private boolean winByCrisCross() {
-        if (allSame(board[0][0], board[1][1], board[2][2]) ||
-                allSame(board[0][2], board[1][1], board[2][0])) {
-            score = String.format(PLAYER_S_WINS, board[1][1]);
-            return true;
+        boolean returnValue = false;
+        if (allSame(board[0][0], board[1][1], board[2][2])) {
+            winColumn = 0;
+            returnValue = true;
+        } else if (allSame(board[0][2], board[1][1], board[2][0])) {
+            winColumn = 2;
+            returnValue = true;
         }
-        return false;
+        if (returnValue) {
+            winDirection = 'd';
+            winRow = 0;
+            winPiece = board[winRow][winColumn];
+        }
+        return returnValue;
     }
 
     private boolean winByColumn(int column) {
         if (allSame(board[0][column], board[1][column], board[2][column])) {
-            score = String.format(PLAYER_S_WINS, board[0][column]);
+            winDirection = 'c';
+            winRow = 0;
+            winColumn = column;
+            winPiece = board[winRow][winColumn];
             return true;
         }
         return false;
@@ -45,7 +118,10 @@ public class TicTacToeGame {
 
     private boolean winByRow(int row) {
         if (allSame(board[row])) {
-            score = String.format(PLAYER_S_WINS, board[row][0]);
+            winDirection = 'r';
+            winRow = row;
+            winColumn = 0;
+            winPiece = board[winRow][winColumn];
             return true;
         }
         return false;
@@ -53,5 +129,6 @@ public class TicTacToeGame {
 
     public void setBoard(Character[][] board) {
         this.board = board;
+        updateGameState();
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/small/tictactoe/TicTacToeGamePlayer.java b/src/main/java/com/small/tictactoe/TicTacToeGamePlayer.java
new file mode 100644
index 0000000000000000000000000000000000000000..677f53f14520776a389a02cc13609837744fe97d
--- /dev/null
+++ b/src/main/java/com/small/tictactoe/TicTacToeGamePlayer.java
@@ -0,0 +1,9 @@
+package com.small.tictactoe;
+
+public interface TicTacToeGamePlayer {
+    Character getNextPiece();
+
+    Character playSquare(int row, int column);
+
+    void newGame();
+}
diff --git a/src/test/groovy/com/small/tictactoe/TicTacToeGame_Specification.groovy b/src/test/groovy/com/small/tictactoe/TicTacToeGame_Specification.groovy
new file mode 100644
index 0000000000000000000000000000000000000000..630332068ddaa5ce1126f1d7781689179308d475
--- /dev/null
+++ b/src/test/groovy/com/small/tictactoe/TicTacToeGame_Specification.groovy
@@ -0,0 +1,56 @@
+package com.small.tictactoe
+
+import spock.lang.Specification
+
+class TicTacToeGame_Specification extends Specification {
+
+    def game = new TicTacToeGame()
+
+    void setup() {
+        game = new TicTacToeGame()
+    }
+    def "should show tie game when no play has happened"() {
+        expect:
+        "Tie Game" == game.getScore()
+
+    }
+
+    def "should show tie game when new game"() {
+        game.playSquare(0, 0)
+        game.playSquare(0, 1)
+        game.playSquare(0, 2)
+        game.newGame()
+        expect:
+        game.getScore() == "Tie Game"
+    }
+
+    def "should show player x wins "() {
+        game.playSquare(0, 0)
+        game.playSquare(2, 0)
+        game.playSquare(0, 1)
+        game.playSquare(2, 1)
+        game.playSquare(0, 2)
+        expect:
+        game.getScore() == "Player x wins."
+    }
+
+    def "should show that play begins with x and swaps to o each call"() {
+        expect:
+        (char)'x' == game.getNextPiece()
+        (char)'o' == game.getNextPiece()
+        (char)'x' == game.getNextPiece()
+        (char)'o' == game.getNextPiece()
+        (char)'x' == game.getNextPiece()
+        (char)'o' == game.getNextPiece()
+    }
+
+    def "should show player x wins when importing a winning board"() {
+        Character [][] board = new Character[3][3]
+        board =[['x' as char,'x' as char, 'x' as char],
+                [' ' as char,' ' as char, ' ' as char],
+                [' ' as char,' ' as char, ' ' as char]]
+        game.setBoard(board)
+        expect:
+        "Player x wins." == game.getScore()
+    }
+}
diff --git a/src/test/groovy/com/small/tictactoe/TicTacToe_Specification.groovy b/src/test/groovy/com/small/tictactoe/TicTacToe_Specification.groovy
deleted file mode 100644
index ee8b588576d37f46775cabcd8a543df419f1ceb4..0000000000000000000000000000000000000000
--- a/src/test/groovy/com/small/tictactoe/TicTacToe_Specification.groovy
+++ /dev/null
@@ -1,56 +0,0 @@
-package com.small.tictactoe
-
-import spock.lang.Specification
-
-class TicTacToe_Specification extends Specification {
-    def game = new TicTacToe()
-    void setup() {
-        game = new TicTacToe()
-    }
-
-    def "should show tie "() {
-        expect:
-        "Tie Game" == game.getScore()
-    }
-
-    def "should show player O win horizontally"() {
-        game.placePiece('O' as char, 0, 0)
-        game.placePiece('O' as char, 0, 1)
-        game.placePiece('O' as char, 0, 2)
-        expect:
-        "Player O wins." == game.getScore()
-    }
-
-    def "should show player X win vertically"() {
-        game.placePiece('X' as char, 0, 0)
-        game.placePiece('X' as char, 1, 0)
-        game.placePiece('X' as char, 2, 0)
-        expect:
-        "Player X wins." == game.getScore()
-    }
-
-    def "should show player O win criss-cross"() {
-        game.placePiece('O' as char, 0, 0)
-        game.placePiece('O' as char, 1, 1)
-        game.placePiece('O' as char, 2, 2)
-        expect:
-        "Player O wins." == game.getScore()
-    }
-
-    def "should play the game"() {
-        game.newGame()
-        game.showBoard()
-        game.placePiece('X' as char, 0,0)
-        game.showBoard()
-        game.placePiece('O' as char, 1,1)
-        game.showBoard()
-        game.placePiece('X' as char, 0,2)
-        game.placePiece('O' as char, 0,1)
-        game.placePiece('X' as char, 2,1)
-        game.placePiece('O' as char, 2,2)
-        game.showBoard()
-        println(game.getScore())
-        expect:
-        true
-    }
-}
\ No newline at end of file