Skip to Main Content

Java Programming

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Developing a BlackJack card game in Java

807606Mar 1 2007 — edited Mar 6 2007
hello there to all you java gurus.
this is james mcfadden. I want to develop a BlackJack card game in java. this is going to be a 2-player network game. I want to get some help in modifying a TicTacToeServer.java program and a TicTacToeClient.java program so that they can pass as BlackJack programs. i found these programs in a book called Introduction to Java Programming by Y. Daniel Liang. I have an electronic copy of these programs on my USB stick. I have renamed these programs BlackJackServer.java and BlackJackClient.java. There is a TicTacToeConstants.java (a program that defines the constants shared by all the classes in the game) program that i am going to use but it doesn't have to be modified much. I've only renamed it BlackJackConstants.java.

This is the way that the game is supposed to work:
The server application deals cards to the client. The server should deal additional cards to the client on request and notify the client when the game has ended. At the start of each game the client enters a bet between 1-10 euros. if the client wins double the bet is returned.

here's the code. your help is greatly appreciated.
thank you.
import java.io.*;
import java.net.*;
import javax.swing.*;
import java.awt.*;
import java.util.Date;

public class BlackJackServer extends JFrame implements BlackJackConstants{
   public static void main(String[] args){
      BlackJackServer frame=new BlackJackServer();
   }

   public BlackJackServer(){
      JTextArea jtaLog=new JTextArea();

      //Create a scroll pane to hold text area
      JScrollPane scrollPane=new JScrollPane(jtaLog);

      //Add the scroll pane to the frame
      add(scrollPane,BorderLayout.CENTER);

      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setSize(300,300);
      setTitle("BlackJackServer");
      setVisible(true);

      try{
         //Create a server socket
         ServerSocket serverSocket=new ServerSocket(8000);
         jtaLog.append(new Date()+": Server started at socket 8000\n");

         //Number a session
         int sessionNo=1;

         //Ready to create a session for every two players
         while(true){
            jtaLog.append(new Date()+": Wait for players to join session "+sessionNo+'\n');

            //Connect to player 1
            Socket player1=serverSocket.accept();

            jtaLog.append(new Date()+": Player 1 joined session "+sessionNo+'\n');
            jtaLog.append("Player 1's IP address"+player1.getInetAddress().getHostAddress()+'\n');

            //Notify that the player is Player 1
            new DataOutputStream(player1.getOutputStream()).writeInt(PLAYER1);

            //Connect to player 2
            Socket player2=serverSocket.accept();

            jtaLog.append(new Date()+": Player 2 joined session "+sessionNo+'\n');
            jtaLog.append("Player 2's IP address"+player2.getInetAddress().getHostAddress()+'\n');

            //Notify that the player is Player 2
            new DataOutputStream(player2.getOutputStream()).writeInt(PLAYER2);

            //Display this session and increment session number
            jtaLog.append(new Date()+": Start a thread for session "+sessionNo++ +'\n');

            //Create a new task for this session of two players
            HandleASession task=new HandleASession(player1,player2);

            //Start the new thread
            new Thread(task).start();
         }
      }
      catch(IOException ex){
         System.err.println(ex);
      }
   }
}

//Define the thread class for handling a new session for two players
class HandleASession implements Runnable,BlackJackConstants{
   private Socket player1;
   private Socket player2;

   //Create and initialize cells
   private char[][] cell=new char[3][3];

   private DataInputStream fromPlayer1;
   private DataOutputStream toPlayer1;
   private DataInputStream fromPlayer2;
   private DataOutputStream toPlayer2;

   //Continue to play
   private boolean continueToPlay=true;

   /*Construct a thread*/
   public HandleASession(Socket player1,Socket player2){
      this.player1=player1;
      this.player2=player2;

      //Initialize cells
      for(int i=0;i<3;i++)
         for(int j=0;j<3;j++)
            cell[i][j]=' ';
   }

