最近花了点时间把以前写的五子棋做成了可以联网的!!
主要思想是这样的:
黑棋先,黑棋先把自己的棋子的x y值传到服务器,然后在由服务器传送到第二个客户端,同意白棋也是这么做的。
服务器端的功能就是如果创建一个连接那么就由一个线程去管理这个连接,接受到来自客户端发送的消息,找到对应的客户端发送过去。
这部分是白棋的代码,黑棋先白棋后下
package com.game; import java.awt.*; import java.net.*; import java.io.*; import javax.imageio.ImageIO; import javax.swing.*; import java.awt.event.*; import java.awt.image.BufferedImage; import java.io.DataOutputStream; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; public class wuziqi_1 extends JFrame implements MouseListener { int x=0; int y=0; int [][]ans=new int [19][19];//把棋盘设计为19*19 boolean iswhat = true;//为了判断当前是白棋还是黑棋 true为黑棋 false为白棋 boolean isrun = false;//判断游戏是否还可以继续运行下去 public Image iBuffer; //图片对象 public Graphics gBuffer;//画笔对象 SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");//格式化输出某样东西 Socket soc;//嵌套字 DataInputStream idata;//读入流 DataOutputStream odata;//输出流 public void init() { this.setTitle("五子棋"); this.setSize(500, 500); this.setResizable(false); this.setLocation((Toolkit.getDefaultToolkit().getScreenSize().width - 400)/2,(Toolkit.getDefaultToolkit().getScreenSize().height - 300)/2);//窗体出现的位置是在屏幕中间 this.addMouseListener(this);//添加鼠标监听 this.setVisible(true);//窗体出现 this.setTitle("白方"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); thread_3 t_3 = new thread_3(); t_3.start(); try { soc = new Socket("127.0.0.1",9998); } catch (IOException e) { e.printStackTrace(); } thread t = new thread(); t.start(); thread_2 t_2 = new thread_2(); t_2.start(); } public class thread_3 extends Thread//这个线程的目的就是不停的重画窗体内部的东西 { public void run() { while(true){ repaint(); try { sleep(1000) ;//让线程休息一下 } catch (InterruptedException e) { System.out.println("sleep error!!"); e.printStackTrace(); } } } } public class thread extends Thread//这个线程是为了不停的接受从服务器接受的另一个玩家当前下的棋的x,y值 { public void run() { while(true) { try { idata = new DataInputStream(soc.getInputStream()); int w = idata.readInt(); int q = idata.readInt(); ans[w][q] = 1; isrun = true; iswhat = false; } catch (IOException e) { e.printStackTrace(); } } } } public class thread_1 extends Thread//这个线程是为了服务器发送他要向那个其他客户端发送和当前下的棋的X Y值 { int x,y; public thread_1(int x,int y) { this.x = x; this.y = y; } public void run() { try { odata = new DataOutputStream(soc.getOutputStream()); odata.writeInt(1); odata.writeInt(x); odata.writeInt(y); } catch (IOException e) { e.printStackTrace(); } } } public class thread_2 extends Thread//这个线程是不停的判断棋局是否赢了 { public void run() { while(true) { if(judge_1(x,y) == 1) { JOptionPane.showMessageDialog(null, "恭喜黑方赢了"); isrun = false; break; } else if(judge_1(x,y) == 2) { JOptionPane.showMessageDialog(null, "恭喜白方赢了"); isrun = false; break; } } } } public void paint(Graphics g)//这个方法就是把当前的整体画在后台,然后在一起出现在前台。不然下一个棋子会闪屏一下,体验不好,或者可以直接使用swing的东西 它自带了这个技术 { if(iBuffer == null) { iBuffer = createImage(this.getSize().width,this.getSize().height); //创建一张大小和窗体一样大的图片 gBuffer = iBuffer.getGraphics(); //得到画笔 } BufferedImage image = null;//从硬盘中读取图片 try { image = ImageIO.read(new File("D:/新建文件夹/wuziqi/image/ddd.jpg/")); } catch (IOException e) { e.printStackTrace(); } gBuffer.drawImage(image,0,20,this);//放在Image中 for(int i = 0;i < 19;i++){ gBuffer.drawLine(10,70+20*i,370,70+20*i);//画线 gBuffer.drawLine(10+20*i,70,10+20*i,430); } gBuffer.fillOval(68,128,4,4); gBuffer.fillOval(308,12,4,4);//(重复设置圆点) Font font = new Font("",1,20);//设置字体 gBuffer.drawString(sdf.format(new Date()), 60,470); gBuffer.setFont(font); if(iswhat) { gBuffer.drawString("现在轮到黑方", 120, 60); } else { gBuffer.drawString("现在轮到白方", 120, 60); } for(int i=0;i<19;i++) { for(int j=0;j<19;j++) { if(ans[i][j] == 1)//画白棋 { int tempx = i*20+10; int tempy = j*20+70; gBuffer.fillOval(tempx-7, tempy-7, 14, 14); } if(ans[i][j] == 2)//画黑棋 { int tmpx = i*20+10; int tmpy = j*20+70; gBuffer.setColor(Color.WHITE); gBuffer.fillOval(tmpx-7, tmpy-7, 14, 14); gBuffer.setColor(Color.BLACK); gBuffer.drawOval(tmpx-7, tmpy-7, 14, 14); } } } g.drawImage(iBuffer, 0, 0, this);//整张花放在jframe中 } public void update(Graphics g) { paint(g); } public void mouseClicked(MouseEvent arg0) {//鼠标如果点击图片中按钮形状的位置就会触发相应的事件 if(arg0.getX() >= 400&&arg0.getX() <= 470&&arg0.getY() >= 320&&arg0.getY() <= 350) { JOptionPane.showMessageDialog(this, "made by yangtuo"); } if(arg0.getX() >= 400&&arg0.getX() <= 470&&arg0.getY() >= 370&&arg0.getY() <= 400) { System.exit(0); } if(arg0.getX() >= 400&&arg0.getX() <= 470&&arg0.getY() >= 170&&arg0.getY() <= 200) { JOptionPane.showMessageDialog(this, "只要某一方连续的五个棋子出现就为赢 "); } if(arg0.getX() >= 400&&arg0.getX() <= 470&&arg0.getY() >= 270&&arg0.getY() <= 300) { int n = JOptionPane.showConfirmDialog(this, "你确定要结束游戏吗?", "标题",JOptionPane.YES_NO_OPTION); System.out.println(n); if(n == 0) { isrun = false; } else if(n == 1) { isrun = true; } } } @Override public void mouseEntered(MouseEvent arg0) { } @Override public void mouseExited(MouseEvent arg0) { } @Override public void mousePressed(MouseEvent arg0) { x = arg0.getX(); y = arg0.getY(); if(x >= 10&&x <= 370&&y >= 70&&y <= 430&&isrun == true) { x = (x-10)/20; y = (y-70)/20; if(ans[x][y] == 0) { ans[x][y] = 2; thread_1 t = new thread_1(x,y); t.start(); isrun = false; iswhat = true; } else { JOptionPane.showMessageDialog(this, "对不起这里已经有棋子了"); } repaint(); } } public void mouseReleased(MouseEvent arg0) { } public static void main(String[] args) { new wuziqi_1().init(); } public int judge_1(int x,int y)//判断是否输赢 { int count = 0; int count_1 = 0; int count_2 = 0; int count_3 = 0; int count_4 = 0; int count_5 = 0; int count_6 = 0; int count_7 = 0; int count_8 = 0; int count_9 = 0; int count_10 = 0; int count_11 = 0; for(int i = 0;i < 19;i++) { for(int j = 0;j < 19;j++) { if(ans[i][j] == 1) { count++; if(count == 5) { return 1; } } if(ans[i][j] != 1) { count = 0; } } } for(int i = 0;i < 19;i++) { for(int j = 0;j < 19;j++) { if(ans[i][j] == 2) { count_1++; if(count_1 == 5) { return 2; } } if(ans[i][j] != 2) { count_1=0; } } } for(int i = 0;i < 19;i++) { for(int j = 0;j < 19;j++) { if(ans[j][i] == 1) { count_2++; if(count_2==5) { return 1; } } if(ans[j][i]!=1) { count_2=0; } } } for(int i = 0;i < 19;i++) { for(int j = 0;j < 19;j++) { if(ans[j][i] == 2) { count_3++; if(count_3 == 5) { return 2; } } if(ans[j][i] != 2) { count_3=0; } } } for(int i = 0;i < 19;i++) { for(int j = 0;j < 19;j++) { if(i+j < 19) { if(ans[j][j+i] == 1) { count_4++; if(count_4 == 5) { return 1; } } if(ans[j][j+i] != 1) { count_4=0; } } } } for(int i = 0;i < 19;i++) { for(int j = 0;j < 19;j++) { if(i+j < 19) { if(ans[j][j+i] == 2) { count_5++; if(count_5 == 5) { return 2; } } if(ans[j][j+i] != 2) { count_5=0; } } } } for(int i = 0;i < 19;i++) { for(int j = 0;j < 19;j++) { if(i+j < 19) { if(ans[i+j][j] == 1) { count_6++; if(count_6 == 5) { return 1; } } if(ans[j+i][j] != 1) { count_6=0; } } } } for(int i = 0;i < 19;i++) { for(int j = 0;j < 19;j++) { if(i+j < 19) { if(ans[i+j][j] == 2) { count_7++; if(count_7 == 5) { return 2; } } if(ans[j+i][j] != 2) { count_7=0; } } } } for(int i = 18;i >= 0;i--) { for(int j = 0;j < 19;j++) { if(i-j < 19&&i-j >= 0) { if(ans[i-j][j] == 1) { count_8++; if(count_8 == 5) { return 1; } } if(ans[i-j][j] != 1) { count_8=0; } } } } for(int i = 18;i >= 0;i--) { for(int j = 0;j < 19;j++) { if(i-j < 19&&i-j >= 0) { if(ans[i-j][j] == 2) { count_9++; if(count_9 == 5) { return 2; } } if(ans[i-j][j] != 2) { count_9=0; } } } } for(int i = 0;i < 19;i++) { for(int j = 0;j < 19;j++) { if(i+j < 19) { if(ans[18-j][i+j] == 1) { count_10++; if(count_10 == 5) { return 1; } } if(ans[18-j][j+i] != 1) { count_10 = 0; } } } } for(int i = 18;i >= 0;i--) { for(int j = 0;j < 19;j++) { if(i+j < 19) { if(ans[18-j][i+j] == 2) { count_11++; if(count_11 == 5) { return 2; } } if(ans[18-j][j+i] != 2) { count_11=0; } } } } return 0; } }
这部分是黑棋的代码,因为和白棋很像所以相同的代码没有注释
package com.game; import java.awt.*; import javax.imageio.ImageIO; import javax.swing.*; import com.game.wuziqi_1.thread_2; import java.net.*; import java.io.*; import java.awt.event.*; import java.awt.image.BufferedImage; import java.io.DataInputStream; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; @SuppressWarnings("serial") public class wuziqi extends JFrame implements MouseListener { int x = 0; int y = 0; int [][]ans = new int [19][19]; boolean iswhat = true; boolean isrun = true; public Image iBuffer; public Graphics gBuffer; SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); Socket soc; DataInputStream idata; DataOutputStream odata; public void init() { this.setTitle("五子棋"); this.setSize(500, 500); this.setResizable(false); this.setLocation((Toolkit.getDefaultToolkit().getScreenSize().width-400)/2,(Toolkit.getDefaultToolkit().getScreenSize().width-300)/2); this.addMouseListener(this); this.setTitle("黑方"); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); thread_3 t_3 = new thread_3(); t_3.start(); try { soc = new Socket("127.0.0.1",9998); } catch (IOException e) { e.printStackTrace(); } thread_1 t = new thread_1(); t.start(); thread_2 t_2 = new thread_2(); t_2.start(); } public class thread_2 extends Thread { public void run() { while(true) { if(judge_1(x,y) == 1) { JOptionPane.showMessageDialog(null, "恭喜黑方赢了"); isrun = false; break; } else if(judge_1(x,y) == 2) { JOptionPane.showMessageDialog(null, "恭喜白方赢了"); isrun = false; break; } } } } public class thread_3 extends Thread { public void run() { while(true){ repaint(); try { sleep(1000) ; } catch (InterruptedException e) { System.out.println("sleep error!!"); e.printStackTrace(); } } } } public class thread extends Thread { int x,y; public thread(int x,int y) { this.x = x; this.y = y; } public void run() { try { odata = new DataOutputStream(soc.getOutputStream()); odata.writeInt(2); odata.writeInt(x); odata.writeInt(y); } catch (IOException e) { e.printStackTrace(); } } } public class thread_1 extends Thread { public void run() { while(true) { try { idata = new DataInputStream(soc.getInputStream()); int w = idata.readInt(); int q = idata.readInt(); System.out.println(w); System.out.println(q); ans[w][q] = 2; isrun = true; iswhat = true; } catch (IOException e) { e.printStackTrace(); } } } } public void paint(Graphics g) { if(iBuffer == null) { iBuffer = createImage(this.getSize().width,this.getSize().height); gBuffer = iBuffer.getGraphics(); } BufferedImage image = null; try { image = ImageIO.read(new File("D:/新建文件夹/wuziqi/image/ddd.jpg/")); } catch (IOException e) { e.printStackTrace(); } gBuffer.drawImage(image,0,20,this); for(int i = 0;i < 19;i++){ gBuffer.drawLine(10,70+20*i,370,70+20*i); gBuffer.drawLine(10+20*i,70,10+20*i,430); } gBuffer.fillOval(68,128,4,4); gBuffer.fillOval(308,12,4,4);//(重复设置圆点) Font font = new Font("",1,20); gBuffer.drawString(sdf.format(new Date()), 60,470); gBuffer.setFont(font); if(iswhat) { gBuffer.drawString("现在轮到黑方", 120, 60); } else { gBuffer.drawString("现在轮到白方", 120, 60); } for(int i = 0;i < 19;i++) { for(int j = 0;j < 19;j++) { if(ans[i][j] == 1) { int tempx = i*20+10; int tempy = j*20+70; gBuffer.fillOval(tempx-7, tempy-7, 14, 14); } if(ans[i][j] == 2) { int tmpx = i*20+10; int tmpy = j*20+70; gBuffer.setColor(Color.WHITE); gBuffer.fillOval(tmpx-7, tmpy-7, 14, 14); gBuffer.setColor(Color.BLACK); gBuffer.drawOval(tmpx-7, tmpy-7, 14, 14); } } } g.drawImage(iBuffer, 0, 0, this); } public void update(Graphics g) { paint(g); } @Override public void mouseClicked(MouseEvent arg0) { if(arg0.getX() >= 400&&arg0.getX() <= 470&&arg0.getY() >= 320&&arg0.getY() <= 350) { JOptionPane.showMessageDialog(this, "made by yangtuo"); } if(arg0.getX() >= 400&&arg0.getX() <= 470&&arg0.getY() >= 370&&arg0.getY() <= 400) { System.exit(0); } if(arg0.getX() >= 400&&arg0.getX() <= 470&&arg0.getY() >= 170&&arg0.getY() <= 200) { JOptionPane.showMessageDialog(this, "只要某一方连续的五个棋子出现就为赢 "); } if(arg0.getX() >= 400&&arg0.getX() <= 470&&arg0.getY() >= 270&&arg0.getY() <= 300) { int n = JOptionPane.showConfirmDialog(this, "你确定要结束游戏吗?", "标题",JOptionPane.YES_NO_OPTION); if(n == 0) { isrun = false; } else if(n == 1) { isrun = true; } } } @Override public void mouseEntered(MouseEvent arg0) { } @Override public void mouseExited(MouseEvent arg0) { } @Override public void mousePressed(MouseEvent arg0) { x = arg0.getX(); y = arg0.getY(); if(x >= 10&&x <= 370&&y >= 70&&y <= 430&&isrun == true) { x = (x-10)/20; y = (y-70)/20; if(ans[x][y] == 0) { ans[x][y] = 1; thread t = new thread(x,y); t.start(); isrun = false; iswhat = false; } else { JOptionPane.showMessageDialog(this, "对不起这里已经有棋子了"); } repaint(); } } @Override public void mouseReleased(MouseEvent arg0) { } public static void main(String[] args) { new wuziqi().init(); } public int judge_1(int x,int y)//判断是否输赢 { int count = 0; int count_1 = 0; int count_2 = 0; int count_3 = 0; int count_4 = 0; int count_5 = 0; int count_6 = 0; int count_7 = 0; int count_8 = 0; int count_9 = 0; int count_10 = 0; int count_11 = 0; for(int i = 0;i < 19;i++) { for(int j = 0;j < 19;j++) { if(ans[i][j] == 1) { count++; if(count == 5) { return 1; } } if(ans[i][j] != 1) { count = 0; } } } for(int i = 0;i < 19;i++) { for(int j = 0;j < 19;j++) { if(ans[i][j] == 2) { count_1++; if(count_1 == 5) { return 2; } } if(ans[i][j] != 2) { count_1=0; } } } for(int i = 0;i < 19;i++) { for(int j = 0;j < 19;j++) { if(ans[j][i] == 1) { count_2++; if(count_2==5) { return 1; } } if(ans[j][i]!=1) { count_2=0; } } } for(int i = 0;i < 19;i++) { for(int j = 0;j < 19;j++) { if(ans[j][i] == 2) { count_3++; if(count_3 == 5) { return 2; } } if(ans[j][i] != 2) { count_3=0; } } } for(int i = 0;i < 19;i++) { for(int j = 0;j < 19;j++) { if(i+j < 19) { if(ans[j][j+i] == 1) { count_4++; if(count_4 == 5) { return 1; } } if(ans[j][j+i] != 1) { count_4=0; } } } } for(int i = 0;i < 19;i++) { for(int j = 0;j < 19;j++) { if(i+j < 19) { if(ans[j][j+i] == 2) { count_5++; if(count_5 == 5) { return 2; } } if(ans[j][j+i] != 2) { count_5=0; } } } } for(int i = 0;i < 19;i++) { for(int j = 0;j < 19;j++) { if(i+j < 19) { if(ans[i+j][j] == 1) { count_6++; if(count_6 == 5) { return 1; } } if(ans[j+i][j] != 1) { count_6=0; } } } } for(int i = 0;i < 19;i++) { for(int j = 0;j < 19;j++) { if(i+j < 19) { if(ans[i+j][j] == 2) { count_7++; if(count_7 == 5) { return 2; } } if(ans[j+i][j] != 2) { count_7=0; } } } } for(int i = 18;i >= 0;i--) { for(int j = 0;j < 19;j++) { if(i-j < 19&&i-j >= 0) { if(ans[i-j][j] == 1) { count_8++; if(count_8 == 5) { return 1; } } if(ans[i-j][j] != 1) { count_8=0; } } } } for(int i = 18;i >= 0;i--) { for(int j = 0;j < 19;j++) { if(i-j < 19&&i-j >= 0) { if(ans[i-j][j] == 2) { count_9++; if(count_9 == 5) { return 2; } } if(ans[i-j][j] != 2) { count_9=0; } } } } for(int i = 0;i < 19;i++) { for(int j = 0;j < 19;j++) { if(i+j < 19) { if(ans[18-j][i+j] == 1) { count_10++; if(count_10 == 5) { return 1; } } if(ans[18-j][j+i] != 1) { count_10 = 0; } } } } for(int i = 18;i >= 0;i--) { for(int j = 0;j < 19;j++) { if(i+j < 19) { if(ans[18-j][i+j] == 2) { count_11++; if(count_11 == 5) { return 2; } } if(ans[18-j][j+i] != 2) { count_11=0; } } } } return 0; } }
服务器部分:由三个类组成
package com.theserver; import java.io.*; import java.net.*; public class theserver { ServerSocket server;//创建一个端口 Socket soc; DataInputStream idata;//输入流 int i = 1;//不停的连接进来的线程标记 public void init() { try { server = new ServerSocket(9998); } catch (IOException e1) { e1.printStackTrace(); } while(true) { try { soc = server.accept();//接受到一个客户端就创建一个线程 newthread t = new newthread(soc); t.start(); idnet.add(String.valueOf(i++),t);//把这个线程放进HashMap的容器中 } catch (IOException e) { e.printStackTrace(); } } } public static void main(String[] args) { new theserver().init(); } }
package com.theserver; import java.util.*; public class idnet { public static HashMap<String,newthread> hm = new HashMap<String,newthread>();//创建一个容器 public static void add(String s,newthread ser)//往里面添加东西 { hm.put(s,ser); } public static newthread getting(String s) { return (newthread)hm.get(s);//通过标志来寻找到那个线程 } public static void judge()//测试时用的 查看容器里面的东西数量 { System.out.println(hm.size()); } }
package com.theserver; import java.net.*; import java.io.*; public class newthread extends Thread{ Socket soc; newthread t; DataInputStream idata; DataOutputStream odata; public newthread(Socket s) { this.soc = s; } public void run() { while(true) { try { idata = new DataInputStream(soc.getInputStream()); int x = idata.readInt();//获得应该往那个客户端发送的id int y = idata.readInt(); int z= idata.readInt(); newthread xc = idnet.getting(String.valueOf(x));//找出那个线程 odata = new DataOutputStream(xc.soc.getOutputStream()); odata.writeInt(y); odata.writeInt(z); } catch (IOException e) { e.printStackTrace(); } } } }