Title: Tic Tac Toe
Course: CPS 261: Advanced Java Concepts ~ DL & MM MASTER

Tic Tac Toe

MyMain.java

same as everything else including guiChat

MyGameInput.java


package ticTacToe;
import java.io.Serializable;

public class MyGameInput  implements Serializable
{
    private static final long serialVersionUID = 1L;
// command options
   static final int NO_COMMAND=-1;
   static final int JOIN_GAME=1;
   static final int SELECT_SQUARE=2;
   static final int DISCONNECTING=3;
   static final int RESETTING=4;

   int command=NO_COMMAND;

   String myName;
   int row, col;

   public void setName(String name)
   {
       myName=name;
   }
}


MyGameOutput.java


package ticTacToe;
import java.io.Serializable;

public class MyGameOutput  implements Serializable
{
    private static final long serialVersionUID = 1L;

    MyGame myGame =null;
    public MyGameOutput(MyGame gs)
    {
        myGame =gs;
    }
}


MyGame.java


package ticTacToe;
import gameNet.GameNet_CoreGame;

import java.io.Serializable;
import java.util.ArrayList;



public class MyGame extends GameNet_CoreGame implements Serializable
{
    private static final long serialVersionUID = 1L;
    private ArrayList<String> currPlayers = new ArrayList<String>();

    // Note that the TttLogic is private and not directly available.  You must
    // go through the public methods in this class.

    private TttLogic tttl = new TttLogic();

    public MyGame()
    {
        tttl.clearBoard();
    }
    // Process commands from each of the game players

    public Object process(Object inputs)
    {
        MyGameInput myGameInput = (MyGameInput)inputs;

        // Note that this routine will add the player if he isn't currently in the
        // game and there is room (i.e. < 2 players)
        int clientIndex = getClientIndex(myGameInput.myName);

        if (clientIndex < 0)
        {
            System.out.println("Already have 2 players");
            return null; // Ignore input
        }

        switch (myGameInput.command)
        {
        case MyGameInput.JOIN_GAME:
            break;
        case MyGameInput.SELECT_SQUARE:
            tttl.makeSelection(clientIndex, myGameInput.row, myGameInput.col);
            break;
        case MyGameInput.DISCONNECTING:
            currPlayers.remove(myGameInput.myName);
            break;
        case MyGameInput.RESETTING:
            tttl.clearBoard();
            break;
        default: /* ignore */
        }

        // Send game back to all clients
        MyGameOutput myGameOutput = new MyGameOutput(this);
        return myGameOutput;
    }

    // Get the proper label for each button in the 3x3 grid
    public String getButtonLabel(int row, int col)
    {
        return ""+tttl.getButtonLabel(row, col);
    }

    // returns your name with either " -- O" or " -- X" appended
    public String getExtendedName(String myName)
    {
         char myMarker =(( getYourIndex(myName)==0)? 'O' : 'X' );
         return myName + " --  " + myMarker;
    }

    // Returns True if the Game is still going
    public boolean gameInProgress()
    {
        return tttl.gameInProgress();
    }

    // Returns whether you won, lost, or the Game is in progress
    public String getStatus(String myName)
    {
        int index = getYourIndex(myName);
        return tttl.getGameStatus(index);
    }

    // returns whether you can select a given 3x3 grid based on the current turn.
    public boolean checkAvailability(String myName, int row, int col)
    {
        int index = getYourIndex(myName);
        return tttl.checkAvailability(index,  row,  col);

    }

    // Returns Information about whose turn it is
    public String getTurnInfo(String myName)
    {
        if (!gameInProgress())
            return " Game Over ";

        int index = getYourIndex(myName);
        if (tttl.isTurn(index))
            return "Your Turn";
        String otherClient = otherPlayerName(myName);
        return otherClient+"'s Turn";
    }

    // If you have already connected, then this will return your index (0 or 1).
    // If you are new and we currently have less than 2 players then you are added
    // to the game and your index is returned (0 or 1)
    // If we already have 2 players, then this will return -1

    private int getClientIndex(String name)
    {
        // The following will return -1 if the name can't be found
        int retval = currPlayers.indexOf(name);

        if (retval < 0 && currPlayers.size() < 2)
        {
            retval = currPlayers.size();
            currPlayers.add(name);
            if (currPlayers.size() == 2)
            {
                // Game ready to go.
            }
        }
        return retval;
    }

    // If you are already in the game, your index will be returned (0 or 1)
    // Otherwise -1 is returned ... you are never added with this routine.
    private int getYourIndex(String name)
    {
        return currPlayers.indexOf(name);
    }