   /*Implement the run() method for the thread*/
   public void run(){
      try{
         //Create data input and output streams
         DataInputStream fromPlayer1=new DataInputStream(player1.getInputStream());
         DataOutputStream toPlayer1=new DataOutputStream(player1.getOutputStream());
         DataInputStream fromPlayer2=new DataInputStream(player2.getInputStream());
         DataOutputStream toPlayer2=new DataOutputStream(player2.getOutputStream());

         //Write anything to notify player 1 to start
         //This is just to let player 1 know to start
         toPlayer1.writeInt(1);

        //Continuously serve the players and determine and report
        //the game status to the players
        while(true){
           //Receive a move from player 1
           int row=fromPlayer1.readInt();
           int column=fromPlayer1.readInt();
           cell[row][column]='X';

           //Check if Player 1 wins
           if(isWon('X')){
              toPlayer1.writeInt(PLAYER1_WON);
              toPlayer2.writeInt(PLAYER1_WON);
              sendMove(toPlayer2,row,column);
              break;//Break the loop
           }
           else if(isFull()){//Check if all cells are filled
              toPlayer1.writeInt(DRAW);
              toPlayer2.writeInt(DRAW);
              sendMove(toPlayer2,row,column);
              break;
           }
           else{
              //Notify player 2 to take the turn
              toPlayer2.writeInt(CONTINUE);

              //Send player 1's selected row and column to player 2
              sendMove(toPlayer2,row,column);
           }

           //Receive a move from Player 2
           row=fromPlayer2.readInt();
           column=fromPlayer2.readInt();
           cell[row][column]='O';

           //Check if Player 2 wins
           if(isWon('O')){
              toPlayer1.writeInt(PLAYER2_WON);
              toPlayer2.writeInt(PLAYER2_WON);
              sendMove(toPlayer1,row,column);
              break;
           }
           else{
              //Notify player 1 to take the turn
              toPlayer1.writeInt(CONTINUE);

              //Send player 2's selected row and column to player 1
              sendMove(toPlayer1,row,column);
              }
           }
        }
        catch(IOException ex){
           System.err.println(ex);
        }
     }

     /*Send the move to other player*/
     private void sendMove(DataOutputStream out,int row,int column)throws IOException{
        out.writeInt(row);//Send row index
        out.writeInt(column);//Send column index
     }

     /*Determine if the cells are all occupied*/
     private boolean isFull(){
        for(int i=0;i<3;i++)
           for(int j=0;j<3;j++)
              if(cell[i][j]==' ')
                 return false;//At least one cell is not filled

        //All cells are filled
        return true;
     }

     /*Determine if the player with the specified token wins*/
     private boolean isWon(char token){
        //Check all rows
        for(int i=0;i<3;i++)
           if((cell[0]==token)&&(cell[i][1]==token)&&(cell[i][2]==token)){
return true;
}

/*Check all columns*/
for (int j= 0;j<3;j++)
if((cell[0][j]==token)&&(cell[1][j]==token)&&(cell[2][j]==token)){
return true;
}

/*Check major diagonal*/
if((cell[0][0]==token)&&(cell[1][1]==token)&&(cell[2][2]==token)){
return true;
}

/*Check subdiagonal*/
if((cell[0][2]==token)&&(cell[1][1]==token)&&(cell[2][0]==token)){
return true;
}

/*All checked, but no winner*/
return false;
}
}

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.LineBorder;
import java.io.*;
import java.net.*;

public class BlackJackClient extends JApplet implements Runnable,BlackJackConstants{
  //Indicate whether the player has the turn
  private boolean myTurn=false;

  //Indicate the token for the player
  private char myToken=' ';

  //Indicate the token for the other player
  private char otherToken=' ';

  //Create and initialize cells
  private Cell[][] cell=new Cell[3][3];

  //Create and initialize a title label
  private JLabel jlblTitle=new JLabel();

