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
}