    // This returns the other Player's name if he exists.  A null is returned if he doesn't exist.
    private String otherPlayerName(String yourName)
    {
        if (currPlayers.size() < 2)
            return null;
        if (yourName.equals(currPlayers.get(0)))
            return currPlayers.get(1);
        else
            return currPlayers.get(0);
    }


}


TttLogic.java


package ticTacToe;

import java.io.Serializable;

public class TttLogic implements Serializable{

    private static final long serialVersionUID = 1L;

        // The TTT 3 x 3 will be filled with -1 (AVAILABLE) to start with
        // There after, entries will receive either a the player's index (0 or 1).
        private static final int AVAILABLE = -1;

        // GameControl Status values
        private static final int GAME_TIE = 2;
        private static final int GAME_IN_PROGRESS=-1;

        // Note that gameWinner will take on the values of:
        // GAME_TIE
        // 0 if the first player is the Winner
        // 1 if the second player is the Winner
        private int gameWinner = GAME_IN_PROGRESS;


        private int[][] board = new int[3][3];

        private int nextTurn = 0;
        private int startingTurn = 1;

        // Used to allow the User interface to fill in appropriate label for each cell
        public char getButtonLabel(int row, int col)
        {
            int value = board[row][col];
            if (value == AVAILABLE)
                return ' ';
            if (value == 0)
                return 'O';
            else
                return 'X';
        }

        // Used to find out if the game is complete
        public boolean gameInProgress()
        {
            if (gameWinner == GAME_IN_PROGRESS)
                return true;
            else
                return false;
        }

        public String getGameStatus(int yourIndex)
        {
            if (yourIndex == gameWinner)
                return "You Win !!!";
            if (gameWinner >= 0 && gameWinner <=1)
                return "You Lose !!!";
            if (gameWinner == GAME_TIE)
                return "Tie";
            return "Game in Progress";
        }

        // New Game
        void clearBoard()
        {
            gameWinner = GAME_IN_PROGRESS;
            // Alternate who starts if multiple games are played
            if (startingTurn != 0)
                startingTurn = 0;
            else
                startingTurn = 1;

            nextTurn = startingTurn;

            for (int i=0; i < 3; i++)
                for (int j=0; j < 3; j ++)
                    board[i][j] = AVAILABLE;
        }

        // Find out if it is your turn
        public boolean isTurn(int clientIndex)
        {
            if (clientIndex == nextTurn)
                return true;
            else
                return false;
        }

        // Can you select this button
        public boolean checkAvailability(int clientIndex, int row,  int col)
        {
            if (!isTurn(clientIndex))
            {
                return false;
            }
            if (row < 0 || row > 2 || col < 0 || col > 2)
            {
                return false;
            }
            if (board[row][col] == AVAILABLE)
                return true;
            else
                return false;

        }

        // makeSelection allows a player to make a selection if possible.
        // Error messages are printed if it is a bad selection.
        // If it is an OK selection, then the "Turn" is switched and the
        // gameWinner status is updated

        public boolean makeSelection(int clientIndex, int row, int col)
        {
            if (!isTurn(clientIndex))
            {
                System.out.println("Out of turn: " + clientIndex);
                return false;
            }
            if (row < 0 || row > 2 || col < 0 || col > 2)
            {
                System.out.println("indices out of bounds: "+ row + ": " + col);
                return false;
            }
            if (board[row][col] != AVAILABLE)
            {
                System.out.println(" Choice is already selected");
                return false;
            }
            // an OK selection
            board[row][col]= nextTurn;

            // change the turn
            nextTurn = (nextTurn +1) % 2;

            // update the game status
            gameWinner = scoreGame();
            return true;
        }


        // This routine returns:
        // GAME_IN_PROGRESS - if the game hasn't finished
        // GAME_TIE - if there are no more empty cells
        // 0 - if the first player wins
        // 1 - if the second player wins

        private int scoreGame()
        {
            // Check Rows For Winner
            for (int i=0; i < 3; i++)
            {
                int firstCol = board[i][0];
                if (firstCol != AVAILABLE && firstCol == board[i][1] && firstCol == board[i][2])
                {
                    return firstCol;
                }
            }

            // Check Cols For Winner
            for (int i=0; i < 3; i++)
            {
                int firstRow = board[0][i];
                if (firstRow != AVAILABLE && firstRow == board[1][i] && firstRow == board[2][i])
                {
                    return firstRow;
                }
            }

            // Check Diagonals
            int center = board[1][1];
            if (center != AVAILABLE)
                if (  (center == board[0][0] && center == board[2][2]) ||
                        (center == board[0][2] && center == board[2][0]))
                {
                    return center;
                }

            // Check to see if all available spaces are filled
            for (int i=0; i < 3; i++)
            {
                for (int j=0; j < 3; j++)
                    if (board[i][j] == AVAILABLE) return GAME_IN_PROGRESS; // GAME_IN_PROGRESS
            }
            return GAME_TIE;
        }


}