  //Create and initialize a status label
  private JLabel jlblStatus=new JLabel();

  //Indicate selected row and column by the current move
  private int rowSelected;
  private int columnSelected;

  //Input and output streams from/to server
  private DataInputStream fromServer;
  private DataOutputStream toServer;

  //Continue to play?
  private boolean continueToPlay=true;

  //Wait for the player to mark a cell
  private boolean waiting=true;

  //Indicate if it runs as application
  private boolean isStandAlone=false;

  //Host name or ip
  private String host="localhost";

  /*Initialize UI*/
  public void init(){
    //Panel p to hold cells
    JPanel p=new JPanel();
    p.setLayout(new GridLayout(3,3,0,0));
	 
    for(int i=0;i<3;i++)
      for(int j=0;j<3;j++)
        p.add(cell[i][j]=new Cell(i,j));

    //Set properties for labels and borders for labels and panel
    p.setBorder(new LineBorder(Color.black,1));
    jlblTitle.setHorizontalAlignment(JLabel.CENTER);
    jlblTitle.setFont(new Font("SansSerif",Font.BOLD,16));
    jlblTitle.setBorder(new LineBorder(Color.black,1));
    jlblStatus.setBorder(new LineBorder(Color.black,1));

    //Place the panel and the labels to the applet
    add(jlblTitle,BorderLayout.NORTH);
    add(p,BorderLayout.CENTER);
    add(jlblStatus,BorderLayout.SOUTH);

    //Connect to the server
    connectToServer();
  }

  private void connectToServer(){
    try{
      //Create a socket to connect to the server
      Socket socket;
		
      if(isStandAlone)
        socket=new Socket(host,8000);
      else
        socket=new Socket(getCodeBase().getHost(),8000);

      //Create an input stream to receive data from the server
      fromServer=new DataInputStream(socket.getInputStream());

      //Create an output stream to send data to the server
      toServer=new DataOutputStream(socket.getOutputStream());
    }
    catch(Exception ex){
      System.err.println(ex);
    }

    //Control the game on a separate thread
    Thread thread=new Thread(this);
    thread.start();
  }

  public void run(){
    try{
      //Get notification from the server
      int player=fromServer.readInt();

      //Am I player 1 or 2?
      if(player==PLAYER1){
        myToken='X';
        otherToken='O';
        jlblTitle.setText("Player 1 with token 'X'");
        jlblStatus.setText("Waiting for player 2 to join");

        //Receive startup notification from the server
        fromServer.readInt();//Whatever read is ignored

        //The other player has joined
        jlblStatus.setText("Player 2 has joined. I start first");

        //It is my turn
        myTurn=true;
      }
      else if(player==PLAYER2){
        myToken='O';
        otherToken='X';
        jlblTitle.setText("Player 2 with token 'O'");
        jlblStatus.setText("Waiting for player 1 to move");
      }

      //Continue to play
      while(continueToPlay){
        if(player==PLAYER1){
          waitForPlayerAction();//Wait for player 1 to move
          sendMove();//Send the move to the server
          receiveInfoFromServer();//Receive info from the server
        }
        else if(player==PLAYER2){
          receiveInfoFromServer();//Receive info from the server
          waitForPlayerAction();//Wait for player 2 to move
          sendMove();//Send player 2's move to the server
        }
      }
    }
    catch(Exception ex){}
  }

  /*Wait for the player to mark a cell*/
  private void waitForPlayerAction()throws InterruptedException{
    while(waiting){
      Thread.sleep(100);
    }

    waiting=true;
  }

  /*Send this player's move to the server*/
  private void sendMove()throws IOException{
    toServer.writeInt(rowSelected);//Send the selected row
    toServer.writeInt(columnSelected);//Send the selected column
  }

