import java.awt.Color; import java.awt.BorderLayout; import java.awt.event.*; import javax.swing.*; import java.awt.*; import java.awt.image.*; import java.net.*; import javax.swing.JComponent.*; import java.awt.geom.*; import java.io.*; /*------------------------------- This is a OX network Program @Author Sam Cavenagh @Date 1/11/02 -------------------------------*/ class OX extends JFrame implements ActionListener, MouseMotionListener, MouseListener, WindowListener { JLabel image; JLabel msg; JPanel panel; int mouseX, mouseY; JMenuBar menuBar; JMenu menu; JMenuItem menuItem; JRadioButtonMenuItem rbMenuItem; Image grid; Image x; Image o; //Graphics buffer stuff Graphics g; BufferedImage offscreen; Rectangle2D gridbox[];// GRID BOX boolean player1 = false; // is 1 player game running boolean player2 = false; //is 2 player game running boolean myTurn = false; //is it my turn boolean imX = true; //am i X ?? boolean goCenter = false; //For AI int board[][]; //Server Stuff ServerSocket serverSocket = null; Socket clientSocket = null; PrintWriter out; BufferedReader in; int movecount = 0; //used for game ai OX() { board = new int[3][3]; //Loading Images MediaTracker tracker = new MediaTracker(this);//Used to track loading of image Toolkit toolkit = Toolkit.getDefaultToolkit(); grid = toolkit.getImage("grid.gif"); o = toolkit.getImage("o.gif"); x = toolkit.getImage("x.gif"); tracker.addImage(grid, 1); tracker.addImage(o, 1); tracker.addImage(x, 1); try { //Waiting until image loaded. tracker.waitForAll(); } catch (InterruptedException e) { msg.setText("Load Error " + e); } offscreen = new BufferedImage(300, 300, BufferedImage.TYPE_3BYTE_BGR); g = offscreen.getGraphics(); g.setColor(Color.white); g.drawImage(grid, 0, 0, this); //Gridbox used to tell which board square user has clicked gridbox = new Rectangle2D.Double[9]; gridbox[0] = new Rectangle2D.Double(0, 0, 100, 100); gridbox[1] = new Rectangle2D.Double(100, 0, 100, 100); gridbox[2] = new Rectangle2D.Double(200, 0, 100, 100); gridbox[3] = new Rectangle2D.Double(0, 100, 100, 100); gridbox[4] = new Rectangle2D.Double(100, 100, 100, 100); gridbox[5] = new Rectangle2D.Double(200, 100, 100, 100); gridbox[6] = new Rectangle2D.Double(0, 200, 100, 100); gridbox[7] = new Rectangle2D.Double(100, 200, 100, 100); gridbox[8] = new Rectangle2D.Double(200, 200, 100, 100); ImageIcon imageI = new ImageIcon(offscreen); image = new JLabel(imageI); addMouseMotionListener(this); addMouseListener(this); requestFocus(); //Construction Menu menuBar = new JMenuBar(); //Build the first menu. menu = new JMenu("File"); menu.setMnemonic(KeyEvent.VK_F); menu.getAccessibleContext().setAccessibleDescription( "Game Options Can Be Found Here"); menuBar.add(menu); //File group of JMenuItems menuItem = new JMenuItem("1 Player", KeyEvent.VK_P); menuItem.getAccessibleContext().setAccessibleDescription( "Start Single Player Game"); menuItem.addActionListener( this ); menu.add(menuItem); menuItem = new JMenuItem("2 Player Server", KeyEvent.VK_S); menuItem.getAccessibleContext().setAccessibleDescription( "Be the server for a 2 player game"); menuItem.addActionListener( this ); menu.add(menuItem); menuItem = new JMenuItem("2 Player Client", KeyEvent.VK_C); menuItem.getAccessibleContext().setAccessibleDescription( "Connect to another 2 player Game"); menuItem.addActionListener( this ); menu.add(menuItem); menuItem = new JMenuItem("Close Connections", KeyEvent.VK_L); menuItem.getAccessibleContext().setAccessibleDescription( "Close Game Connection"); menuItem.addActionListener( this ); menu.add(menuItem); menuItem = new JMenuItem("Quit", KeyEvent.VK_Q); menuItem.getAccessibleContext().setAccessibleDescription( "Quit Game"); menuItem.addActionListener( this ); menu.add(menuItem); //Build second menu in the menu bar. menu = new JMenu("Options"); menu.getAccessibleContext().setAccessibleDescription( "Game Options"); menuBar.add(menu); //a group of radio button menu items ButtonGroup group = new ButtonGroup(); rbMenuItem = new JRadioButtonMenuItem("I'm X's"); rbMenuItem.setSelected(true); rbMenuItem.setMnemonic(KeyEvent.VK_X); rbMenuItem.addActionListener( this ); group.add(rbMenuItem); menu.add(rbMenuItem); rbMenuItem = new JRadioButtonMenuItem("I'm O's"); rbMenuItem.setMnemonic(KeyEvent.VK_O); rbMenuItem.addActionListener( this ); group.add(rbMenuItem); menu.add(rbMenuItem); addWindowListener(this); msg = new JLabel("Welcome to O&X's"); //Testing if images loaded correctly File f = new File("grid.gif"); if (!f.exists() && !f.isFile() && !f.canRead()) msg.setText("Unable to load file " +f.getAbsolutePath()); panel = new JPanel(); panel.setLayout(new BorderLayout()); panel.setBackground(Color.white); getContentPane().add(panel); panel.add(BorderLayout.NORTH, menuBar); panel.add(BorderLayout.CENTER, image); panel.add(BorderLayout.SOUTH, msg); resetBoard(); } public void actionPerformed(ActionEvent event){ String label = event.getActionCommand(); if (label.equals("Quit")){ //Closing Sockets on Quiting if(serverSocket != null) try{ serverSocket.close(); }catch(IOException e){} if(clientSocket != null) try{ clientSocket.close(); }catch(IOException e){} System.exit(0); //terminates the program } else if (label.equals("Close Connections")){ //Closing Sockets on Quiting if(serverSocket != null) try{ serverSocket.close(); }catch(IOException e){} if(clientSocket != null) try{ clientSocket.close(); }catch(IOException e){} msg.setText("Connection Closed"); resetBoard(); } else if(label.equals("1 Player")){ resetBoard(); movecount = 0; player1 = true; goCenter = false; msg.setText("1 Player"); otherPlayer(); } else if(label.equals("2 Player Server")){ resetBoard(); player2 = true; msg.setText("Listening for other Player"); listen(); } else if(label.equals("2 Player Client")){ resetBoard(); player2 = true; InputBox inputbox = new InputBox(this); String servername = inputbox.getString("Server Name"); msg.setText("Looking for other Player"); look(servername); } else if(label.equals("I'm X's") && imX == false){ Image temp = o; o = x; x = temp; imX = true; imageSwap(); } else if(label.equals("I'm O's") && imX == true){ Image temp = o; o = x; x = temp; imX = false; imageSwap(); } } private void look(String servername) { try{ clientSocket = new Socket(servername, 4444); out = new PrintWriter(clientSocket.getOutputStream(), true); in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); }catch(UnknownHostException e) { msg.setText("Server: " + servername + " Could not be Found"); }catch(IOException e2){ msg.setText("Open I/O Error: " + e2); } if (clientSocket != null) msg.setText("Connection Established"); new Waitformove(); } public void mousePressed( MouseEvent me) { if(myTurn == true){ int move = 0; if(gridbox[0].contains(mouseX, mouseY) && board[0][0] == 0) { drawImage(x, 1, 1); myTurn = false; move = 1; } if(gridbox[1].contains(mouseX, mouseY) && board[0][1] == 0) { drawImage(x, 2, 1); myTurn = false; move = 2; } if(gridbox[2].contains(mouseX, mouseY) && board[0][2] == 0) { drawImage(x, 3, 1); myTurn = false; move = 3; } if(gridbox[3].contains(mouseX, mouseY) && board[1][0] == 0) { drawImage(x, 4, 1); myTurn = false; move = 4; } if(gridbox[4].contains(mouseX, mouseY) && board[1][1] == 0) { drawImage(x, 5, 1); myTurn = false; move = 5; } if(gridbox[5].contains(mouseX, mouseY) && board[1][2] == 0) { drawImage(x, 6, 1); myTurn = false; move = 6; } if(gridbox[6].contains(mouseX, mouseY) && board[2][0] == 0) { drawImage(x, 7, 1); myTurn = false; move = 7; } if(gridbox[7].contains(mouseX, mouseY) && board[2][1] == 0) { drawImage(x, 8, 1); myTurn = false; move = 8; } if(gridbox[8].contains(mouseX, mouseY) && board[2][2] == 0) { drawImage(x, 9, 1); myTurn = false; move = 9; } if(player2) sendMove(move); checkforwin(); if(player1 == true && myTurn == false) otherPlayer(); if(player2 == true && myTurn == false) new Waitformove(); } } private void sendMove(int move) { out.println(Integer.toString(move)); } private void listen() { serverSocket = null; try { serverSocket = new ServerSocket(4444); } catch (IOException e) { msg.setText("Could not listen " + e); } new ListenThread(); } private void resetBoard() { for(int n = 0;n<3; n++) for(int q = 0;q<3;q++) board[n][q] = 0; myTurn = false; g.clearRect(0, 0, 300, 300); g.drawImage(grid, 0, 0, this); panel.repaint(); //Closing Sockets on Quiting if(serverSocket != null) try{ serverSocket.close(); }catch(IOException e){} if(clientSocket != null) try{ clientSocket.close(); }catch(IOException e){} } private void checkforwin() { boolean owins = false; boolean xwins = searcharray(3); if(xwins){ player1 = false; myTurn = false; movecount = 0; if(imX) msg.setText("X Wins"); else msg.setText("O Wins"); }else{ owins = searcharray(-3); if(owins){ player1 = false; player2 = false; myTurn = false; movecount = 0; if(imX) msg.setText("O Wins"); else msg.setText("X Wins"); }} if(board[0][0] != 0 && board[0][1] != 0 && board[0][2] != 0 && board[1][0] !=0 && board[1][1] != 0 && board[1][2] != 0 && board[2][0] != 0 && board[2][1] !=0 && board[2][2] != 0 && owins == false && xwins == false){ player1 = false; player2 = false; myTurn = false; movecount = 0; msg.setText("Draw"); } } private boolean searcharray(int lookingfor) { for(int n= 0;n < 3; n++) if(board[n][0] + board[n][1] + board[n][2] == lookingfor) return true; for(int n= 0;n < 3; n++) if(board[0][n] + board[1][n] + board[2][n] == lookingfor) return true; if(board[0][0] + board[1][1] + board[2][2] == lookingfor) return true; if(board[0][2] + board[1][1] + board[2][0] == lookingfor) return true; return false; } public void mouseMoved(MouseEvent me) { //ajusting so mouse point is as over image mouseX = me.getX() - 5; mouseY = me.getY() - 50; } private void drawImage(Image image, int gridno, int setto) { switch(gridno){ case 1: board[0][0] = setto; g.drawImage(image, 10, 10, this); break; case 2: board[0][1] = setto; g.drawImage(image, 110, 10, this); break; case 3: board[0][2] = setto; g.drawImage(image, 210, 10, this); break; case 4: board[1][0] = setto; g.drawImage(image, 10, 110, this); break; case 5: board[1][1] = setto; g.drawImage(image, 110, 110, this); break; case 6: board[1][2] = setto; g.drawImage(image, 210, 110, this); break; case 7: board[2][0] = setto; g.drawImage(image, 10, 210, this); break; case 8: board[2][1] = setto; g.drawImage(image, 110, 210, this); break; case 9: board[2][2] = setto; g.drawImage(image, 210, 210, this); break; } panel.repaint(); } private void otherPlayer() { boolean mademove = false; if(movecount == 0) drawImage(o, 1, -1); if(movecount == 1){ if(board[1][0]== 0 && board[0][1] == 0 && board[1][2] == 0 && board[2][1] == 0) { if(board[2][2] == 0) drawImage(o, 9, -1); else drawImage(o, 3, -1); }else{ goCenter = true; if(board[0][1] == 1) drawImage(o, 7, -1); else drawImage(o, 3, -1); } } if(movecount > 1) { mademove = checkForWin(-2); if(!mademove) mademove = checkForWin(2); } if(movecount == 2 && goCenter == true && board[1][1] == 0){ drawImage(o, 5, -1); mademove = true; } if(movecount == 2 && mademove == false){ if(board[2][0] == 0){ drawImage(o, 7, -1); mademove = true; } else if(board[0][2] == 0){ drawImage(o, 3, -1); mademove = true; } } if(movecount > 1 && mademove == false) nextFree(); movecount++; checkforwin(); if(player1) myTurn = true; } private boolean checkForWin(int sum) { //Checking Horrizontal & Vertical for(int n = 0; n < 3; n++){ if(board[n][0] + board[n][1] == sum && board[n][2] == 0){ drawImage(o, 3 + 3*n, -1); return true; } if(board[n][0] + board[n][2] == sum && board[n][1] == 0){ drawImage(o, 2 + 3*n, -1); return true; } if(board[n][1] + board[n][2] == sum && board[n][0] == 0){ drawImage(o, 1 + 3*n, -1); return true; } if(board[0][n] + board[1][n] == sum && board[2][n] == 0){ drawImage(o, 7 + 1*n, -1); return true; } if(board[0][n] + board[2][n] == sum && board[1][n] == 0){ drawImage(o, 4 + 1*n, -1); return true; } if(board[1][n] + board[2][n] == sum && board[0][n] == 0){ drawImage(o, 1 + 1*n, -1); return true; } } //Diaginals if(board[0][0] + board[1][1] == sum && board[2][2] == 0){ drawImage(o, 9, -1); return true; } if(board[0][0] + board[2][2] == sum && board[1][1] == 0){ drawImage(o, 5, -1); return true; } if(board[1][1] + board[2][2] == sum && board[0][0] == 0){ drawImage(o, 1, -1); return true; } if(board[0][2] + board[1][1] == sum && board[2][0] == 0){ drawImage(o, 7, -1); return true; } if(board[2][0] + board[1][1] == sum && board[0][2] == 0){ drawImage(o, 3, -1); return true; } if(board[2][0] + board[0][2] == sum && board[1][1] == 0){ drawImage(o, 5, -1); return true; } return false; } private void nextFree() { if(board[0][0] == 0) drawImage(o, 1, -1); else if(board[0][1] == 0) drawImage(o, 2, -1); else if(board[0][2] == 0) drawImage(o, 3, -1); else if(board[1][0] == 0) drawImage(o, 4, -1); else if(board[1][1] == 0) drawImage(o, 5, -1); else if(board[1][2] == 0) drawImage(o, 6, -1); else if(board[2][0] == 0) drawImage(o, 7, -1); else if(board[2][1] == 0) drawImage(o, 8, -1); else if(board[2][2] == 0) drawImage(o, 9, -1); } public void mouseDragged(MouseEvent e) {} public void mouseEntered( MouseEvent me ) {} public void mouseExited( MouseEvent me) {} public void mouseClicked( MouseEvent me) {} public void mouseReleased( MouseEvent me){} public static void main(String[] args){ OX frame = new OX(); frame.setTitle("O & X"); // frame.addWindowListener(l); frame.pack(); frame.setVisible(true); } private void imageSwap() { g.clearRect(0, 0, 300, 300); g.drawImage(grid, 0, 0, this); if(board[0][0] == 1) drawImage(x, 1, 1); if(board[0][0] == -1) drawImage(o, 1, -1); if(board[0][1] == 1) drawImage(x, 2, 1); if(board[0][1] == -1) drawImage(o, 2, -1); if(board[0][2] == 1) drawImage(x, 3, 1); if(board[0][2] == -1) drawImage(o, 3, -1); if(board[1][0] == 1) drawImage(x, 4, 1); if(board[1][0] == -1) drawImage(o, 4, -1); if(board[1][1] == 1) drawImage(x, 5, 1); if(board[1][1] == -1) drawImage(o, 5, -1); if(board[1][2] == 1) drawImage(x, 6, 1); if(board[1][2] == -1) drawImage(o, 6, -1); if(board[2][0] == 1) drawImage(x, 7, 1); if(board[2][0] == -1) drawImage(o, 7, -1); if(board[2][1] == 1) drawImage(x, 8, 1); if(board[2][1] == -1) drawImage(o, 8, -1); if(board[2][2] == 1) drawImage(x, 9, 1); if(board[2][2] == -1) drawImage(o, 9, -1); panel.repaint(); } public void windowClosing(WindowEvent e) { //Closing Sockets on Quiting if(serverSocket != null) try{ serverSocket.close(); }catch(IOException e2){} if(clientSocket != null) try{ clientSocket.close(); }catch(IOException e3){} System.exit(0); } public void windowClosed(WindowEvent e) { } public void windowOpened(WindowEvent e) { } public void windowIconified(WindowEvent e) { } public void windowDeiconified(WindowEvent e) { } public void windowActivated(WindowEvent e) { } public void windowDeactivated(WindowEvent e) { } class ListenThread implements Runnable{ Thread lt; //Listen Thread ListenThread() { lt = new Thread(this, "Listen"); //lt.setPriority(Thread.MAX_PRIORITY); lt.start(); // Starting thread } public void run() { clientSocket = null; try { //waits 60 seconds before timing out serverSocket.setSoTimeout(60000); clientSocket = serverSocket.accept(); } catch (InterruptedIOException ie) { msg.setText("Time Out"); } catch (IOException e) { msg.setText("Error Accept " + e); } try{ out = new PrintWriter(clientSocket.getOutputStream(), true); in = new BufferedReader( new InputStreamReader( clientSocket.getInputStream())); } catch (IOException e) { msg.setText("Error Out / In problem." + e); } msg.setText("Connection established"); myTurn = true; msg.setText("Its Your Turn"); } } class Waitformove implements Runnable{ Thread wt; //Wait Thread Waitformove() { wt = new Thread(this, "Wait"); //lt.setPriority(Thread.MAX_PRIORITY); wt.start(); // Starting thread } public void run() { int othermove= 0; String otherplayer = "1"; msg.setText("Waiting for Other Players Move"); repaint(); try{ otherplayer = in.readLine(); }catch(IOException e) { msg.setText("Read Error: " + e); } try{ othermove = Integer.parseInt(otherplayer); }catch(NumberFormatException b){ msg.setText("Message Error " + b); } drawImage(o, othermove, -1); checkforwin(); if(player2){ msg.setText("Your Turn"); myTurn = true; } } } }