Java 多客户端版 2048 源码

byte包

Calss Byte

 1 package Byte;
 2 import java.io.*;
 3 public class Byte implements Serializable{
 4     public static byte[] int2Byte(int []intValue){
 5         int length=intValue.length;
 6         byte[] b=new byte[length*4];
 7         for(int i=0;i<length;i++){
 8             for(int j=0;j<4;j++){
 9                 b[i*4+j]=(byte)(intValue[i]>>8*(3-j) & 0xFF);
10             }
11         }
12         return b;
13     }
14     public static int[] byte2Int(byte[] b){
15         int len=b.length/4;
16         int []intValue=new int[len];
17         for(int j=0;j<len;j++){
18             for(int i=0;i<4;i++){
19                 intValue[j] +=(b[j*4+i] & 0xFF)<<(8*(3-i));
20             }
21         }
22         return intValue;
23     }
24     public static Object ByteToObject(byte[] bytes){
25         Object obj = null;
26         try {
27             ByteArrayInputStream bi = new ByteArrayInputStream(bytes);
28             ObjectInputStream oi = new ObjectInputStream(bi);
29     
30             obj = (Object) oi.readObject();
31     
32             bi.close();
33             oi.close();
34         }
35         catch(Exception e) {
36             e.printStackTrace();
37         }
38         return obj;
39     }
40     public static byte[] ObjectToByte(Object obj)
41     {
42         byte[] bytes=null;
43         try {
44             //object to bytearray
45             ByteArrayOutputStream bo = new ByteArrayOutputStream();
46             ObjectOutputStream oo = new ObjectOutputStream(bo);
47             oo.writeObject(obj);
48             bytes = bo.toByteArray();
49             bo.close();
50             oo.close();   
51         }
52         catch(Exception e) {
53             e.printStackTrace();
54         }
55         return(bytes);
56    }
57 }

Client 包

