So I am having a few problems with this application. When I try to run it, I get a NullPointerException for the creation of a new player and also I am not sure how to best use a stack to keep track of the turns between the user and the computer which needs to be used to check for victories. here is the code 
Game interface
package tictactoestack;
public interface Game {
    public enum Player {X, O}
    public Player getTurn();
    public Move getAutoMove();
    public Move getPlayerMove(int row, int col);
    public Character[][] getBoard();
    public boolean checkForVictory();
    public boolean isStalemated();
    public Player getPlayer();
    public void goBack();
    public Move redo();
}
Game Implementation
package tictactoestack;
import java.util.Stack;
import tictactoestack.Game.Player;
public class GameImpl implements Game {
    Character[][] newBoard = new Character[3][3];
    Player user = Player.X;
    Player computer = Player.O;
    Stack<Move> moves;
    Move prevMove = null;
    public GameImpl(Player x) {
        this.user = x;
    }
    @Override
    public Player getTurn() {
        Move m = new MoveImpl(moves.peek().getPlayer(), moves.peek().getCol(), moves.peek().getRow());
        if (m.getPlayer() == user && moves.peek().getPlayer() == Player.X)  {
            return user;
        }
        if (m.getPlayer() == computer) {
            return computer;
        }
        return null;
    }
    @Override
    public Move getAutoMove() {
        TicTacToeSolver auto = new SolverImpl();
        moves.push(auto.getMove(computer, newBoard)); 
        return auto.getMove(computer, newBoard);    
    }
    @Override
    public Move getPlayerMove(int row, int col) {
        Move playerMove = new MoveImpl(user, row, col);
        moves.push(playerMove);
        return playerMove;
    }
    @Override
    public Character[][] getBoard() {
        return newBoard;
    }
    @Override
    public boolean checkForVictory() {
/*      if(checkRowVictory(getBoard()) == true) 
            return true;
        else if(checkColVictory(getBoard()) == true)
            return true;
        else if(checkDiagVictory(getBoard()) == true) 
            return true;
        else 
            return false;
*/
        return false;
        }
    @Override
    public boolean isStalemated() {
        // TODO Auto-generated method stub
        return false;
    }
    @Override
    public Player getPlayer() {
        if(moves.peek().getPlayer() == Player.X) 
            return user;
        else if(moves.peek().getPlayer() == Player.O) 
            return computer; 
        else
            return null;
    }
    @Override
    public void goBack() {
        prevMove = moves.pop();
    }
    @Override
    public Move redo() {
        moves.push(prevMove);
        return new MoveImpl(getTurn(), prevMove.getRow(), prevMove.getCol()); 
    }
}
Move Interface
package tictactoestack;
import tictactoestack.Game.Player;
public interface Move {
    public int getRow();
    public int getCol();
    public Player getPlayer();
}
Move Implementation
package tictactoestack;
import tictactoestack.Game.Player;
public class MoveImpl implements Move {
    int row;
    int col;
    Player turn;
    public MoveImpl(Player turnIn, int rowIn, int colIn) {
        turn = turnIn;
        row = rowIn;
        col = colIn;
    }
    @Override
    public int getRow() {
        return row;
    }
    @Override
    public int getCol() {
        return col;
    }
    @Override
    public Player getPlayer() {
        if (turn == Player.X) {
            return Player.X;
        } else {
            return Player.O;
        }
    }
}
TicTacToeGUI.java
package tictactoestack;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.EmptyStackException;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.border.Border;
import tictactoestack.Game.Player;
public class TicTacToeGUI {
    private JFrame frame;
    private JPanel startPanel;
    private JButton oStartButton;
    private JButton xStartButton;
    private JButton backButton;
    private JButton redoButton;
    private JPanel boardPanel;
    private JLabel[][] labels;
    private Game game;
    private void setUpGUI() {
        game = new GameImpl(Player.X);
        labels = new JLabel[3][3];
        frame = new JFrame();
        frame.setLayout(new BorderLayout());
        startPanel = new JPanel();
        boardPanel = new JPanel(new GridLayout(3, 3));
        setUpStartPanel();
        setUpLabels();
        frame.add(startPanel, BorderLayout.NORTH);
        frame.add(boardPanel, BorderLayout.SOUTH);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
    private void setUpLabels() {
        for (int row = 0; row < 3; row++)
            for (int col = 0; col < 3; col++) {
                JLabel l = new JLabel();
                labels[row][col] = l;
                setUpLabel(l, row, col);
                boardPanel.add(l);
            }
    }
    private void setUpLabel(final JLabel l, final int row, final int col) {
        l.setPreferredSize(new Dimension(85,85));
        setLabelBorder(l, row, col);
        l.setFont(new Font(null, 0, 40));
        l.setHorizontalAlignment(0);
        l.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent arg0) {
                if (game.getBoard()[row][col] == ' '
                        && game.getPlayer() == game.getTurn()
                        && !game.checkForVictory()) {
                    playerMove(l, row, col);
                }
            }
            @Override
            public void mouseEntered(MouseEvent arg0) {
            }
            @Override
            public void mouseExited(MouseEvent arg0) {
            }
            @Override
            public void mousePressed(MouseEvent arg0) {
            }
            @Override
            public void mouseReleased(MouseEvent arg0) {
            }
        });
    }
    private void setLabelBorder(JLabel l, int row, int col) {
        Border blackline = BorderFactory.createLineBorder(Color.black);
        if (row == 1) {
            if (col == 1)
                l.setBorder(BorderFactory
                        .createMatteBorder(1, 1, 1, 1, Color.black));           else
                l.setBorder(BorderFactory.createMatteBorder(1, 0, 1, 0,
                        Color.black));
        } else if (col == 1) {
            l.setBorder(BorderFactory
                    .createMatteBorder(0, 1, 0, 1, Color.black));
        }
    }
    private void updateLabels() {
        Character[][] board = game.getBoard();
        for (int row = 0; row < 3; row++)
            for (int col = 0; col < 3; col++) {
                labels[row][col].setText(String.valueOf(board[row][col]));
            }
    }
    private void setUpStartPanel() {
        setUpOButton();
        setUpXButton();
        setUpBackButton();
        setUpRedoButton();
        startPanel.add(oStartButton);
        startPanel.add(xStartButton);
        startPanel.add(backButton);
        startPanel.add(redoButton);
    }
    private void setUpOButton() {
        oStartButton = new JButton("Play O");
        oStartButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                game = new GameImpl(Player.O);
                updateLabels();
            }
        });
    }
    private void setUpXButton() {
        xStartButton = new JButton("Play X");
        xStartButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                game = new GameImpl(Player.X);
                updateLabels();
            }
        });
    }
    private void setUpBackButton(){
        backButton = new JButton("Back");
        backButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                try {
                    game.goBack();
                } catch (EmptyStackException e) {
                    JOptionPane.showMessageDialog(null, "Can't go back");
                } catch (Exception e) {
                    e.printStackTrace();
                }
                updateLabels();
            }
        });}
        private void setUpRedoButton(){
            redoButton = new JButton("Redo");
            redoButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent arg0) {
                    try {
                        game.redo();
                    } catch (EmptyStackException e) {
                        JOptionPane.showMessageDialog(null, "Can't Redo");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    updateLabels();
                }
            });
    }
    public void play() {
        while (true) {
            if (game.getTurn() != game.getPlayer() && !game.checkForVictory()
                    && !game.isStalemated())
                getAutoMove();
            else
                try {
                    Thread.sleep(400);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
        }
    }
    public void executeMove(Move m) {
        updateLabels();
        if (game.checkForVictory()) {
            char victorChar;
            if (game.getTurn() == Player.X)
                victorChar = 'O';
            else
                victorChar = 'X';
            JOptionPane.showMessageDialog(null, victorChar + " wins!");
        }
    }
    private void playerMove(JLabel l, int row, int col) {
        Character[][] board = game.getBoard();
        if (board[row][col] == ' ') {
            Move m = game.getPlayerMove(row, col);
            executeMove(m);
        }
    }
    private void getAutoMove() {
        Move m = game.getAutoMove();
        executeMove(m);
    }
    public static void main(String[] args) {
        TicTacToeGUI gui = new TicTacToeGUI();
        gui.setUpGUI();
        gui.play();
    }
}
most of it is still a work in progress since I cannot fully test it but my most important question is why am I getting the nullpointerexception when I try to initiate the Game.Player variable for the user
heres the stacktrace associated with the error
Exception in thread "main" java.lang.NullPointerException at tictactoestack.GameImpl.getTurn(GameImpl.java:26) which is this line
if (m.getPlayer() == computer && (moves.peek().getPlayer() == Player.O)) {
at tictactoestack.TicTacToeGUI.play(TicTacToeGUI.java:189)
if (game.getTurn() != game.getPlayer() && !game.checkForVictory()
at tictactoestack.TicTacToeGUI.main(TicTacToeGUI.java:229)
gui.play();
 
     
    