MyUserInterface.java


package ticTacToe;

import gameNet.GameNet_UserInterface;
import gameNet.GamePlayer;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
// New Import for Events


public class MyUserInterface extends JFrame
implements   ActionListener, GameNet_UserInterface
{
    private MyGame myGame=null;
    private GamePlayer  myGamePlayer=null;
    private String myName="";
    private MyGameInput myGameInput = new MyGameInput();

    private JButton[][] buttonArr = new JButton[3][3];
    private JButton resetButton = new JButton("Reset");
    private JLabel messageLabel = new JLabel("");
    private JLabel nameLabel = new JLabel("");

    private Termination closeMonitor = new Termination();


    public MyUserInterface()
    {
        super("Tic Tac Toe");
    }


    public void startUserInterface (GamePlayer gamePlayer) {
        myGamePlayer = gamePlayer;
        myName=gamePlayer.getPlayerName();
        myGameInput.setName(myName);

        sendMessage(MyGameInput.JOIN_GAME);

        addWindowListener(this.closeMonitor);
        screenLayout();
        setVisible(true);
    }


    private void sendMessage(int command)
    {
        myGameInput.command = command;
        myGamePlayer.sendMessage(myGameInput);
    }

    private void sendMessageSelection(int row, int col)
    {
        myGameInput.row = row;
        myGameInput.col =col;
        sendMessage(MyGameInput.SELECT_SQUARE);
    }




    public void actionPerformed(ActionEvent e)
    {
        for (int row=0; row < 3; row++)
        {
            for (int col=0; col < 3; col++)
            {
                if (e.getSource() == buttonArr[row][col])
                {
                    if (myGame != null && myGame.checkAvailability(myName, row, col))
                    {
                        sendMessageSelection(row, col);
                    }

                }
            }
        }
        if (e.getSource() == resetButton)
        {
            sendMessage(MyGameInput.RESETTING);
        }
    }

    public void receivedMessage(Object ob)
    {
        MyGameOutput myGameOutput = (MyGameOutput)ob;
        myGame = myGameOutput.myGame;

        String msg= myGame.getStatus(myName);
        String turnMsg = myGame.getTurnInfo(myName);
        String extendedName =  myGame.getExtendedName(myName);

        nameLabel.setText(extendedName);
        messageLabel.setText(turnMsg + " ------- " + msg);

        if ( myGame.gameInProgress())
            resetButton.setVisible(false);
        else
            resetButton.setVisible(true);

        for (int row=0; row < 3; row++)
        {
            for (int col=0; col < 3; col++)
            {
                String label = myGame.getButtonLabel(row, col);
                buttonArr[row][col].setText(label);
            }
        }

    }


    private void screenLayout()
    {
        setLayout(new BorderLayout());

        setSize(500,500);
        JPanel centerPanel = new JPanel();
        Font myFont = new Font("TimesRoman", Font.BOLD, 48);

        for (int i=0; i < 3; i++)
        {
            for (int j=0; j < 3; j++)
            {
                JButton b =new JButton(" ");
                b.addActionListener(this);
                b.setFont(myFont);
                centerPanel.add(b);
                buttonArr[i][j] = b;
            }
        }
        centerPanel.setLayout(new GridLayout(3,3));
        add (centerPanel, BorderLayout.CENTER);

        JPanel northPanel = new JPanel();
        northPanel.setLayout(new GridLayout(0,1));
        northPanel.add(nameLabel);

        JPanel topPanel = new JPanel();
        topPanel.setLayout(new FlowLayout());
        topPanel.add(resetButton);
        resetButton.addActionListener(this);
        topPanel.add(messageLabel);
        northPanel.add(topPanel);

        add(northPanel, BorderLayout.NORTH);

    }






    //*******************************************************
    // Inner Class
    //*******************************************************

    class Termination extends WindowAdapter
    {
        public void windowClosing(WindowEvent e)
        {
            sendMessage(MyGameInput.DISCONNECTING);
            myGamePlayer.doneWithGame();
            System.exit(0);
        }
    }
}




October 9, 2013 3:29 AM