import java.awt.*; import java.applet.*; import java.util.*; import java.io.*; import java.awt.event.*; import java.net.*; /* Pfotocal used: Connect, Play, Move, Start, Disconnect, New */ class Protocol { static final String C = "Connect"; static final String P = "Play"; static final String M = "Move"; static final String S = "Start"; static final String D = "Disconnect"; static final String N = "New"; static final String U = "Update"; static final String R = "Remove"; } public class Checkers extends Frame // extends Applet { Label statusLabel; Button startButton, restartButton; Button connectButton; Button disconnectButton; Label listLabel; List opponentList; Label userName, whoTurn; Board board; public boolean netGame= false; public boolean greenSide= false; public boolean blueSide= false; public boolean greenTurn = true; //public boolean greenMoved = false; int xpos, ypos; int pieceMove; Graphics g; String host,id,pass, user, opponent; connectDlg cd; Client client; Toolkit tool; public static void main(String[] args) { Checkers c = new Checkers(); } public Checkers() { init(); show(); } public void init() { setLayout(null); setSize(465,400); setBackground(new Color(12632256)); newBoard(); statusLabel = new java.awt.Label("Press Start game"); statusLabel.setBounds(12,350,312,28); statusLabel.setBackground(new Color(12632256)); add(statusLabel); startButton = new java.awt.Button(); startButton.setActionCommand("button"); startButton.setLabel("Start Game"); startButton.setBounds(336,158,108,24); startButton.setBackground(new Color(65535)); add(startButton); restartButton = new java.awt.Button(); restartButton.setActionCommand("button"); restartButton.setLabel("Restart Game"); restartButton.setBounds(336,198,108,24); restartButton.setBackground(new Color(65535)); restartButton.setEnabled(false); add(restartButton); connectButton = new java.awt.Button(); connectButton.setActionCommand("button"); connectButton.setLabel("Net Game"); connectButton.setBounds(336,234,108,24); connectButton.setBackground(new Color(65535)); add(connectButton); disconnectButton = new java.awt.Button(); disconnectButton.setActionCommand("button"); disconnectButton.setLabel("Disconnect"); disconnectButton.setBounds(336,270,108,24); disconnectButton.setBackground(new Color(65535)); add(disconnectButton); disconnectButton.setEnabled(false); userName = new java.awt.Label("User: "); userName.setBounds(336,310,84,24); add(userName); whoTurn = new java.awt.Label(); whoTurn.setBounds(336,340,84,24); add(whoTurn); listLabel = new java.awt.Label("Opponent List"); listLabel.setBounds(336,42,84,24); add(listLabel); opponentList = new java.awt.List(0,false); //opponentList.addItem("Not Connected"); add(opponentList); opponentList.setBounds(336,66,100,72); opponentList.setBackground(new Color(16777215)); } public void reinit() { connectButton.setEnabled(true); disconnectButton.setEnabled(false); startButton.setEnabled(true); opponentList.removeAll(); if(client!= null) { client.stop(); client.closeClientSocket(); } client = null; netGame= false; } public boolean handleEvent(Event e) { if(e.id== Event.WINDOW_DESTROY) { if(client != null) client.sendToServer("Disconnect " + id); hide(); dispose(); System.exit(0); return true; } return super.handleEvent(e); } public void newBoard() { board= new Board(304,304); board.setBounds(12,42,312,312); add(board);/* board.gPawnImage = getImage(getCodeBase(), "greenPawn.gif"); board.bPawnImage = getImage(getCodeBase(), "bluePawn.gif"); board.gKingImage = getImage(getCodeBase(), "greenKing.gif"); board.bKingImage = getImage(getCodeBase(), "blueKing.gif"); */ board.gPawnImage = Toolkit.getDefaultToolkit().getImage("greenPawn.gif"); board.bPawnImage = Toolkit.getDefaultToolkit().getImage("bluePawn.gif"); board.gKingImage = Toolkit.getDefaultToolkit().getImage("greenKing.gif"); board.bKingImage = Toolkit.getDefaultToolkit().getImage("blueKing.gif"); } ////////////////////////////////////////////////////////////////////////////// class connectDlg extends Frame { Panel txts,tmp; Label lbl; Button okbtn,canbtn; int port; TextField hosttxt,porttxt,usertxt,passtxt,idtxt; public boolean action(Event e,Object obj) { String s; if (e.target == okbtn) { host=hosttxt.getText(); id=idtxt.getText(); pass=passtxt.getText(); user=usertxt.getText(); s=porttxt.getText(); client= new Client(host, s); System.out.println("New client thread"); userName.setText(id); netGame= true; // send out login messge" New + username client.sendToServer(Protocol.C + " " + id); disconnectButton.setEnabled(true); connectButton.setEnabled(false); restartButton.setEnabled(false); startButton.setEnabled(false); hide(); } else if (e.target == canbtn) { hide(); connectButton.setEnabled(true); } return true; } public void setParams() { host = "localhost"; port = 5166; id = "Firebird"; pass = "1234"; user = "Hung Nguyen"; } connectDlg() { super("Connect"); Frame cd = this; setParams(); GridBagLayout gb = new GridBagLayout(); cd.setLayout(gb); GridBagConstraints c = new GridBagConstraints(); cd.resize(440,160); c.fill = GridBagConstraints.BOTH; c.weightx = 1.0; c.gridwidth = 1; lbl = new Label("Host/port",Label.LEFT); gb.setConstraints(lbl,c); add(lbl); hosttxt = new TextField(host,30); gb.setConstraints(lbl,c); add(hosttxt); porttxt = new TextField(String.valueOf(port),6); c.gridwidth = GridBagConstraints.REMAINDER; gb.setConstraints(porttxt,c); porttxt.setEditable(false); add(porttxt); c.weightx = 1.0; c.gridwidth = 1; lbl = new Label("Nick/pass",Label.LEFT); gb.setConstraints(lbl,c); add(lbl); idtxt = new TextField(id,30); gb.setConstraints(idtxt,c); add(idtxt); passtxt = new TextField(pass,16); c.gridwidth = GridBagConstraints.REMAINDER; gb.setConstraints(passtxt,c); passtxt.setEchoChar('*'); add(passtxt); c.weightx = 1.0; c.gridwidth = 1; lbl = new Label("Real Name",Label.LEFT); gb.setConstraints(lbl,c); add(lbl); usertxt = new TextField(user,38); c.gridwidth = GridBagConstraints.REMAINDER; gb.setConstraints(usertxt,c); add(usertxt); c.weightx = 1.0; c.gridwidth = 1; okbtn = new Button("OK"); gb.setConstraints(okbtn,c); add(okbtn); canbtn = new Button("Cancel"); c.gridwidth = GridBagConstraints.REMAINDER; gb.setConstraints(canbtn,c); add(canbtn); } } class Client extends Thread { Socket sock; PrintStream pout; InputStream in; OutputStream out; DataInputStream din; DataOutputStream dout; Checkers myClient; String port, host; int portInt; Client(String h, String p) { this.host= h; this.port= p; try { sock = new Socket(host, 5166); System.out.println("client socket opened"); in = sock.getInputStream(); out = sock.getOutputStream(); pout = new PrintStream(out); din = new DataInputStream(in); dout = new DataOutputStream(out); System.out.println("client streams opened"); start(); } catch (UnknownHostException e ) {System.out.println("can't find host"); } catch ( IOException e ) { System.out.println("Error connecting to host"); stop(); } } public void run() { while(true) { try { String input = din.readLine(); if(input != null) checkMsg(input); } catch ( IOException e ) {System.out.println("Error connecting to host");} } } void checkMsg(String msg) { StringTokenizer token= new StringTokenizer(msg); String first= token.nextToken(); if(first.equals(Protocol.U)) //"update" { String next; opponentList.removeAll(); while(token.hasMoreTokens()) { next= token.nextToken(); if(!next.equals(id)) opponentList.addItem(next); } if(opponentList.countItems()==0) statusLabel.setText("Only you login to the Server!"); else statusLabel.setText("To choose your opponent, double click the list item"); } if(first.equals(Protocol.P)) // "Play" choose opponent. { token.nextToken(); // the opponent of opponent which is the user itself. opponent = token.nextToken(); statusLabel.setText(id + " VS " + opponent + " : game waiting."); startButton.setEnabled(true); opponentList.setEnabled(false); } if(first.equals(Protocol.M)) // "Move" { //move on checkboard. String xmove = token.nextToken(); String ymove = token.nextToken(); pieceMove = (int)Integer.parseInt(token.nextToken()); int index = (int)Integer.parseInt(xmove); int upIndex = (int)Integer. parseInt(ymove); whoTurn.setText("Your turn!"); board.makeOpponentMove(index, upIndex,pieceMove); System.out.println("Move " + index + " ? " + upIndex + " " + pieceMove); } /* is equal "Start", that is the other client pressed 'Start', this this client is blue, so set green false set blue true; */ if(first.equals(Protocol.S)) //"Start" { opponent= token.nextToken(); opponent = token.nextToken(); // statusLabel.setText(id + " VS " + opponent + " : game beginning."); connectButton.setEnabled(false); startButton.setEnabled(false); restartButton.setEnabled(true); whoTurn.setText("Not your turn!"); greenSide= false; blueSide= true; } if(first.equals(Protocol.N)) //"New" { statusLabel.setText("Choose opponent"); opponentList.setEnabled(true); //connectButton.setEnabled(false); restartButton.setEnabled(false); whoTurn.setText(""); remove(board); newBoard(); greenSide= false; blueSide= false; } if(first.equals(Protocol.D) || first.equals(Protocol.R)) //"Disconnect" { System.out.println("Disconnected"); netGame= false; statusLabel.setText("Server downs or Your opponent quits"); reinit(); // closeClientSocket(); } } public void sendToServer(String s) { pout.println(s); } public void closeClientSocket() { try { out.close(); pout.close(); din.close(); dout.close(); sock.close(); } catch ( IOException ie ) { System.out.println("Can't close stream or socket");} } } /////////////////////////////////////////////////////////////////////////// class Board extends Canvas { int s; int size; int x,y,t; int index; int color; int x0, y0; int totalBlue=12; int totalGreen=12; int boardInfo[][] = new int [8][8]; int pawnInfo [] = new int [64]; public final int emptySquare = 0; public final int greenPawn = 1; public final int greenKing = 2; public final int bluePawn = 3; public final int blueKing = 4; //boolean greenTurn = true; boolean isGood = false; boolean restart = true; public Image gKingImage; public Image bKingImage; public Image bPawnImage; public Image gPawnImage; public Image pieceImage; public Board(int width, int height) { if(width < height) s = width; else s = height; size = s/8; } public void paint(Graphics g) { paintBoard(g); if (restart) { paintInitPieces(g); restart = false; //greenTurn = true; isGood = false; } paintPieces(g); if(totalGreen == 0 || totalBlue == 0) isWin(g); } public void makeOpponentMove( int index, int upIndex, int opponentImage) { //int upIndex = 8 * ((int) y/size) + ((int) x/size); this.index = index; System.out.println(this.index + " in makeOpponentMove"); switch(opponentImage) { case greenPawn: pieceImage = gPawnImage; break; case greenKing: pieceImage = gKingImage; break; case bluePawn: pieceImage = bPawnImage; break; case blueKing: pieceImage = bKingImage; break; } if( isValidMove(upIndex)) { greenTurn = !greenTurn; System.out.println("Is good move"); } isGood = false; repaint(); } public boolean mouseDown(Event e, int x, int y) { x0 = (x/size) * size; y0 = (y/size) * size; index = 8 * ((int) y/size) + ((int) x/size); //always check for correct turn and images if (greenSide && greenTurn && (pawnInfo[index] == greenPawn)) { pieceImage = gPawnImage; isGood = true; } else if (greenSide && greenTurn && (pawnInfo[index] == greenKing)) { pieceImage = gKingImage; isGood = true; } else if (blueSide && !greenTurn && (pawnInfo[index] == bluePawn)) { pieceImage = bPawnImage; isGood = true; } else if (blueSide && !greenTurn && (pawnInfo[index] == blueKing)) { pieceImage = bKingImage; isGood = true; } x0 = x0 + 19; y0 = y0 + 19; pieceMove = pawnInfo[index]; // this is for sending the move over the net return true; } public boolean mouseUp(Event e, int x, int y) { int upIndex = 8 * ((int) y/size) + ((int) x/size); if (x > 304 || y > 304 || x <0 || y < 0) isGood = false; if (isGood && isValidMove(upIndex)) { greenTurn = !greenTurn; if (netGame ) { client.sendToServer("Move " + index + " " + upIndex + " " + pieceMove); whoTurn.setText("Not your turn!"); System.out.println("Move " + index + " " + upIndex + " " + pieceMove); } } isGood = false; repaint(); return true; } public boolean mouseDrag(Event e, int x, int y) { if (isGood) move(x, y); return true; } public void move(int x, int y) { Graphics g = getGraphics(); g.setXORMode(Color.black); g.drawImage(pieceImage, x0 - 15, y0 - 15,this); g.drawImage(pieceImage, x - 15, y - 15,this); x0 = x; y0 = y; } public void paintBoard (Graphics g) { int s = 0; for(y=0;y<8;y++) for(x=0;x<8;x++) { color =(y+s)%2; if(color == 0) { boardInfo[y][x] = 0; g.setColor(Color.red); } else { boardInfo[y][x] = 1; g.setColor(Color.black); } g.fillRect(x*size,y*size,size,size); s++; } } public void paintInitPieces(Graphics g) { int temp; for(int j = 0; j < 8; j++) { int t = (j+1)%2; if (j < 3) temp = greenPawn; else if ( j < 5) temp = emptySquare; else temp = bluePawn; for(int i = t; i < 8; i=i+2) { x = (i * size) + 4; y = (j * size) + 4; pawnInfo[(8 * j) + i] = temp; } } } public void paintPieces(Graphics g) { for(int i=0; i < 64; i++) { if (pawnInfo[i] == greenPawn) { g.drawImage(gPawnImage, (int)(i%8)*size+4, (int)(i/8)*size+4,this); } else if (pawnInfo[i] == bluePawn) { g.drawImage(bPawnImage, (int)(i%8)*size+4, (int)(i/8)*size+4,this); } else if (pawnInfo[i] == greenKing) { g.drawImage(gKingImage, (int)(i%8)*size+4, (int)(i/8)*size+4,this); } else if (pawnInfo[i] == blueKing) { g.drawImage(bKingImage, (int)(i%8)*size+4, (int)(i/8)*size+4,this); } } } public boolean isValidMove(int destIdx) { if (pawnInfo[destIdx] != emptySquare) return false; switch( pawnInfo[index] ) { case bluePawn: return movePawn( bluePawn, blueKing, destIdx); case greenPawn: return movePawn( greenPawn, greenKing, destIdx); case greenKing: return moveKing( greenPawn, greenKing, destIdx); case blueKing: return moveKing( bluePawn, blueKing, destIdx); default: return true; } } public boolean movePawn(int Pawn, int King, int destIdx) { int dif = destIdx - index; if ( Pawn == bluePawn ) dif = -dif; if (dif == 7 || dif == 9) { pawnInfo[index] = emptySquare; if ((Pawn==bluePawn && destIdx >7) ||( Pawn==greenPawn && destIdx < 56)) pawnInfo[destIdx] = Pawn; else pawnInfo[destIdx] = King; return true; } else if (dif == 14 || dif == 18) { if (pawnInfo[index]==bluePawn) dif = -dif; if ( (pawnInfo[destIdx - (dif/2)] != Pawn) && (pawnInfo[destIdx -(dif/2)] != King) ) { pawnInfo[index] = emptySquare; if ((Pawn==greenPawn && destIdx < 56) || (Pawn==bluePawn && destIdx>7)) pawnInfo[destIdx] = Pawn; else pawnInfo[destIdx] = King; pawnInfo[destIdx - (dif/2)] = emptySquare; if ( Pawn == greenPawn || Pawn == greenKing ) totalBlue--; else totalGreen--; return true; } } else return false; return false; } public boolean moveKing(int Pawn, int King, int destIdx) { int dif = destIdx - index; int absDif = Math.abs(dif); if (absDif == 7 || absDif == 9) { pawnInfo[index] = emptySquare; pawnInfo[destIdx] = King; return true; } else if ((dif == 14 || dif == 18 || dif == -14 || dif == -18 )&& (pawnInfo[destIdx - (dif/2)] != Pawn && pawnInfo[destIdx - (dif/2)] != King)) pawnInfo[destIdx - (dif/2)] = emptySquare; else return false; pawnInfo[index] = emptySquare; pawnInfo[destIdx] = King; if ( Pawn == greenPawn || Pawn == greenKing ) totalBlue--; else totalGreen--; return true; } public boolean isWin(Graphics g) { g.setColor(Color.white); g.setFont(new Font("Times",Font.BOLD,30)); if(totalGreen == 0) g.drawString("Blue is the Winner",24,160); else g.drawString("Green is the Winner",14,160); return true; } // end of class Board. } //////////////////////////////////////////////////////////////////////// public boolean action( Event e, Object o) { if(e.target== connectButton) { connectButton.disable(); disconnectButton.setEnabled(true); startButton.setEnabled(false); restartButton.setEnabled(false); cd = new connectDlg(); cd.show(); } if(e.target== startButton) { startButton.setEnabled(false); if(netGame) { greenSide = true; blueSide= false; statusLabel.setText(id + " VS " + opponent + " : game beginning."); client.sendToServer("Start " + opponent + " " + id); whoTurn.setText("Your turn!"); restartButton.setEnabled(true); return true; } else { blueSide = true; greenSide = true; restartButton.setEnabled(true); statusLabel.setText("Start New Single Game"); remove(board); newBoard(); } } if(e.target== restartButton) { if ( netGame ) { client.sendToServer( Protocol.N ); opponentList.setEnabled(true); whoTurn.setText(""); statusLabel.setText("Choose your opponent"); } else statusLabel.setText("Start New Single Game"); remove(board); newBoard(); blueSide = true; greenSide = true; } if(e.target== disconnectButton) { // this.reinit(); connectButton.setEnabled(true); disconnectButton.setEnabled(false); if(client != null) { client.sendToServer("Disconnect " + id); client.closeClientSocket(); client.stop(); } netGame= false; client.stop(); client = null; startButton.setEnabled(true); connectButton.setEnabled(true); } if(e.target==opponentList) { opponent= opponentList.getSelectedItem(); client.sendToServer("Play " + opponent + " " + id); statusLabel.setText(id +" VS. " + opponent + ":game waiting"); startButton.setEnabled(true); opponentList.setEnabled(false); } return true; } }