  /*Receive info from the server*/
  private void receiveInfoFromServer()throws IOException{
    //Receive game status
    int status=fromServer.readInt();

    if (status == PLAYER1_WON) {
      // Player 1 won, stop playing
      continueToPlay = false;
      if (myToken == 'X') {
        jlblStatus.setText("I won! (X)");
      }
      else if (myToken == 'O') {
        jlblStatus.setText("Player 1 (X) has won!");
        receiveMove();
      }
    }
    else if (status == PLAYER2_WON) {
      // Player 2 won, stop playing
      continueToPlay = false;
      if (myToken == 'O') {
        jlblStatus.setText("I won! (O)");
      }
      else if (myToken == 'X') {
        jlblStatus.setText("Player 2 (O) has won!");
        receiveMove();
      }
    }
    else if (status == DRAW) {
      // No winner, game is over
      continueToPlay = false;
      jlblStatus.setText("Game is over, no winner!");

      if (myToken == 'O') {
        receiveMove();
      }
    }
    else {
      receiveMove();
      jlblStatus.setText("My turn");
      myTurn = true; // It is my turn
    }
  }

  private void receiveMove() throws IOException {
    // Get the other player's move
    int row = fromServer.readInt();
    int column = fromServer.readInt();
    cell[row][column].setToken(otherToken);
  }

  // An inner class for a cell
  public class Cell extends JPanel {
    // Indicate the row and column of this cell in the board
    private int row;
    private int column;

    // Token used for this cell
    private char token = ' ';

    public Cell(int row, int column) {
      this.row = row;
      this.column = column;
      setBorder(new LineBorder(Color.black, 1)); // Set cell's border
      addMouseListener(new ClickListener());  // Register listener
    }

    /** Return token */
    public char getToken() {
      return token;
    }

    /** Set a new token */
    public void setToken(char c) {
      token = c;
      repaint();
    }

    /** Paint the cell */
    protected void paintComponent(Graphics g) {
      super.paintComponent(g);

      if (token == 'X') {
        g.drawLine(10, 10, getWidth() - 10, getHeight() - 10);
        g.drawLine(getWidth() - 10, 10, 10, getHeight() - 10);
      }
      else if (token == 'O') {
        g.drawOval(10, 10, getWidth() - 20, getHeight() - 20);
      }
    }

    /** Handle mouse click on a cell */
    private class ClickListener extends MouseAdapter {
      public void mouseClicked(MouseEvent e) {
        // If cell is not occupied and the player has the turn
        if ((token == ' ') && myTurn) {
          setToken(myToken);  // Set the player's token in the cell
          myTurn = false;
          rowSelected = row;
          columnSelected = column;
          jlblStatus.setText("Waiting for the other player to move");
          waiting = false; // Just completed a successful move
        }
      }
    }
  }

  /** This main method enables the applet to run as an application */
  public static void main(String[] args) {
    // Create a frame
    JFrame frame = new JFrame("BlackJackClient");

    // Create an instance of the applet
    BlackJackClient applet = new BlackJackClient();
    applet.isStandAlone = true;

    // Get host
    if (args.length == 1) applet.host = args[0];

    // Add the applet instance to the frame
    frame.getContentPane().add(applet, BorderLayout.CENTER);

    // Invoke init() and start()
    applet.init();
    applet.start();

    // Display the frame
    frame.setSize(320, 300);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
  }
}
just in case some of you don't have the Introduction to Java Programming book, here's the BlackJackConstants.java program (originally the TicTacToeConstants.java program) .
public interface BlackJackConstants{
   public static int PLAYER1=1;//Indicate player 1
   public static int PLAYER2=2;//Indicate player 2
   public static int PLAYER1_WON=1;//Indicate player 1 won
   public static int PLAYER2_WON=2;//Indicate player 2 won
   public static int DRAW=3;//Indicate a draw
   public static int CONTINUE=4;//Indicate to continue
}
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Apr 3 2007
Added on Mar 1 2007
8 comments
1,078 views