class Window

  1 package Client;
  2 import javax.swing.*;
  3 import java.awt.*;
  4 import java.awt.event.*;
  5 import java.io.DataInputStream;
  6 import java.io.DataOutputStream;
  7 import java.io.IOException;
  8 import java.net.DatagramPacket;
  9 import java.net.InetAddress;
 10 import java.net.InetSocketAddress;
 11 import java.net.MulticastSocket;
 12 import java.net.Socket;
 13 
 14 import Byte.Byte;
 15 /**
 16  * @author 荣钦
 17  *
 18  */
 19 public class Window extends JFrame implements KeyListener, Runnable {
 20     /**
 21      * 
 22      */
 23     private static final long serialVersionUID = -7379543475187728667L;
 24     private Container cn;
 25     private JLabel sc,bestsc;
 26     mainFrame mainframe;
 27     JLabel statue = new JLabel();
 28     JButton [][]piece = new JButton[4][4];
 29 //    String InetAddr = "192.168.0.101";
 30     String InetAddr = "127.0.0.1";
 31 //    String InetAddr = "10.22.149.112";
 32     Socket socket=null;
 33     DataInputStream in=null;
 34     DataOutputStream out=null;
 35     int port=5858;                                   //组播的端口
 36     InetAddress group=null;                          //组播组的地址
 37     MulticastSocket Msocket=null;                    //多点广播套接字 
 38     Thread Receive; 
 39     Window(){
 40         int length=376,width=679;
 41         double dw=360/9;
 42         /*
 43          * 9:16
 44          * 1:4:4:4:4:1
 45          * 7:8:1
 46          */
 47         this.setSize(length, width);
 48         this.setLocationRelativeTo(null);                  //让窗体居中显示
 49         this.setLayout(null);
 50         addKeyListener(this);
 51         cn=getContentPane();
 52         
 53         statue.setBounds((int)(dw*4),(int)(dw*10),(int)(dw*3),+(int)dw);
 54         cn.add(statue);
 55         sc = new JLabel();
 56         bestsc = new JLabel();
 57         bestsc.setBounds((int)(6*dw), (int)dw,(int)(4*dw),(int)(1*dw));
 58         cn.add(bestsc);
 59         sc.setBounds((int)(6*dw), (int)(2*dw),(int)(4*dw),(int)(1*dw));
 60         cn.add(sc);
 61         mainframe = new mainFrame();
 62         mainframe.setBackground(new Color(153,204,255));
 63         mainframe.setBounds((int)(dw/2), (int)(15*dw/2),(int)(8*dw),(int)(8*dw));
 64         cn.add(mainframe);
 65         this.validate();
 66         init();
 67         this.setVisible(true);
 68         this.requestFocus();//添加button 后Frame 失去焦点
 69         int i,j;
 70         for(i=0;i<4;i++){
 71             for(j=0;j<4;j++){
 72                 piece[i][j] = new JButton();
 73                 piece[i][j].setSize(70,70);
 74                 piece[i][j].setEnabled(false);
 75                 piece[i][j].setLocation(5,5);
 76             }
 77         }
 78         mainframe.show(piece);
 79         Receive=new Thread(this);
 80         socket=new Socket();
 81         try { 
 82             if(socket.isConnected()){}                //请求和服务器建立套接字连接:
 83             else{
 84                 InetAddress  address=InetAddress.getByName(InetAddr);
 85                 InetSocketAddress socketAddress=new InetSocketAddress(address,4331);
 86                 socket.connect(socketAddress); 
 87                 in =new DataInputStream(socket.getInputStream());
 88                 out = new DataOutputStream(socket.getOutputStream());
 89                 System.out.println("identity:"+in.read());
 90                 if(!(Receive.isAlive()))
 91                     Receive=new Thread(this);
 92                  Receive.start();
 93             }
 94             group=InetAddress.getByName("239.255.8.0");//设置广播组的地址为239.255.8.0
 95             Msocket=new MulticastSocket(port);    //多点广播套接字将在port端口广播
 96             Msocket.joinGroup(group); //加入group
 97         } 
 98         catch (IOException ee) {
 99             System.out.println(ee);
100             socket=new Socket();
101         }
102         
103     }
104     /*
105      * 初始化
106      */
107     void init(){
108         statue.setText("");
109         statue.setVisible(false);
110         this.requestFocus();//添加button 后Frame 失去焦点
111     }
112 
113 
114     /*
115      * 按键事件
116      * (non-Javadoc)
117      * @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent)
118      */
119     public void keyTyped(KeyEvent arg0) {
120     }
121     public void keyReleased(KeyEvent arg0) {
122     }
123     public void keyPressed(KeyEvent arg0) {
124 
125         switch(arg0.getKeyCode()){
126             case KeyEvent.VK_LEFT:
127             case KeyEvent.VK_A:{
128                 slip(0);
129                 break;
130             }
131             case KeyEvent.VK_RIGHT:
132             case KeyEvent.VK_D:{
133                 slip(1);
134                 break;
135             }
136             case KeyEvent.VK_UP:
137             case KeyEvent.VK_W:{
138                 slip(2);
139                 break;
140             }
141             case KeyEvent.VK_DOWN:
142             case KeyEvent.VK_S:{
143                 slip(3);
144                 break;
145             }                
146         }
147     }
148     void slip(int control){
149         try {
150             out.write(control);
151         } catch (IOException e) {
152             e.printStackTrace();
153         }
154     }
155     public void run() {
156         int[] pieces = null;
157         int i,j;
158         while(true) {   
159             byte data[]=new byte[80];
160             DatagramPacket packet=null;
161             packet=new DatagramPacket(data,data.length,group,port); //待接收的数据包,即数据存于字节数组data中)
162             try { Msocket.receive(packet);
163                 data=packet.getData();
164             }
165             catch(Exception e) {}
166             pieces = Byte.byte2Int(data);
167             for(i=0;i<4;i++)
168                 for(j=0;j<4;j++){
169                     pieceSet(piece[i][j],pieces[3+i*4+j]);
170                 }
171             mainframe.show(piece);
172             if(pieces[0]==-1){
173                 statue.setText("Game Over");
174                 statue.setVisible(true);
175             }
176             else if(pieces[0]==1){
177                 statue.setText("Win");
178                 statue.setVisible(true);
179             }
180             else {
181                 statue.setVisible(false);
182             }
183             sc.setFont(new Font("Arial",Font.BOLD,15));
184             sc.setText("Score:"+pieces[1]);
185             bestsc.setText("Best:"+pieces[2]);
186             bestsc.setFont(new Font("Arial",Font.BOLD,15));
187         } 
188     }
189     void pieceSet(JButton p,int level){
190         int value=1;
191         int colorValue=256/10*(10-level);
192         p.setBackground(new Color(255,colorValue,colorValue));
193         if (level==0){
194             p.setText("");
195             return;
196         }
197         int i;
198         for(i=0;i<level;i++){
199             value=value*2;
200         }
201         p.setFont(new Font("Arial",Font.BOLD,20));
202         p.setText(""+value);
203     }
204     public static void main(String args[]){
205         new Window();
206     }
207 }

