Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

For my java class we have to create a Networked game, and the project must use M

ID: 3858235 • Letter: F

Question

For my java class we have to create a Networked game, and the project must use MVC (Model View Controller) and gameNet to create a networked game.

The classes which gameNet may implement can be found here

https://drive.google.com/open?id=0B8Jh4LT8NcplRW4zcTI4eEI3N0U

Your program must be networked and use "gameNet". I would like to see you use concepts taught in the course wherever possible.

Your program can be a game of your own choosing. I would recommend not taking on more than you can handle. Sample games to consider ( not all equally difficult to implement)

In this project we are trying to simulate a task you might have in industry. Your boss gives you a specification like MVC and some software(like gameNet). Your job is to create some software which works with these specifications and the defined interface.

In the Networked Games Zip file, you will find a package called "gamenet". You will need this for your project. This is the package demo'ed in the MVC gamenet videos. There is also another package called "gamenet_cloneable". In general you don't want to use gamenet_cloneable. It is very similar to gamenet, but there are more requirements for using this package. However, if your game has so much information flying around that gamenet sometimes crashes on you (See the Networked Drawing game where this crash is demo'ed), then you might consider gamenet_cloneable. Discuss the additional ramifications with your teacher if you do need this.

Make sure you understand the MVC (Model View Controller) approach. The following videos go over MVC and how it works with gameNet. Make sure you understand these concepts

MVC, gameNet High Level

gameNet interfaces

Please make A Tic Tac toe game to the specifications stated above:

Explanation / Answer

MyGame.java
------------------------------------------
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);
   }
  

}
----------------------------------------------------------
MyGameInput.java
------------------------
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
-------------------
import java.io.Serializable;

public class MyGameOutput implements Serializable
{
   private static final long serialVersionUID = 1L;
  
   MyGame myGame =null;
   public MyGameOutput(MyGame gs)
   {
       myGame =gs;
   }
}
-----------------------------------------------------
MyMain.java
-----------------

import gameNet.*;

// ***************************************************
public class MyMain extends GameCreator{

   public GameNet_CoreGame createGame()
   {
       return new MyGame();
   }


   public static void main(String[] args)
   {
       MyMain myMain = new MyMain();

          
       GameNet_UserInterface myUserInterface =
               new MyUserInterface();
      

       myMain.enterGame(myUserInterface);
   }// end of main
}// end of class
-----------------------------------------------------
MyUserInterface.java
----------------------
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);
       }
   }


}
---------------------------------------------------------
TttLogic.java
------------------------
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;
       }


}