1 / 24

Java 網路程式設計

Java 網路程式設計. 第 18 章 完整的實例探討. Java 網路應用開發. Java 網路程式設計可以用來開發各種應用系統 在練習開發實例的過程中,會對於各種語法與 API 有比較深刻的認識,所以盡可能地自己運用前面所學到的方法來進行開發,解決困難,這樣應該就能跨過初學者的門檻. BestMove.java. // 記錄最佳的下棋位置,包括對應的欄 (column) 與列 (row) // final class BestMove { int row; int column; int val;

juliet
Download Presentation

Java 網路程式設計

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Java網路程式設計 第18章 完整的實例探討

  2. Java網路應用開發 • Java網路程式設計可以用來開發各種應用系統 • 在練習開發實例的過程中,會對於各種語法與API有比較深刻的認識,所以盡可能地自己運用前面所學到的方法來進行開發,解決困難,這樣應該就能跨過初學者的門檻

  3. BestMove.java // 記錄最佳的下棋位置,包括對應的欄(column)與列(row) // final class BestMove { int row; int column; int val; // val代表目前的盤勢 public BestMove( int v ) { this( v, 0, 0 ); } public BestMove( int v, int r, int c ) { val = v; row = r; column = c; } }

  4. TicTacToe.java class TicTacToe { // 用一些常數值的名稱讓程式碼更容易閱讀 public static final int HUMANOPP = 0; public static final int COMPUTER = 1; public static final int NOLABEL = 2; // 棋盤位置是空的,可以下 public static final int HUMANOPP_WIN = 0; public static final int DRAW = 1; // 平手 public static final int UNKNOWN = 2; // 還未知勝負 public static final int COMPUTER_WIN = 3; public TicTacToe( ) { clearBoard( ); } public int [ ] [ ] getBoard( ) { return board; } // 決定下一步該圈(O)或叉(X) public BestMove TryOneMove( int YouKnowMe ) { int opp; // 敵方 BestMove GiveItATry; // 敵方的最佳對策 int CurrentResult; int bestRow = 0; int bestColumn = 0; int value; // 呼叫CheckResult()看目前的盤勢,假如還未知勝負,才繼續往下執行 if( ( CurrentResult = CheckResult( ) ) != UNKNOWN ) return new BestMove( CurrentResult ); if( YouKnowMe == COMPUTER ) { // 以下棋的人來說,我們會假設他會設法贏 opp = HUMANOPP; value = HUMANOPP_WIN; } else { // 以電腦來說,當然也是會設法贏 opp = COMPUTER; value = COMPUTER_WIN; } // 每一步可能下的棋步都要考慮到 for( int row = 0; row < 3; row++ ) for( int column = 0; column < 3; column++ ) if( squareIsNOLABEL( row, column ) ) // 只有空棋才能下 { // 目前呼叫TryOneMove的那一邊先下一步 place( row, column, YouKnowMe ); // 對手呼叫TryOneMove選擇一步好棋步 GiveItATry = TryOneMove( opp ); // 因為只是預測,假設情況下的棋步要還原 place( row, column, NOLABEL ); // 不管是那一邊,只要呼叫TryOneMove,就要選最佳的棋步 if( YouKnowMe == COMPUTER && GiveItATry.val > value || YouKnowMe == HUMANOPP && GiveItATry.val < value ) { value = GiveItATry.val; bestRow = row; bestColumn = column; } } return new BestMove( value, bestRow, bestColumn ); } // 下手, 同時檢查下的位置是否還是空位, 或是否有超出棋盤範圍 public boolean recordMoveInArray( int YouKnowMe, int row, int column ) { if( row < 0 || row >= 3 || column < 0 || column >= 3 || board[ row ][ column ] != NOLABEL ) return false; board[ row ][ column ] = YouKnowMe; return true; } // 其他相關的有用程序 public void clearBoard( ) { for( int i = 0; i < 3; i++ ) for( int j = 0; j < 3; j++ ) board[ i ][ j ] = NOLABEL; } public boolean boardIsFull( ) { for( int row = 0; row < 3; row++ ) for( int column = 0; column < 3; column++ ) if( board[ row ][ column ] == NOLABEL ) return false; return true; } boolean ResultIsWin( int YouKnowMe ) { int row, column; // 查看是否有整列排成的情況 for( row = 0; row < 3; row++ ) { for( column = 0; column < 3; column++ ) if( board[ row ][ column ] != YouKnowMe ) break; if( column >= 3 ) return true; } // 查看是否有整行排成的情況 for( column = 0; column < 3; column++ ) { for( row = 0; row < 3; row++ ) if( board[ row ][ column ] != YouKnowMe ) break; if( row >= 3 ) return true; } // 查看是否有對角線排成的情況 if( board[ 1 ][ 1 ] == YouKnowMe && board[ 2 ][ 2 ] == YouKnowMe && board[ 0 ][ 0 ] == YouKnowMe ) return true; if( board[ 0 ][ 2 ] == YouKnowMe && board[ 1 ][ 1 ] == YouKnowMe && board[ 2 ][ 0 ] == YouKnowMe ) return true; return false; } private int [ ] [ ] board = new int[ 3 ][ 3 ]; // 下手 private void place( int row, int column, int piece ) { board[ row ][ column ] = piece; } private boolean squareIsNOLABEL( int row, int column ) { return board[ row ][ column ] == NOLABEL; } // 確認目前的戰況 private int CheckResult( ) { return ResultIsWin( COMPUTER ) ? COMPUTER_WIN : ResultIsWin( HUMANOPP ) ? HUMANOPP_WIN : boardIsFull( )? DRAW : UNKNOWN; } }

  5. TestTicTacToe.java import java.awt.*; import java.awt.event.*; public class TestTicTacToe extends Frame implements WindowListener, ActionListener { // 啟動棋盤, 等待使用者點按 public void init( ) { setLayout( new GridLayout( 3, 3 ) ); for( int i = 0; i < 3; i++ ) for( int j = 0; j < 3; j++ ) { BookKeepArray[ i ][ j ] = new Button( ); add( BookKeepArray[ i ][ j ] ); BookKeepArray[ i ][ j ].addActionListener( this ); BookKeepArray[ i ][ j ].setFont(new Font("Serif", Font.BOLD, 72)); } addWindowListener( this ); newBoard( ); } public TestTicTacToe( ) { init( ); } // 重玩 ! 新建一個TicTacToe的案例, 清除按鈕上的標籤 public void newBoard( ) { t = new TicTacToe( ); for( int i = 0; i < 3; i++ ) for( int j = 0; j < 3; j++ ) { BookKeepArray[ i ][ j ].setLabel( "" ); // 無標籤 BookKeepArray[ i ][ j ].setEnabled( true ); // 可點按下棋步 } } private int KeepGameInteresting = 0; // 為電腦選一個棋步 // 若是電腦先下,利用KeepGameInteresting隨機選擇棋步,增加遊戲的變化 // 否則就要呼叫TryOneMove來選個好棋步 public void doComputerMove( boolean predictToWin ) { BestMove ComputerMove; if( predictToWin ) ComputerMove = t.TryOneMove( TicTacToe.COMPUTER ); else { ComputerMove = new BestMove( 0, KeepGameInteresting % 3, KeepGameInteresting / 3 ); KeepGameInteresting = ( KeepGameInteresting + 1 ) % 9; } System.out.println( " 電腦選的列的位置 = " + ComputerMove.row + " 電腦選的行的位置 = " + ComputerMove.column ); BookKeepArray[ ComputerMove.row ][ ComputerMove.column ].setLabel( computerYouKnowMe ); BookKeepArray[ ComputerMove.row ][ ComputerMove.column ].setEnabled( false ); t.recordMoveInArray( TicTacToe.COMPUTER, ComputerMove.row, ComputerMove.column ); } // 遊戲結束時(注意結束的條件), 開始另一盤, 圈叉對調 public boolean GameOverRest( boolean condition, String message, boolean ComputerMoves ) { if( condition ) { System.out.println( message ); System.out.println( "重新開始新的一盤遊戲!" ); newBoard( ); if( ComputerMoves ) { System.out.println( "電腦先下囉!" ); computerYouKnowMe = "X"; HUMANOPPYouKnowMe = "O"; doComputerMove( false ); } else { HUMANOPPYouKnowMe = "X"; computerYouKnowMe = "O"; System.out.println( "您先下吧!" ); } } return condition; } // WindowListener介面的實作 public void windowClosing( WindowEvent event ) { System.exit( 0 ); } public void windowClosed( WindowEvent event ) { } public void windowDeiconified( WindowEvent event ) { } public void windowIconified( WindowEvent event ) { } public void windowActivated( WindowEvent event ) { } public void windowDeactivated( WindowEvent event ) { } public void windowOpened( WindowEvent event ) { } // 處理按鈕點選(button click)事件,注意按錯時的處理方式 public void actionPerformed( ActionEvent evt ) { if( evt.getSource( ) instanceof Button ) { // 棋手每按一下棋盤,就要進行處理 ( (Button)evt.getSource( ) ).setLabel( HUMANOPPYouKnowMe ); // 外觀改變 ( (Button)evt.getSource( ) ).setEnabled( false ); // 已下棋步,不能再按 for( int i = 0; i < 3; i++ ) for( int j = 0; j < 3; j++ ) if( evt.getSource( ) == BookKeepArray[ i ][ j ] ) // 在陣列資料結構上記載棋步 t.recordMoveInArray( TicTacToe.HUMANOPP, i, j ); // 在棋手下完後,檢查勝負,棋盤滿而無勝負就是平手(Draw) if( GameOverRest( t.boardIsFull( ), "DRAW", true ) ) return; // 換電腦下 doComputerMove( true ); // 檢查勝負 GameOverRest( t.ResultIsWin( TicTacToe.COMPUTER ), "嘿!我贏了", true ); // 檢查是否平手(Draw) GameOverRest( t.boardIsFull( ), "DRAW", false ); return; // 等棋手下棋 } } // 主程式, 建立新棋盤,開始玩! public static void main( String [ ] args ) { Frame f = new TestTicTacToe( ); f.pack( ); f.show( ); // 啟始之後,等棋手下棋 } private Button [ ][ ] BookKeepArray = new Button[ 3 ][ 3 ];//開始時棋盤是空的 private TicTacToe t; private String computerYouKnowMe = "O"; private String HUMANOPPYouKnowMe = "X"; }

  6. 網路遊戲 • 圈圈叉叉(Tic Tac Toe)的遊戲 • 單機版的設計 • 網路版的設計

  7. TicTacToe類別裡定義的TryOneMove • 在目前的盤勢下找出最佳的棋步 • 預測與思考

  8. 圈圈叉叉(Tic Tac Toe)的遊戲

  9. 網路版設計上要注意的事項 • 注意TestTicTacToe與TestTicTacToe1兩個程式在通訊時所使用的host address與port number的分配。 • 棋步的傳送與處理細節。 • 發現平手或是分出勝負時重新開始的處理方式。

  10. 網路版TicTacToe.java class TicTacToe { // 用一些常數值的名稱讓程式碼更容易閱讀 public static final int HUMANOPP = 0; public static final int COMPUTER = 1; public static final int NOLABEL = 2; // 棋盤位置是空的,可以下 public static final int HUMANOPP_WIN = 0; public static final int DRAW = 1; // 平手 public static final int UNKNOWN = 2; // 還未知勝負 public static final int COMPUTER_WIN = 3; public TicTacToe( ) { clearBoard( ); } public int [ ] [ ] getBoard( ) { return board; } // 下手, 同時檢查下的位置是否還是空位, 或是否有超出棋盤範圍 public boolean recordMoveInArray( int YouKnowMe, int row, int column ) { if( row < 0 || row >= 3 || column < 0 || column >= 3 || board[ row ][ column ] != NOLABEL ) return false; board[ row ][ column ] = YouKnowMe; return true; } // 其他相關的有用程序 public void clearBoard( ) { for( int i = 0; i < 3; i++ ) for( int j = 0; j < 3; j++ ) board[ i ][ j ] = NOLABEL; } public boolean boardIsFull( ) { for( int row = 0; row < 3; row++ ) for( int column = 0; column < 3; column++ ) if( board[ row ][ column ] == NOLABEL ) return false; return true; } boolean ResultIsWin( int YouKnowMe ) { int row, column; // 查看是否有整列排成的情況 for( row = 0; row < 3; row++ ) { for( column = 0; column < 3; column++ ) if( board[ row ][ column ] != YouKnowMe ) break; if( column >= 3 ) return true; } // 查看是否有整行排成的情況 for( column = 0; column < 3; column++ ) { for( row = 0; row < 3; row++ ) if( board[ row ][ column ] != YouKnowMe ) break; if( row >= 3 ) return true; } // 查看是否有對角線排成的情況 if( board[ 1 ][ 1 ] == YouKnowMe && board[ 2 ][ 2 ] == YouKnowMe && board[ 0 ][ 0 ] == YouKnowMe ) return true; if( board[ 0 ][ 2 ] == YouKnowMe && board[ 1 ][ 1 ] == YouKnowMe && board[ 2 ][ 0 ] == YouKnowMe ) return true; return false; } private int [ ] [ ] board = new int[ 3 ][ 3 ]; // 下手 private void place( int row, int column, int piece ) { board[ row ][ column ] = piece; } private boolean squareIsNOLABEL( int row, int column ) { return board[ row ][ column ] == NOLABEL; } // 確認目前的戰況 private int CheckResult( ) { return ResultIsWin( COMPUTER ) ? COMPUTER_WIN : ResultIsWin( HUMANOPP ) ? HUMANOPP_WIN : boardIsFull( )? DRAW : UNKNOWN; } }

  11. TestTicTacToe .java import java.awt.*; import java.awt.event.*; import java.io.*; // new import java.net.*; // new import java.util.StringTokenizer; // new // 我們先把TestTicTacToe當成Human這一邊的 public class TestTicTacToe extends Frame implements WindowListener, ActionListener { int portNo; InetAddress addr; DatagramSocket ssocket; DatagramSocket rsocket; // 啟動棋盤, 等待使用者點按 public void init( ) { this.portNo =5555; System.out.print("Please input the IP address of destination :"); BufferedReader uip= new BufferedReader(new InputStreamReader(System.in)); try{ String ServerIP=uip.readLine(); this.addr=InetAddress.getByName(ServerIP); this.ssocket=new DatagramSocket(1700); this.rsocket=new DatagramSocket(1800); } catch (SocketException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } setLayout( new GridLayout( 3, 3 ) ); for( int i = 0; i < 3; i++ ) for( int j = 0; j < 3; j++ ) { BookKeepArray[ i ][ j ] = new Button( ); add( BookKeepArray[ i ][ j ] ); BookKeepArray[ i ][ j ].addActionListener( this ); BookKeepArray[ i ][ j ].setFont(new Font("Serif", Font.BOLD, 100)); } addWindowListener( this ); newBoard( ); } public TestTicTacToe(String whoami ) { super("TestTicTacToe (was human): "+whoami); init( ); } // 重玩 ! 新建一個TicTacToe的案例, 清除按鈕上的標籤 public void newBoard( ) { t = new TicTacToe( ); for( int i = 0; i < 3; i++ ) for( int j = 0; j < 3; j++ ) { BookKeepArray[ i ][ j ].setLabel( "" ); // 無標籤 BookKeepArray[ i ][ j ].setEnabled( true ); // 可點按下棋步 } } private int KeepGameInteresting = 0; // 遊戲結束時(注意結束的條件), 開始另一盤, 圈叉不對調 public boolean GameOverRest( boolean condition, String message, boolean ComputerMoves ) { if( condition ) { System.out.println( message ); System.out.println( "重新開始新的一盤遊戲!" ); newBoard( ); if( ComputerMoves ) { System.out.println( "先下囉!" ); } else { System.out.println( "等對方下吧!" ); byte buffer1[]=new byte[100]; try { DatagramPacket packet1=new DatagramPacket(buffer1,100,this.addr,1600); System.out.println("wait on receiving ...等對方下!"); this.rsocket.receive(packet1); String msg1=new String(buffer1,0,packet1.getLength()); System.out.println("收到下面的訊息 : " + msg1); StringTokenizer stok1 = new StringTokenizer(msg1,","); int dontcare = Integer.parseInt(stok1.nextToken()); int x1=Integer.parseInt(stok1.nextToken()); int y1=Integer.parseInt(stok1.nextToken()); BookKeepArray[x1][y1].setLabel(computerYouKnowMe); BookKeepArray[x1][y1].setEnabled(false); t.recordMoveInArray( TicTacToe.COMPUTER, x1, y1 ); }catch (SocketException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }// end } } return condition; } // WindowListener介面的實作 public void windowClosing( WindowEvent event ) { System.exit( 0 ); } public void windowClosed( WindowEvent event ) { } public void windowDeiconified( WindowEvent event ) { } public void windowIconified( WindowEvent event ) { } public void windowActivated( WindowEvent event ) { } public void windowDeactivated( WindowEvent event ) { } public void windowOpened( WindowEvent event ) { } // 處理按鈕點選(button click)事件,注意按錯時的處理方式 public void actionPerformed( ActionEvent evt ) { if( evt.getSource( ) instanceof Button ) { // 棋手每按一下棋盤,就要進行處理 ( (Button)evt.getSource( ) ).setLabel( HUMANOPPYouKnowMe ); // 外觀改變 ( (Button)evt.getSource( ) ).setEnabled( false ); // 已下棋步,不能再按 int i=0; int j=0; int ii=0, jj=0; for( i = 0; i < 3; i++ ) for( j = 0; j < 3; j++ ) if( evt.getSource( ) == BookKeepArray[ i ][ j ] ) // 在陣列資料結構上記載棋步 { t.recordMoveInArray( TicTacToe.HUMANOPP, i, j ); ii=i; jj=j; }; System.out.println("TestTicTacToe : (i,j) "+ii+" "+jj); // 開始準備傳送棋步 Integer oi = new Integer(ii); Integer oj = new Integer(jj); Integer oid = new Integer(TicTacToe.HUMANOPP); String dataOut = oid.toString()+","+oi.toString()+","+oj.toString(); int oLength=dataOut.length(); byte buffer[]=new byte[oLength]; System.out.println(dataOut); buffer=dataOut.getBytes(); try { DatagramPacket packet=new DatagramPacket(buffer,oLength,this.addr,1600); System.out.println(this.portNo); this.ssocket.send(packet); System.out.println("sent ..., check!"); // 在棋手下完後,檢查勝負,棋盤滿而無勝負就是平手(Draw) if (GameOverRest( t.ResultIsWin( TicTacToe.HUMANOPP ), "嘿!我贏了", true )) return; if( GameOverRest( t.boardIsFull( ), "DRAW", true ) ) return; // 換對方下(即之前的computer) System.out.println("human wait on receiving ..."); DatagramPacket packet1=new DatagramPacket(buffer,oLength,this.addr,1800); this.rsocket.receive(packet1); String msg=new String(buffer,0,packet1.getLength()); System.out.println("收到下面的訊息 : " + msg); StringTokenizer stok = new StringTokenizer(msg,","); int dontcare = Integer.parseInt(stok.nextToken()); int x=Integer.parseInt(stok.nextToken()); int y=Integer.parseInt(stok.nextToken()); BookKeepArray[x][y].setLabel(computerYouKnowMe); BookKeepArray[x][y].setEnabled(false); t.recordMoveInArray( TicTacToe.COMPUTER, x, y ); } catch (SocketException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } // 檢查勝負 GameOverRest( t.ResultIsWin( TicTacToe.COMPUTER ), "嘿!我輸了", false ); // 檢查是否平手(Draw) GameOverRest( t.boardIsFull( ), "DRAW", true ); return; // 等棋手下棋 } } // 主程式, 建立新棋盤,開始玩! public static void main( String [ ] args ) { Frame f = new TestTicTacToe("使用X"); f.pack( ); f.show( ); // 啟始之後,等棋手下棋 } private Button [ ][ ] BookKeepArray = new Button[ 3 ][ 3 ];//開始時棋盤是空的 private TicTacToe t; private String computerYouKnowMe = "O"; private String HUMANOPPYouKnowMe = "X"; }

  12. TestTicTacToe1.java import java.awt.*; import java.awt.event.*; import java.io.*; // new import java.net.*; // new import java.util.StringTokenizer; // new // 我們先把TestTicTacToe1當成Computer這一邊的 public class TestTicTacToe1 extends Frame implements WindowListener, ActionListener { int portNo; InetAddress addr; DatagramSocket ssocket; DatagramSocket rsocket; // 啟動棋盤, 等待使用者點按 public void init( ) { this.portNo =5556; System.out.print("Please input the IP address of destination :"); BufferedReader uip= new BufferedReader(new InputStreamReader(System.in)); try{ String ServerIP=uip.readLine(); this.addr=InetAddress.getByName(ServerIP); this.ssocket=new DatagramSocket(1500); this.rsocket=new DatagramSocket(1600); } catch (SocketException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } setLayout( new GridLayout( 3, 3 ) ); for( int i = 0; i < 3; i++ ) for( int j = 0; j < 3; j++ ) { BookKeepArray[ i ][ j ] = new Button( ); add( BookKeepArray[ i ][ j ] ); BookKeepArray[ i ][ j ].addActionListener( this ); BookKeepArray[ i ][ j ].setFont(new Font("Serif", Font.BOLD, 100)); } addWindowListener( this ); newBoard( ); //_____________________________________________________ // Computer這一邊一開始先等human下! byte buffer1[]=new byte[100]; try { DatagramPacket packet1=new DatagramPacket(buffer1,100,this.addr,1600); System.out.println("wait on receiving ...等對方下!"); this.rsocket.receive(packet1); String msg1=new String(buffer1,0,packet1.getLength()); System.out.println("收到下面的訊息 : " + msg1); StringTokenizer stok1 = new StringTokenizer(msg1,","); int dontcare = Integer.parseInt(stok1.nextToken()); int x1=Integer.parseInt(stok1.nextToken()); int y1=Integer.parseInt(stok1.nextToken()); BookKeepArray[x1][y1].setLabel(HUMANOPPYouKnowMe); BookKeepArray[x1][y1].setEnabled(false); t.recordMoveInArray( TicTacToe.HUMANOPP, x1, y1 ); }catch (SocketException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } //_____________________________________________________ } public TestTicTacToe1( String whoami) { super("TestTicTacToe1 (was computer: " +whoami); init( ); } // 重玩 ! 新建一個TicTacToe的案例, 清除按鈕上的標籤 public void newBoard( ) { t = new TicTacToe( ); for( int i = 0; i < 3; i++ ) for( int j = 0; j < 3; j++ ) { BookKeepArray[ i ][ j ].setLabel( "" ); // 無標籤 BookKeepArray[ i ][ j ].setEnabled( true ); // 可點按下棋步 } } private int KeepGameInteresting = 0; // 遊戲結束時(注意結束的條件), 開始另一盤, 圈叉不對調 // 平手時由human先下, 否則由贏的先下 public boolean GameOverRest( boolean condition, String message, boolean ComputerMoves ) { if( condition ) { System.out.println( message ); System.out.println( "重新開始新的一盤遊戲!" ); newBoard( ); if( ComputerMoves ) { System.out.println( "先下囉!" ); } else { System.out.println( "等對方先下吧!" ); byte buffer2[]=new byte[100]; try { DatagramPacket packet2=new DatagramPacket(buffer2,100,this.addr,1600); System.out.println("wait on receiving ...等對方下!"); this.rsocket.receive(packet2); String msg2=new String(buffer2,0,packet2.getLength()); System.out.println("收到下面的訊息 : " + msg2); StringTokenizer stok2 = new StringTokenizer(msg2,","); int dontcare2 = Integer.parseInt(stok2.nextToken()); int x2=Integer.parseInt(stok2.nextToken()); int y2=Integer.parseInt(stok2.nextToken()); BookKeepArray[x2][y2].setLabel(HUMANOPPYouKnowMe); BookKeepArray[x2][y2].setEnabled(false); t.recordMoveInArray( TicTacToe.HUMANOPP, x2, y2 ); }catch (SocketException ex) { ex.printStackTrace(); } catch (IOException ex) { ex.printStackTrace(); } } } return condition; } // WindowListener介面的實作 public void windowClosing( WindowEvent event ) { System.exit( 0 ); } public void windowClosed( WindowEvent event ) { } public void windowDeiconified( WindowEvent event ) { } public void windowIconified( WindowEvent event ) { } public void windowActivated( WindowEvent event ) { } public void windowDeactivated( WindowEvent event ) { } public void windowOpened( WindowEvent event ) { } // 處理按鈕點選(button click)事件,注意按錯時的處理方式 public void actionPerformed( ActionEvent evt ) { if( evt.getSource( ) instanceof Button ) { // 棋手每按一下棋盤,就要進行處理 ( (Button)evt.getSource( ) ).setLabel( computerYouKnowMe ); // 外觀改變 ( (Button)evt.getSource( ) ).setEnabled( false ); // 已下棋步,不能再按 int i=0; int j=0; int ii=0, jj=0; for( i = 0; i < 3; i++ ) for( j = 0; j < 3; j++ ) if( evt.getSource( ) == BookKeepArray[ i ][ j ] ) // 在陣列資料結構上記載棋步 { t.recordMoveInArray( TicTacToe.COMPUTER, i, j ); ii=i; jj=j;}; System.out.println("TestTicTacToe1 : (i,j) "+ii+" "+jj); Integer oi = new Integer(ii); Integer oj = new Integer(jj); Integer oid = new Integer(TicTacToe.COMPUTER); String dataOut = oid.toString()+","+oi.toString()+","+oj.toString(); int oLength=dataOut.length(); byte buffer[]=new byte[oLength]; System.out.println(dataOut); buffer=dataOut.getBytes(); try { DatagramPacket packet=new DatagramPacket(buffer,oLength,this.addr,1800); System.out.println(this.portNo); this.ssocket.send(packet); System.out.println("sent ..., check!"); // 在棋手下完後,檢查勝負,棋盤滿而無勝負就是平手(Draw) if (GameOverRest( t.ResultIsWin( TicTacToe.COMPUTER ), "嘿!我贏了", true )) return; if( GameOverRest( t.boardIsFull( ), "DRAW", false ) ) return; // 換Human下 DatagramPacket packet1=new DatagramPacket(buffer,oLength,this.addr,1600); System.out.println("comp wait receiving ..."); this.rsocket.receive(packet1); String msg=new String(buffer,0,packet1.getLength()); System.out.println("收到下面的訊息 : " + msg); StringTokenizer stok = new StringTokenizer(msg,","); int dontcare = Integer.parseInt(stok.nextToken()); int x=Integer.parseInt(stok.nextToken()); int y=Integer.parseInt(stok.nextToken()); BookKeepArray[x][y].setLabel(HUMANOPPYouKnowMe); BookKeepArray[x][y].setEnabled(false); t.recordMoveInArray( TicTacToe.HUMANOPP, x, y ); } catch (SocketException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } // 檢查勝負 GameOverRest( t.ResultIsWin( TicTacToe.HUMANOPP ), "嘿!我輸了", false ); // 檢查是否平手(Draw) GameOverRest( t.boardIsFull( ), "DRAW", false ); return; // 等棋手下棋 } } // 主程式, 建立新棋盤,開始玩! public static void main( String [ ] args ) { Frame f = new TestTicTacToe1("使用O" ); f.pack( ); f.show( ); // 啟始之後,等棋手下棋 } private Button [ ][ ] BookKeepArray = new Button[ 3 ][ 3 ];//開始時棋盤是空的 private TicTacToe t; private String computerYouKnowMe = "O"; private String HUMANOPPYouKnowMe = "X"; }

  13. 變成網路遊戲的TicTacToe

  14. Hypercube • Hypercube是一種交換式的多電腦(Switched multi-computer)架構 • 各頂點代表一個CPU,兩個立方體對應的頂點彼此相連,CPU有運算的能力,連接的頂點之間則可互相交換訊息

  15. d維度(d-dimensional)的hypercube • 在d維度(d-dimensional)的hypercube network中,每個節點會連上每個維度中的一個節點,通常會以d個二進位元來表示一個d維度hypercube中的節點 • 以3-dimensional的hypercube為例,含有8個節點

  16. 3-dimensional hypercube

  17. hypercube的訊息路由方式

  18. 從兩個3維度hypercubes來組成一個4維度hypercube

  19. 導入平行演算法(parallel algorithms)的概念 • 在hypercube中執行quicksort運算的方式 • divide-and-conquer類型的排序演算法 • quicksort(list, start, end) • { • if (start<end) { • partition(list, start, end, pivotIndex); • quicksort(list, start, pivotIndex-1); // 遞迴呼叫 • quicksort(list, pivotIndex+1, end); // 遞迴呼叫 • } • }

  20. 多處理器分配資料與運算

  21. hypercube中進行paralle quicksort時各階段的運算與溝通

  22. 資料的分送

  23. odd-even mergesort

  24. 認識hypercube的觀念

More Related