人人對戰版五子棋
阿新 • • 發佈:2019-02-13
最近花了點時間把以前寫的五子棋做成了可以聯網的!!
主要思想是這樣的:
黑棋先,黑棋先把自己的棋子的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();
}
}
}
}