Server 包

class Server

 

  1 package Server;
  2 import java.awt.event.ActionEvent;
  3 import java.awt.event.ActionListener;
  4 import java.io.DataInputStream;
  5 import java.io.DataOutputStream;
  6 import java.io.IOException;
  7 import java.net.DatagramPacket;
  8 import java.net.InetAddress;
  9 import java.net.MulticastSocket;
 10 import java.net.ServerSocket;
 11 import java.net.Socket;
 12 
 13 import javax.swing.SwingUtilities;
 14 import javax.swing.Timer;
 15 
 16 import Byte.Byte;
 17 
 18 public class Server implements ActionListener, Runnable{
 19     private int [][]piece;
 20     private int score;
 21     private int bestscore;
 22     private int statue;
 23     private int[] controls;
 24     Timer time;
 25     Thread client;
 26     
 27     int port=5858;
 28     InetAddress group=null;                          //组播组的地址
 29     MulticastSocket Msocket=null;                     //多点广播套接字  
 30     public Server(){
 31         client = new Thread(this);
 32         time = new Timer(500,this);
 33         init();
 34         client.start();
 35     }
 36     public static void main(String args[]){
 37         new Server();
 38     }
 39     public void init(){
 40         piece = new int[4][4];
 41         for(int i=0;i<4;i++)
 42             for(int j=0;j<4;j++){
 43                 piece[i][j]=0;
 44             }
 45         controls = new int[4];
 46         for(int i=0;i<4;i++)
 47             controls[i]=0;
 48         score=0;
 49         statue=0;
 50         addNewPiece();
 51         addNewPiece();
 52         SwingUtilities.invokeLater(
 53             new Runnable(){//实例化更新组件的线程 unnable run
 54                 public void run() {
 55                     broadcast();
 56                 }
 57             }
 58         );
 59         
 60         time.start();
 61     }
 62     @Override
 63     public void actionPerformed(ActionEvent arg0) {
 64         int control = handle(-1);
 65         if(control!=-1){
 66             Run2048(control);
 67             SwingUtilities.invokeLater(
 68                 new Runnable(){//实例化更新组件的线程 unnable run
 69                     public void run() {
 70                         addNewPiece();
 71                     }
 72                 }
 73             );
 74         }
 75         SwingUtilities.invokeLater(
 76             new Runnable(){//实例化更新组件的线程 unnable run
 77                 public void run() {
 78                     broadcast();
 79                 }
 80             }
 81         );
 82     }
 83     void Run2048(int mindex){
 84         switch(mindex){
 85         case 0:{
 86             SwingUtilities.invokeLater(
 87                 new Runnable(){//实例化更新组件的线程 unnable run
 88                     public void run() {
 89                         leftgo(0);
 90                     }
 91                 }
 92             );
 93             SwingUtilities.invokeLater(
 94                 new Runnable(){//实例化更新组件的线程 unnable run
 95                     public void run() {
 96                         leftgo(1);
 97                     }
 98                 }
 99             );
100             SwingUtilities.invokeLater(
101                 new Runnable(){//实例化更新组件的线程 unnable run
102                     public void run() {
103                         leftgo(2);
104                     }
105                 }
106             );
107             SwingUtilities.invokeLater(
108                 new Runnable(){//实例化更新组件的线程 unnable run
109                     public void run() {
110                         leftgo(3);
111                     }
112                 }
113             );
114             break;
115         }
116         case 1:{
117             SwingUtilities.invokeLater(
118                 new Runnable(){//实例化更新组件的线程 unnable run
119                     public void run() {
120                         rihetgo(0);
121                     }
122                 }
123             );
124             SwingUtilities.invokeLater(
125                 new Runnable(){//实例化更新组件的线程 unnable run
126                     public void run() {
127                         rihetgo(1);
128                     }
129                 }
130             );
131             SwingUtilities.invokeLater(
132                 new Runnable(){//实例化更新组件的线程 unnable run
133                     public void run() {
134                         rihetgo(2);
135                     }
136                 }
137             );
138             SwingUtilities.invokeLater(
139                 new Runnable(){//实例化更新组件的线程 unnable run
140                     public void run() {
141                         rihetgo(3);
142                     }
143                 }
144             );
145             break;
146         }
147         case 2:{
148             SwingUtilities.invokeLater(
149                 new Runnable(){//实例化更新组件的线程 unnable run
150                     public void run() {
151                         upgo(0);
152                     }
153                 }
154             );
155             SwingUtilities.invokeLater(
156                 new Runnable(){//实例化更新组件的线程 unnable run
157                     public void run() {
158                         upgo(1);
159                     }
160                 }
161             );
162             SwingUtilities.invokeLater(
163                 new Runnable(){//实例化更新组件的线程 unnable run
164                     public void run() {
165                         upgo(2);
166                     }
167                 }
168             );
169             SwingUtilities.invokeLater(
170                 new Runnable(){//实例化更新组件的线程 unnable run
171                     public void run() {
172                         upgo(3);
173                     }
174                 }
175             );
176             break;
177         }
178         case 3:{
179             SwingUtilities.invokeLater(
180                 new Runnable(){//实例化更新组件的线程 unnable run
181                     public void run() {
182                         downgo(0);
183                     }
184                 }
185             );
186             SwingUtilities.invokeLater(
187                 new Runnable(){//实例化更新组件的线程 unnable run
188                     public void run() {
189                         downgo(1);
190                     }
191                 }
192             );
193             SwingUtilities.invokeLater(
194                 new Runnable(){//实例化更新组件的线程 unnable run
195                     public void run() {
196                         downgo(2);
197                     }
198                 }
199             );
200             SwingUtilities.invokeLater(
201                 new Runnable(){//实例化更新组件的线程 unnable run
202                     public void run() {
203                         downgo(3);
204                     }
205                 }
206             );
207             break;
208         }
209         }
210     }
211     void leftgo(int i){
212         int k;//当前的下标
213         int p;//遍历用
214         int q=i;//第几条
215         int m;//末端的下标
216         int n;//消除位置
217         k=0;
218         m=3;
219         n=k;
220         while(k<=m){
221             while(piece[q][k]==0){
222                 for(p=k;p<m;p++)
223                     piece[q][p]=piece[q][p+1];
224                 piece[q][m]=0;
225                 m--;
226                 if(m<k)
227                     return;
228             }
229             
230             if(k>n){
231                 if(piece[q][k]==piece[q][k-1]){
232                     setCreateScore(++piece[q][k-1]);
233                     piece[q][k]=0;
234                     n=k;
235                     k--;
236                 }
237             } 
238             k++;
239         }
240     }
241     void rihetgo(int i){
242         int k;//当前的下标
243         int p;//遍历用
244         int q=i;//第几条
245         int m;//末端的下标
246         int n;//消除位置
247         k=3;
248         m=0;
249         n=k;
250         while(k>=m){
251             while(piece[q][k]==0){
252                 for(p=k;p>0;p--)
253                     piece[q][p]=piece[q][p-1];
254                 piece[q][m]=0;
255                 m++;
256                 if(m>k)
257                     return;
258             }
259             if(k<n){
260                 if(piece[q][k]==piece[q][k+1]){
261                     setCreateScore(++piece[q][k+1]);
262                     piece[q][k]=0;
263                     n=k;
264                     k++;
265                 }
266             } 
267             k--;
268         }
269     }
270     void upgo(int i){
271         int k;//当前的下标
272         int p;//遍历用
273         int q=i;//第几条
274         int m;//末端的下标
275         int n;//消除位置
276         k=0;
277         m=3;
278         n=k;
279         while(k<=m){
280             while(piece[k][q]==0){
281                 for(p=k;p<m;p++)
282                     piece[p][q]=piece[p+1][q];
283                 piece[m][q]=0;
284                 m--;
285                 if(m<k)
286                     return;
287             }
288             if(k>n){
289                 if(piece[k][q]==piece[k-1][q]){
290                     setCreateScore(++piece[k-1][q]);
291                     piece[k][q]=0;
292                     n=k;
293                     k--;
294                 }
295             } 
296             k++;
297         }
298     }
299     void downgo(int i){
300         int k;//当前的下标
301         int p;//遍历用
302         int q=i;//第几条
303         int m;//末端的下标
304         int n;//消除位置
305         k=3;
306         m=0;
307         n=k;
308         while(k>=m){
309             while(piece[k][q]==0){
310                 for(p=k;p>0;p--)
311                     piece[p][q]=piece[p-1][q];
312                 piece[m][q]=0;
313                 m++;
314                 if(m>k)
315                     return;
316             }
317             if(k<n){
318                 if(piece[k][q]==piece[k+1][q]){
319                     setCreateScore(++piece[k+1][q]);
320                     piece[k][q]=0;
321                     n=k;
322                     k++;
323                 }
324             } 
325             k--;
326         }
327     }
328     synchronized void setCreateScore(int level){
329         int i;
330         int levelValue=1;
331         for(i=0;i<level;i++)
332             levelValue=levelValue*2;
333         score+=levelValue;
334         if(levelValue>1023){
335             statue=1;
336         }
337         if(score>bestscore)
338             bestscore=score;
339     }
340     void addNewPiece(){
341         int p;
342         for(p=0;p<16;p++){
343             if(piece[p/4][p%4]==0){
344                 while(true){
345                     int i=(int)(Math.random()*4);
346                     int j=(int)(Math.random()*4);
347                     if(piece[i][j]==0){
348                         piece[i][j]++;
349                         return;
350                     }
351                 }
352             }
353         }
354         statue=-1;
355     }
356     /*
357      * (non-Javadoc)
358      * @see java.lang.Runnable#run()
359      * 监听连接客户端
360      */
361     @Override
362     public void run() {
363         ServerSocket server=null;
364         Socket socket=null;
365         while(true) {
366             try{  
367                 server=new ServerSocket(4331);
368             }
369             catch(IOException e1) { 
370                    System.out.println("正在监听"); //ServerSocket对象不能重复创建
371             } 
372             try{  
373                 System.out.println(" 等待客户呼叫");
374                    socket=server.accept();
375                    System.out.println("客户的地址:"+socket.getInetAddress());
376             } 
377             catch (IOException e) {
378                 System.out.println("正在等待客户");
379             }
380             if(socket!=null) { 
381                 if(ServerThread.clientnum<ServerThread.maxclientnum)
382                       new ServerThread(socket,this).start(); //为每个客户启动一个专门的线程  
383                 else System.out.println("超出最大客户端数量");
384             }
385         }
386     }
387     /*
388      * 数据广播
389      */
390     void broadcast(){
391         try {
392             group=InetAddress.getByName("239.255.8.0");//设置广播组的地址为
393             Msocket=new MulticastSocket(port);         //多点广播套接字将在port端口广播
394             Msocket.setTimeToLive(1); //多点广播套接字发送数据报范围为本地网络
395             Msocket.joinGroup(group); //加入group后,socket发送的数据报被group中的成员接收到
396         } catch (Exception e) {
397         }
398         DatagramPacket packet=null;        //待广播的数据包
399         int []dataInt = new int[20];
400         dataInt[0]=statue;
401         dataInt[1]=score;
402         dataInt[2]=bestscore;
403         int i,j;
404         for(i=0;i<4;i++){
405             for(j=0;j<4;j++){
406                 dataInt[3+i*4+j]=piece[i][j];
407             }
408         }
409         byte []data = Byte.int2Byte(dataInt);
410         packet=new DatagramPacket(data,data.length,group,port); 
411         try {
412             Msocket.send(packet);
413         } catch (IOException e) {
414             e.printStackTrace();
415         } 
416         if(statue!=0){
417             time.stop();
418             try {
419                 new Thread().sleep(2*1000);
420             } catch (InterruptedException e) {
421                 // TODO Auto-generated catch block
422                 e.printStackTrace();
423             }
424             init();
425             time.start();
426         }    
427     }
428     /*
429      * 数据处理
430      */
431     public synchronized int handle(int control){
432         switch (control){
433         case -1:
434             int i,mindex=0;
435             for(i=0;i<4;i++)
436                 if(controls[mindex]<controls[i])
437                     mindex=i;
438             if(controls[mindex]==0)
439                 mindex =-1;
440             for(i=0;i<4;i++)
441                 controls[i]=0;
442             return mindex;
443         default:
444             controls[control]++;
445             return -1;
446         }
447     }
448 }
449 class ServerThread extends Thread{
450     Server server;
451     Socket socket;
452     DataOutputStream out=null;
453     DataInputStream  in=null;
454     /*
455      * 客户端信息
456      */
457     int identity=0;
458     static int clientnum=0;
459     final static int maxclientnum=10;
460     private static int clientn=0;//用来设置id
461     
462     public ServerThread(Socket socket,Server server) {
463         this.socket=socket;
464         this.server=server;
465         try {  
466             out=new DataOutputStream(socket.getOutputStream());
467             in=new DataInputStream(socket.getInputStream());
468         }
469         catch (IOException e){}
470         try {
471             out.write(identity);
472         } catch (IOException e) {
473             e.printStackTrace();
474         }                               
475         catch(Exception e) {
476             System.out.println("Error: "+ e);          
477         }
478         /*
479          * 给每一个客户端分配ID
480          * 统计当前已经连接的客户端数量
481          */
482         clientn++;
483         identity=clientn;
484         clientnum++;  
485         System.out.println("新连接客户端:客户端"+identity);
486     }
487     /*
488      * (non-Javadoc)
489      * @see java.lang.Thread#run()
490      * 接受数据
491      */
492     public void run(){
493          while(true) {
494               try{  
495                   int r=in.read();    //堵塞状态,除非读取到信息
496 //                  统计数据
497                   server.handle(r);
498               }
499               catch (IOException e) {
500                   clientnum--;
501                   System.out.println("客户离开");
502                   return;
503               }
504            }
505     }
506 }

 

 

 



posted @ 2014-06-13 15:53  crq85分  阅读(342)  评论(0编辑  收藏  举报