主頁 >  其他 > java專案開發(一)----五子棋

java專案開發(一)----五子棋

2021-08-16 12:17:13 其他

java專案開發(一)----五子棋

  • 專案(一)------五子棋
    • 開發思路
      • 五子棋的要素
        • 兩個用戶
        • 黑白棋子
        • 棋盤
        • 游戲的幾個界面---登錄、模式選擇、勝負彈窗、游戲界面
      • 游戲規則
    • 游戲視窗的創建
      • 創建視窗物件
        • 視窗創建思路
        • 代碼
      • 創建按鈕物件
        • 按鈕創建設定思路
        • 代碼
      • 設定布局
        • 布局設定思路
        • 代碼
        • 效果圖
    • 棋盤的繪制
        • 棋盤繪制思路
        • 代碼
        • 效果圖
    • 如何在棋盤上下棋
      • 繪制棋子
      • 設定輪流下棋
      • 設定下棋范圍
        • 設定落子點為網格交叉處
        • 落子邊界設定
        • 重繪棋子
          • 所遇到的問題:怎么知道知道棋盤的棋子布局??
          • 解決辦法:建立二維陣列來儲存棋子布局資訊
        • 設定不能重復下棋
    • 如何設定悔棋
      • 解決方法:
      • 關鍵代碼:
      • 實作后的代碼
    • 如何判斷勝負
      • 思路:遍歷棋盤,看縱向、橫向兩個斜向是否有五顆同色棋子相連;如果有判斷贏;如果沒有;判斷輸
      • 代碼實作
      • 實作影像
    • 如何設定登錄界面以及頁面跳轉
      • 創建登錄界面、并設定一個賬號、密碼登錄
        • 我們如何設定界面跳轉??
        • 如何呼叫其他類視窗提的方法??
        • 如何實作存檔讀檔
    • 各項實作后的代碼
    • 效果圖
    • 程式還需優化改進之處

專案(一)------五子棋

? 我們都玩過五子棋那么,這么一個看似簡單的游戲怎么用JAVA代碼去實作呢??

開發思路

五子棋的要素

兩個用戶

五子棋需要雙方來下棋

所以我們需要兩個用戶來對戰

雙方可以是人也可以是AI

一方手執白棋、一方手執黑棋

黑白棋子

-我們通過黑白棋子來區分用戶雙方

  • 屬性

    -棋子顏色

    -棋子尺寸

    -棋子行列坐標

    -下的棋順序

  • 主要方法

    -繪制棋子

    -判斷勝負

棋盤

-有棋盤我們才有地方下棋,我們需要棋盤

  • 屬性

    -棋盤尺寸

    -棋盤坐標

    -棋盤背景

    -棋盤格

  • 方法

    -棋盤繪制

游戲的幾個界面—登錄、模式選擇、勝負彈窗、游戲界面

-我們無論繪制棋盤還是繪制棋子,都需要在視窗體上獲取畫筆,在視窗體上作畫

-我們用戶登錄需要有登錄界面、游戲模式選擇要有模式選項界面、勝負判斷勝負判斷界面、游戲要有游戲界面

  • 屬性

    -尺寸

    -功能按鈕

    -界面標題

    -界面背景

    -界面布局

  • 方法

    -視窗體創建、可視化

    -監聽器

    -地址傳輸

    -布局設定

    -按鈕、面板、標簽的設定

游戲規則

-勝負判斷:五子棋顧名思義,從縱向、橫向、兩個斜向只要有五個同色棋子相連便贏了

-下棋順序:白棋為先,黑白棋輪流下棋

-下棋規則:可以悔一步棋,不能重復一個地方下棋,不能將棋子下到邊界之外

游戲視窗的創建

創建視窗物件

視窗創建思路

-輸入javax.swing.*的包:import java.swing.*;   //我們需要用里面的JFrame來創建視窗物件
-通過繼承JFrame,用this來直接參考父類的方法設定視窗體,所以我們這里一開始可以不創建物件---子類繼承父類的方法
-視窗體設定:運用JFrame的幾個方法我們設定視窗體的標題、尺寸、小圖示、關閉設定、可視化

代碼

package com.xsx0805;

import javax.swing.*; 
import java.awt.*;
public class WuZiqi extends JFrame{
	 
	
	//設定視窗體
	public void initUI() {
		
		//設定視窗體屬性
		this.setTitle("五子棋0");//設定視窗標題
		this.setSize(1100, 1000);//設定尺寸
		this.setIconImage(new ImageIcon("image\\saierda.png").getImage());//設定視窗體的小圖示	

		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//關閉設定
		this.setLocationRelativeTo(null);//讓視窗提居中
		this.setVisible(true);//設定可視化
			
	}

創建按鈕物件

按鈕創建設定思路

-創建按鈕物件
	按鈕創建格式:
 	JButton 物件名=new JButton();//創建按鈕物件的格式
-設定按鈕的各種屬性---尺寸、文本內容、字體

代碼

		JButton btn_1=new JButton();
		JButton btn_2=new JButton();
		JButton btn_3=new JButton();
		JButton btn_4=new JButton();
		JButton btn_5=new JButton();
		JButton btn_6=new JButton();
		JButton btn_7=new JButton();
		JButton btn_8=new JButton();
		
		//設定按鈕內容---一些現在用的和以后慢慢完善的
		btn_1.setText("悔棋");
		btn_2.setText("回放");
		btn_3.setText("存檔");
		btn_4.setText("讀檔");
		btn_5.setText("回傳選單");
		btn_6.setText("開始錄制");
		btn_7.setText("停止錄制");
		btn_8.setText("重新開始");
		//設定字體
		btn_1.setFont(new Font("SimSun",1,15));
		btn_2.setFont(new Font("SimSun",1,15));
		btn_3.setFont(new Font("SimSun",1,15));
		btn_4.setFont(new Font("SimSun",1,15));
		btn_5.setFont(new Font("SimSun",1,15));
		btn_6.setFont(new Font("SimSun",1,15));
		btn_7.setFont(new Font("SimSun",1,15));
		btn_8.setFont(new Font("SimSun",1,15));


		Dimension dim_2=new Dimension(100,40);
		
		//設定按鈕尺寸
		btn_1.setPreferredSize(dim_2);
		btn_2.setPreferredSize(dim_2);
		btn_3.setPreferredSize(dim_2);
		btn_4.setPreferredSize(dim_2);
		btn_5.setPreferredSize(dim_2);
		btn_6.setPreferredSize(dim_2);
		btn_7.setPreferredSize(dim_2);
		btn_8.setPreferredSize(dim_2);

設定布局

布局設定思路

-布局選擇:按鈕在視窗體上不可以影響到棋盤的繪制,所以我們需要將他們設定邊界布局—BorderLayout,它分為 SOUTH\NORTH\CENTER\EAST\WEST五個方位

-面板設定:按鈕很多,所以我們選擇創建一個面板將他們加到面板上—JPanel通過面板類來創建面板物件

-加入表單:最后將面板加入視窗體

代碼

	public void initUI() {
		
		//設定視窗體屬性
		this.setTitle("五子棋0");
		this.setSize(1100, 1000);
		this.setIconImage(new ImageIcon("image\\saierda.png").getImage());
		
		
		//創建按鈕面板物件
		JPanel jp_1=new JPanel(new FlowLayout(FlowLayout.CENTER,20,10));
		jp_1.setBackground(Color.gray);//設定面板的背景顏色

		JButton btn_1=new JButton();
		JButton btn_2=new JButton();
		JButton btn_3=new JButton();
		JButton btn_4=new JButton();
		JButton btn_5=new JButton();
		JButton btn_6=new JButton();
		JButton btn_7=new JButton();
		JButton btn_8=new JButton();
		
		//設定按鈕內容
		btn_1.setText("悔棋");
		btn_2.setText("回放");
		btn_3.setText("存檔");
		btn_4.setText("讀檔");
		btn_5.setText("回傳選單");
		btn_6.setText("開始錄制");
		btn_7.setText("停止錄制");
		btn_8.setText("重新開始");
		
		btn_1.setFont(new Font("SimSun",1,15));
		btn_2.setFont(new Font("SimSun",1,15));
		btn_3.setFont(new Font("SimSun",1,15));
		btn_4.setFont(new Font("SimSun",1,15));
		btn_5.setFont(new Font("SimSun",1,15));
		btn_6.setFont(new Font("SimSun",1,15));
		btn_7.setFont(new Font("SimSun",1,15));
		btn_8.setFont(new Font("SimSun",1,15));

		Dimension dim_1=new Dimension(1000,70);
		Dimension dim_2=new Dimension(100,40);
		
		//設定按鈕大小
		btn_1.setPreferredSize(dim_2);
		btn_2.setPreferredSize(dim_2);
		btn_3.setPreferredSize(dim_2);
		btn_4.setPreferredSize(dim_2);
		btn_5.setPreferredSize(dim_2);
		btn_6.setPreferredSize(dim_2);
		btn_7.setPreferredSize(dim_2);
		btn_8.setPreferredSize(dim_2);
		
		
		//設定面板大小
		jp_1.setPreferredSize(dim_1);
		//在面板上加入按鈕
		jp_1.add(btn_1);
		jp_1.add(btn_2);
		jp_1.add(btn_3);
		jp_1.add(btn_4);
		jp_1.add(btn_5);
		jp_1.add(btn_6);
		jp_1.add(btn_7);
		jp_1.add(btn_8);

		this.add(jp_1,BorderLayout.SOUTH);//將面板以邊界布局加到視窗上
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setLocationRelativeTo(null);
		this.setVisible(true);				
	}

效果圖

在這里插入圖片描述

棋盤的繪制

棋盤繪制思路

- 獲取畫筆--Graphics它需要在視窗體上獲取
- 設定監聽器:將畫筆傳入監聽器來畫棋盤和網格
			//獲取畫筆并將畫筆傳入監聽器
		wl.setGraphics(this.getGraphics());
- 棋盤網格:設定好網格的各種屬性--行列數、行列間距、網格繪制初始坐標,我們可以將他們一起寫入介面再將他們接入;
package com.xsx0805;

public interface GoBaangConfig {
	
	/*** SIZE: 棋盤間距 兼 棋子直徑 */ 
	int SIZE=50;

	/*** 棋盤左上角 X坐 標 */ 
	int X=100;
	
	
	/*** 棋盤左上角 Y 坐 標 */
	int Y=100; 
	
	
	/*** 棋盤的行列值 */
	int ROW=15; 
	int CLOUN=15;

}

- 棋盤背景影像--創建一個檔案夾image存上我們選好的畫板影像和背景影像,使用的時候用ImageIcon來創建圖片物件供畫筆用
- 棋盤繪制:通過網格的尺寸和坐標,設定好棋盤的尺寸和繪制坐標來繪制

代碼

package com.xsx0805;

import javax.swing.*; 
import java.awt.*;
public class WuZiqi extends JFrame implements GoBaangConfig{
	
	private static final Image bgimg=new ImageIcon("image\\yellow.png").getImage();
	
	//創建監聽器物件
	private WuZiqiListener wl=new WuZiqiListener();
	//設定視窗體
	public void initUI() {
		
		//設定視窗體屬性
		this.setTitle("五子棋0");
		this.setSize(1100, 1000);
		this.setIconImage(new ImageIcon("image\\saierda.png").getImage());
		
		
		//創建按鈕面板物件
		JPanel jp_1=new JPanel(new FlowLayout(FlowLayout.CENTER,20,10));
		jp_1.setBackground(Color.gray);
		JButton btn_1=new JButton();
		JButton btn_2=new JButton();
		JButton btn_3=new JButton();
		JButton btn_4=new JButton();
		JButton btn_5=new JButton();
		JButton btn_6=new JButton();
		JButton btn_7=new JButton();
		JButton btn_8=new JButton();
		
		//設定按鈕內容
		btn_1.setText("悔棋");
		btn_2.setText("回放");
		btn_3.setText("存檔");
		btn_4.setText("讀檔");
		btn_5.setText("回傳選單");
		btn_6.setText("開始錄制");
		btn_7.setText("停止錄制");
		btn_8.setText("重新開始");
		
		btn_1.setFont(new Font("SimSun",1,15));
		btn_2.setFont(new Font("SimSun",1,15));
		btn_3.setFont(new Font("SimSun",1,15));
		btn_4.setFont(new Font("SimSun",1,15));
		btn_5.setFont(new Font("SimSun",1,15));
		btn_6.setFont(new Font("SimSun",1,15));
		btn_7.setFont(new Font("SimSun",1,15));
		btn_8.setFont(new Font("SimSun",1,15));

		Dimension dim_1=new Dimension(1000,70);
		Dimension dim_2=new Dimension(100,40);
		
		//設定按鈕大小
		btn_1.setPreferredSize(dim_2);
		btn_2.setPreferredSize(dim_2);
		btn_3.setPreferredSize(dim_2);
		btn_4.setPreferredSize(dim_2);
		btn_5.setPreferredSize(dim_2);
		btn_6.setPreferredSize(dim_2);
		btn_7.setPreferredSize(dim_2);
		btn_8.setPreferredSize(dim_2);
		
		
		//設定面板大小
		jp_1.setPreferredSize(dim_1);
		//在面板上加入按鈕
		jp_1.add(btn_1);
		jp_1.add(btn_2);
		jp_1.add(btn_3);
		jp_1.add(btn_4);
		jp_1.add(btn_5);
		jp_1.add(btn_6);
		jp_1.add(btn_7);
		jp_1.add(btn_8);
		
		this.add(jp_1,BorderLayout.SOUTH);//將面板以邊界布局加到視窗上
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setLocationRelativeTo(null);
		this.setVisible(true);
		
		
		//獲取畫筆并將畫筆傳入監聽器
		wl.setGraphics(this.getGraphics());
			
		//加上監聽器
		this.addMouseListener(wl);

			
	}
			public void paint(Graphics g) {
			//呼叫父類的表單繪制方法
			super.paint(g);
			
			//加入背景圖并且設計它的尺寸
			//我們這里還設定了一個背景板,通過畫筆的先后順序先畫背景后畫棋盤來覆寫,從而實作設定背景
			g.drawImage(bg1img, 0, 0, 1200, 920,null);
			g.drawImage(bgimg, X-SIZE, Y-SIZE, ROW*SIZE+2*SIZE, ROW*SIZE+2*SIZE, null);
			//設定棋盤網格
			for(int i=0;i<=ROW;i++) {
				
			g.drawLine(X, Y+i*SIZE, X+ROW*SIZE, Y+i*SIZE);
			g.drawLine(X+i*SIZE, Y, X+i*SIZE, Y+CLOUN*SIZE);
			}		
	
		
}



package com.xsx0805;
import javax.swing.*; 
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class WuZiqiListener implements MouseListener,GoBaangConfig {


	
	private Graphics g;

	//設定getGraphics來傳址
	public void setGraphics(Graphics g) {this.g=g;}

	@Override
	public void mouseClicked(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}
	

}

package com.xsx0805;

public interface GoBaangConfig {
	
	/*** SIZE: 棋盤間距 兼 棋子直徑 */ 
	int SIZE=50;

	/*** 棋盤左上角 X坐 標 */ 
	int X=100;
	
	
	/*** 棋盤左上角 Y 坐 標 */
	int Y=100; 
	
	
	/*** 棋盤的行列值 */
	int ROW=15; 
	int CLOUN=15;

}

效果圖

  • 這里我自己畫了一個丑丑的背景=.=
    在這里插入圖片描述

如何在棋盤上下棋

繪制棋子

  • 設定棋子的尺寸大小–通過行列間距來設定棋子寬高
  • 獲取棋子坐標—通過滑鼠監聽器來獲取按下滑鼠時的坐標
	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub
		int x=e.getX();
		int y=e.getY();
  • 我們可以通過呼叫我們繪制背景的畫筆來畫棋子
		g.fillOval(x, y,SIZE, SIZE);

設定輪流下棋

  • 問題:下出來的棋子都是一個顏色
    解決方法:通過創建if陳述句來設定每下一次棋換棋子顏色
	//設定全域變數
	int flag=0;
 	
 	//然后在方法里設定回圈
 		if(flag==0) {
		g.setColor(Color.white);

		flag++;
		}
		else if(flag==1){
		g.setColor(Color.black);

		flag--;
		}

這樣就可以實作白黑棋子輪流下棋

設定下棋范圍

設定落子點為網格交叉處

-問題:我們下棋不能下到網格交叉處該怎么辦?
-解決辦法:通過將獲取到的棋子坐標轉化為行列值來畫圖

-實作:設定全域變數chessx,chessy來表示行列值
			選定好下棋的區域通過chessx=(x-X+SIZE/2)/SIZE、chessy=(y-Y+SIZE/2)/SIZE;;來實作坐標的行列值化
			將畫筆的畫圖坐標改成行列值坐標		
			//設定全域變數chessx,chessy來表示行列值
			int chessx;
			int chessy;

			//選定好下棋的區域通過chessx=(x-X+SIZE/2)/SIZE、chessy=(y-Y+SIZE/2)/SIZE;;來實作坐標的行列值化
			chessx=(x-X+SIZE/2)/SIZE;
			chessy=(y-Y+SIZE/2)/SIZE;
			//將畫筆的畫圖坐標改成行列值坐標	
			g.fillOval(chessx*SIZE+X-SIZE/2, chessy*SIZE+Y-SIZE/2,SIZE, SIZE);

落子邊界設定

-問題:我們下棋有可能下到棋盤外面該如何解決?
-解決辦法:通過判斷所下棋子的行和列是否大于0小于行列數判斷它落子是否正確

-實作:設定if陳述句
		if(chessx<0||chessx>ROW) {
			return;
		}
		if(chessy<0||chessy>CLOUN) {
			return;
		}

重繪棋子

所遇到的問題:怎么知道知道棋盤的棋子布局??
解決辦法:建立二維陣列來儲存棋子布局資訊
	- 創建二維陣列:int[][] chessNumArr=new chessNumArr[ROW+1][CLOUN+1]來存盤資訊
	- 設定棋子資訊:0表示沒有棋子;1表示黑棋;2表示白棋;用chessNum來設定
	- 存盤資訊、畫圖:先將陣列物件傳址給視窗體的繪圖方法;通過for回圈遍歷棋盤給陣列賦值然后畫圖;
		//設定陣列來存盤棋盤資訊
		//設定陣列來存盤棋盤資訊
		int chessNum=0;//設定棋盤資料表示棋盤布局黑棋:1、白棋:2、空:0
		int[][] chessNumArr=new int[ROW+1][CLOUN+1];
		//用此方法獲取陣列地址
		public int[][] getchessNumArr() {
		return chessNumArr;
	}
		
		//表單方法中
			//獲取監聽器的陣列資料
			int [][] chessNumArr=wl.getchessNumArr();
			//利用棋盤布局來再次繪制棋盤
			for(int i=0;i<chessNumArr.length;i++) {
				for(int j=0;j<chessNumArr[i].length;j++) {
//					System.out.print(chessNumArr[j][i]+" ");//用此可以將棋盤列印出來
					int chessNum=chessNumArr[i][j];
					if(chessNum==2) {
						g.setColor(Color.white);
						g.fillOval(i*SIZE+X-SIZE/2, j*SIZE+Y-SIZE/2,SIZE, SIZE);
					}
					else if(chessNum==1) {
						g.setColor(Color.black);
						g.fillOval(i*SIZE+X-SIZE/2, j*SIZE+Y-SIZE/2,SIZE, SIZE);
					} else{
						
					}
					
				}
			}

			

設定不能重復下棋

  • 解決辦法:我們可以通過檢查存盤的棋盤資訊來判斷這個落點是否有棋子
  • 實作:設定if陳述句判斷chessNum的值
			if(chessNumArr[chessx][chessy]!=0) {
			return;
		}

如何設定悔棋

解決方法:

	-創建一個chess類來存盤下棋的順序和屬性;				
	-通過取出上一下好的棋子洗掉;
	-重畫;
	-加上動作監聽器來獲取按鈕“悔棋”的操作
	-將表單類的物件傳址過來使用重畫重繪界面

關鍵代碼:


//創建一個類存盤資訊
package com.xsx0805;

public class Chess {

	int index;
	int chessNum;
	int row,clun;
	
	
	public  Chess(int index,int chessNum,int row,int clun) {
		
		
		this.index=index;
		this.chessNum=chessNum;
		this.row=row;
		this.clun=clun;
	}
	/*
	 * index:落子順序
	 * chessNum:棋子的黑白序號
	 * row:行
	 * clun:列
	 * */
}


//在監聽器中創建物件來存入資訊
		//用這個方法來存盤下棋順序
		Chess[] chesslist=new Chess[ROW*CLOUN];
		int chessIndex;
		//下完棋子之后
		//用此來存盤一個棋子物件
		chesslist[chessIndex]=new Chess(chessIndex,chessNum,chessx,chessy);
		chessIndex++;
//在視窗體類、監聽器類中加入動作監聽器
	//監聽器中再加上動作監聽讓他實作滑鼠和按鈕監聽
	import java.awt.event.ActionListener;
	class WuZiqiListener implements MouseListener,GoBaangConfig,ActionListener

	//將表單物件傳址過來
	public WuZiqi wzq;
	public void setWuZiqi(WuZiqi wzq) {this.wzq=wzq;}
	//寫撤回按鈕內容,通過取出上一次棋子資訊并清除來實作悔棋目的		
	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		String btner=e.getActionCommand();
				if(btner.equals("悔棋")) {
			System.out.println("撤回");
			//從存盤資料中取出這個棋子物件
			Chess chess=chesslist[chessIndex-1];
			if(chessNumArr[chess.row][chess.clun]==1) {

			}else if(chessNumArr[chess.row][chess.clun]==2) {

			}
			//由這個棋子的行列值洗掉這個棋子在chessNumArr中的資料
			chessNumArr[chess.row][chess.clun]=0;
			//刪去它在資料中的值
			chesslist[chessIndex-1]=null;
			chessIndex--;
			wzq.repaint();
			
		}
	}	

	//視窗體中給按鈕加上動作監聽
			//給按鈕加上動作監聽器
		btn_1.addActionListener(wl);
		btn_2.addActionListener(wl);
		btn_3.addActionListener(wl);
		btn_4.addActionListener(wl);
		btn_5.addActionListener(wl);
		btn_6.addActionListener(wl);
		btn_7.addActionListener(wl);
		btn_8.addActionListener(wl);
	
		//使用方法傳址給監聽器
		wl.setWuZiqi(this);
	}

實作后的代碼

package com.xsx0813;

public class Chess {
	
	int index;
	int chessNum;
	int row,clun;
	
	
	public  Chess(int index,int chessNum,int row,int clun) {
		
		
		this.index=index;
		this.chessNum=chessNum;
		this.row=row;
		this.clun=clun;
	}
	/*
	 * index:落子順序
	 * chessNum:棋子的黑白序號
	 * row:行
	 * clun:列
	 * */

}

package com.xsx0813;

public interface GoBaangConfig {
	
	/*** SIZE: 棋盤間距 兼 棋子直徑 */ 
	int SIZE=50;

	/*** 棋盤左上角 X坐 標 */ 
	int X=100;
	
	
	/*** 棋盤左上角 Y 坐 標 */
	int Y=100; 
	
	
	/*** 棋盤的行列值 */
	int ROW=15; 
	int CLOUN=15;

}


package com.xsx0813;


import javax.swing.*; 
import java.awt.*;
public class WuZiqi extends JFrame implements GoBaangConfig{
	
	private static final Image bgimg=new ImageIcon("image\\yellow.png").getImage();
	private static final Image bg1img=new ImageIcon("image\\背景板.png").getImage();	
	//創建監聽器物件
	private WuZiqiListener wl=new WuZiqiListener();
	//設定視窗體
	public void initUI() {
		
		//設定視窗體屬性
		this.setTitle("五子棋0");
		this.setSize(1100, 1000);
		this.setIconImage(new ImageIcon("image\\saierda.png").getImage());
		
		
		//創建按鈕面板物件
		JPanel jp_1=new JPanel(new FlowLayout(FlowLayout.CENTER,20,10));
		jp_1.setBackground(Color.gray);
		JButton btn_1=new JButton();
		JButton btn_2=new JButton();
		JButton btn_3=new JButton();
		JButton btn_4=new JButton();
		JButton btn_5=new JButton();
		JButton btn_6=new JButton();
		JButton btn_7=new JButton();
		JButton btn_8=new JButton();
		
		//設定按鈕內容
		btn_1.setText("悔棋");
		btn_2.setText("回放");
		btn_3.setText("存檔");
		btn_4.setText("讀檔");
		btn_5.setText("回傳選單");
		btn_6.setText("開始錄制");
		btn_7.setText("停止錄制");
		btn_8.setText("重新開始");
		
		btn_1.setFont(new Font("SimSun",1,15));
		btn_2.setFont(new Font("SimSun",1,15));
		btn_3.setFont(new Font("SimSun",1,15));
		btn_4.setFont(new Font("SimSun",1,15));
		btn_5.setFont(new Font("SimSun",1,15));
		btn_6.setFont(new Font("SimSun",1,15));
		btn_7.setFont(new Font("SimSun",1,15));
		btn_8.setFont(new Font("SimSun",1,15));

		Dimension dim_1=new Dimension(1000,70);
		Dimension dim_2=new Dimension(100,40);
		
		//設定按鈕大小
		btn_1.setPreferredSize(dim_2);
		btn_2.setPreferredSize(dim_2);
		btn_3.setPreferredSize(dim_2);
		btn_4.setPreferredSize(dim_2);
		btn_5.setPreferredSize(dim_2);
		btn_6.setPreferredSize(dim_2);
		btn_7.setPreferredSize(dim_2);
		btn_8.setPreferredSize(dim_2);
		
		
		//設定面板大小
		jp_1.setPreferredSize(dim_1);
		//在面板上加入按鈕
		jp_1.add(btn_1);
		jp_1.add(btn_2);
		jp_1.add(btn_3);
		jp_1.add(btn_4);
		jp_1.add(btn_5);
		jp_1.add(btn_6);
		jp_1.add(btn_7);
		jp_1.add(btn_8);
		
		//給按鈕加上動作監聽器
		btn_1.addActionListener(wl);
		btn_2.addActionListener(wl);
		btn_3.addActionListener(wl);
		btn_4.addActionListener(wl);
		btn_5.addActionListener(wl);
		btn_6.addActionListener(wl);
		btn_7.addActionListener(wl);
		btn_8.addActionListener(wl);
		
		this.add(jp_1,BorderLayout.SOUTH);//將面板以邊界布局加到視窗上
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setLocationRelativeTo(null);
		this.setVisible(true);
		
		
		//使用方法傳址給監聽器
		wl.setWuZiqi(this);
		//獲取畫筆并將畫筆傳入監聽器
		wl.setGraphics(this.getGraphics());
			
		//加上監聽器
		this.addMouseListener(wl);


			
	}
	
	public void paint(Graphics g) {
	//呼叫父類的表單繪制方法
	super.paint(g);
	
	//加入背景圖并且設計它的尺寸
	g.drawImage(bg1img, 0, 0, 1200, 920,null);
	g.drawImage(bgimg, X-SIZE, Y-SIZE, ROW*SIZE+2*SIZE, ROW*SIZE+2*SIZE, null);
	//設定棋盤網格
	for(int i=0;i<=ROW;i++) {
		
	g.drawLine(X, Y+i*SIZE, X+ROW*SIZE, Y+i*SIZE);
	g.drawLine(X+i*SIZE, Y, X+i*SIZE, Y+CLOUN*SIZE);
	
	}
	//獲取監聽器的陣列資料
	int [][] chessNumArr=wl.getchessNumArr();
	//利用棋盤布局來再次繪制棋盤
	for(int i=0;i<chessNumArr.length;i++) {
		for(int j=0;j<chessNumArr[i].length;j++) {
//			System.out.print(chessNumArr[j][i]+" ");//用此可以將棋盤列印出來
			int chessNum=chessNumArr[i][j];
			if(chessNum==2) {
				g.setColor(Color.white);
				g.fillOval(i*SIZE+X-SIZE/2, j*SIZE+Y-SIZE/2,SIZE, SIZE);
			}
			else if(chessNum==1) {
				g.setColor(Color.black);
				g.fillOval(i*SIZE+X-SIZE/2, j*SIZE+Y-SIZE/2,SIZE, SIZE);
			} else{
				
			}
			
		}
	}
	}		
}


package com.xsx0813;
import javax.swing.*;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class WuZiqiListener implements MouseListener,GoBaangConfig,ActionListener {


		public WuZiqi wzq;
		public void setWuZiqi(WuZiqi wzq) {this.wzq=wzq;}
		private Graphics g;
		public void setGraphics(Graphics g) {this.g=g;}
		//判斷下棋顏色
		int flag=0;
		
		//設定行列坐標
		int chessx;
		int chessy;
		//設定陣列來存盤棋盤資訊
		int chessNum=0;//設定棋盤資料表示棋盤布局黑棋:1、白棋:2、空:0
		int[][] chessNumArr=new int[ROW+1][CLOUN+1];
		//通過這個方法來傳值
		public int[][] getchessNumArr() {
			return chessNumArr;
		}
		//用這個方法來存盤下棋順序
		Chess[] chesslist=new Chess[ROW*CLOUN];
		int chessIndex;
		
		
	@Override
	public void actionPerformed(ActionEvent e) {
			// TODO Auto-generated method stub
		String btner=e.getActionCommand();
		if(btner.equals("悔棋")) {
			System.out.println("撤回");
			//從存盤資料中取出這個棋子物件
			Chess chess=chesslist[chessIndex-1];
			if(chessNumArr[chess.row][chess.clun]==1) {

			}else if(chessNumArr[chess.row][chess.clun]==2) {

			}
			//由這個棋子的行列值洗掉這個棋子在chessNumArr中的資料
			chessNumArr[chess.row][chess.clun]=0;
			//刪去它在資料中的值
			chesslist[chessIndex-1]=null;
			chessIndex--;
			wzq.repaint();
		}
		if(btner.equals("重新開始")) {
		}
	}
	@Override
	public void mouseClicked(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub
		//獲取落點坐標
		int x=e.getX();
		int y=e.getY();
		
		//進行坐標轉化
		chessx=(x-X+SIZE/2)/SIZE;
		chessy=(y-Y+SIZE/2)/SIZE;
		
		//設定下棋邊界,做到不能在棋盤外下棋
		if(chessx<0||chessx>ROW) {
			return;
		}
		if(chessy<0||chessy>CLOUN) {
			return;
		}
		//設定不能重復下棋
		if(chessNumArr[chessx][chessy]!=0) {
		return;
	}
		//繪制棋子
 		if(flag==0) {
		g.setColor(Color.white);
		chessNum=2;
		chessNumArr[chessx][chessy]=chessNum;
		flag++;
		}
		else if(flag==1){
		g.setColor(Color.black);
		chessNum=1;
		chessNumArr[chessx][chessy]=chessNum;
		flag--;
		}
 		g.fillOval(chessx*SIZE+X-SIZE/2, chessy*SIZE+Y-SIZE/2,SIZE, SIZE);
 		
		//用此來存盤一個棋子物件
		chesslist[chessIndex]=new Chess(chessIndex,chessNum,chessx,chessy);
		chessIndex++;
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}
	

}

package com.xsx0813;

public class StartGame {
	public static void main(String[] args) {
		WuZiqi wzq=new WuZiqi();
		wzq.initUI();
	}

}
	

如何判斷勝負

思路:遍歷棋盤,看縱向、橫向兩個斜向是否有五顆同色棋子相連;如果有判斷贏;如果沒有;判斷輸

代碼實作

-創建一個boolean類在里面寫好判斷代碼,輸入棋子資訊然后輸出true\false來判斷勝負
-方法寫成static可以直接使用類呼叫
	package com.xsx0813;

import java.awt.Color;

public class WinChess {
	

	public static boolean win(int[][] chessNumArr,int row,int cloun) {
		if(winrow(chessNumArr,row,cloun)>=5||wincloun(chessNumArr,row, cloun)>=5
		||winxie_1(chessNumArr,row,cloun)>=5||winxie_2(chessNumArr,row,cloun)>=5) {
			return true;
		}
		else {
			return false;
		}
	}


	public static int	winrow(int[][] chessNumArr,int row ,int cloun) {
		int count=0;
		for(int j=cloun;j<=15;j++) {
			if(chessNumArr[row][j]==chessNumArr[row][cloun]) {
				count++;
			}	
			else {
				break;			
			}	
		}
		for(int j=cloun-1;j>=0;j--) {
			if(chessNumArr[row][j]==chessNumArr[row][cloun]) {
				count++;
			}
				
			else {
				break;
			}	
		}
		return count;	
		}
	public static int wincloun(int[][] chessNumArr,int row ,int cloun) {
		int count=1;
		for(int i=row+1;i<=15;i++) {
			if(chessNumArr[i][cloun]==chessNumArr[row][cloun]) {
				count++;
			}

			else {
				break;
			}
		}
		for(int i=row-1;i>=0;i--) {
			if(chessNumArr[i][cloun]==chessNumArr[row][cloun]) {
				count++;
			}
				
			else {
				break;
			}
		}
	     return count;
	}
		public static int winxie_1(int[][] chessNumArr,int row ,int cloun) {
		int count=1;
		for(int j=cloun+1,i=row-1;i>=0&&j<=15;i--,j++) {
				if(chessNumArr[i][j]==chessNumArr[row][cloun]) {
					count++;
				}
				
				else {
					break;
				}
	        }

		for(int j=cloun-1,i=row+1;i<=15&&j>=0;i++,j--) {
				if(chessNumArr[i][j]==chessNumArr[row][cloun]) {
					count++;
				}
				else {
					break;
				}
	        }
			return count;
	}
		public static int winxie_2(int[][] chessNumArr,int row ,int cloun) {
		int count=1;
		for(int j=row+1,i=cloun+1;i<=15&&j<=15;i++,j++) {
				if(chessNumArr[i][j]==chessNumArr[row][cloun]) {
					count++;
				}
				
				else {
					break;
				}
	        }

		for(int j=cloun-1,i=row-1;i>=0&&j>=0;i--,j--) {
				if(chessNumArr[i][j]==chessNumArr[row][cloun]) {
					count++;
				}
				
				else {
					break;
				}

	        }
		return count;
		}
		
}

		if(WinChess.win(chessNumArr, chessx, chessy)==true) {
			if(chessNumArr[chessx][chessy]==1) {
				System.out.println("黑棋勝!");
			}else {
				System.out.println("白棋勝!");
			}
			
		}
	}

實作影像

在這里插入圖片描述

如何設定登錄界面以及頁面跳轉

創建登錄界面、并設定一個賬號、密碼登錄

我們如何設定界面跳轉??

	- 將我們選擇這個視窗可視化關閉再參考下一個視窗體建立的方法創建視窗體;
	- 我們需要將視窗體物件傳址進入監聽器然后實作視窗體的可視化false;

如何呼叫其他類視窗提的方法??

	-創建一個public static void  mian(String[] args){}函式里面創建一個物件參考一個視窗體建立函式;這樣其他類也可以呼叫啦
		public static void main(String[] args) {
		new StartUI().startUI();
		
	}

如何實作存檔讀檔

	-存檔:將存檔時的棋子資訊傳給設定好的陣列已經計數物件;
	-讀檔:再將存盤好的值賦值給此時的棋盤陣列和計數物件
	-重繪
		//全域變數記錄存檔資訊
		int countblack1=0;
		int countwhite1=0;
		int[][] chessRecord=new int[ROW+1][CLOUN+1];
			//設定按鈕資訊
			if(btner.equals("存檔")) {
			System.out.println("存檔");
			//應用后面的方法來存資料
			for(int i=0;i<chessNumArr.length;i++) {
				for(int j=0;j<chessNumArr[i].length;j++) {
					chessRecord[i][j]=chessNumArr[i][j];
				}
			}
			countblack1=countblack;
			countwhite1=countwhite;


		}
		if(btner.equals("讀檔")){
			System.out.println("讀檔");
			for(int i=0;i<chessNumArr.length;i++) {
				for(int j=0;j<chessNumArr[i].length;j++) {
					chessNumArr[i][j]=chessRecord[i][j];
				}
			}
			countblack=countblack1;
			countwhite=countwhite1;

			wzqjf.repaint();
			}

各項實作后的代碼

package com.xsx0813;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

public class LoginUI extends JFrame {
	
	private LoginListener ll=new LoginListener();
	public void LoginUI() {
		
		String text1;
		String pwd;
		//設定視窗
		this.setTitle("66五子棋");
		this.setSize(400, 400);
		this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		this.setIconImage(new ImageIcon("image\\saierda.png").getImage());
		
		//設定按鈕
		JButton btn=new JButton();
		JButton btn1=new JButton();
		btn.setText("登錄");
		btn1.setText("注冊");
		btn.setFont(new Font("SimSun",1,15));
		btn1.setFont(new Font("SimSun",1,15));
		
		//設定標簽
		//設定影像
		ImageIcon image=new ImageIcon("image\\wzq.png");
		JLabel label=new JLabel(image);
		//設定賬號密碼文字
		JLabel j1=new JLabel();
		JLabel j2=new JLabel("賬號:");
		JLabel j3=new JLabel("密碼:");
		j2.setFont(new Font("STFangsong",1,17));
		j3.setFont(new Font("STFangsong",1,17));
		//設定面板
		JPanel jpp_1=new JPanel(new FlowLayout(FlowLayout.CENTER,20,15));
		JPanel jpp_2=new JPanel(new FlowLayout(FlowLayout.CENTER,30,2));
		jpp_1.setBackground(Color.gray);
		jpp_2.setBackground(Color.gray);

		//設定輸入框
		JTextField jt1=new JTextField();
		JPasswordField jp1=new JPasswordField();

		//設定尺寸大小
		Dimension dim_1=new Dimension(100,50);//面板
		Dimension dim_2=new Dimension(250,25);//輸入框
		Dimension dim_3=new Dimension(400,200);//圖片標簽
		Dimension dim_4=new Dimension(100,25);//按鈕
		
		//圖片標簽大小
		label.setPreferredSize(dim_3);
		//輸入框尺寸
		jt1.setPreferredSize(dim_2);
		jp1.setPreferredSize(dim_2);
		//面板尺寸
		jpp_1.setPreferredSize(dim_1);
		jpp_2.setPreferredSize(dim_1);
		//按鈕尺寸
		btn.setPreferredSize(dim_4);
		btn1.setPreferredSize(dim_4);
		
		//加入監聽器
		//按鈕加上動作監聽器
		btn.addActionListener(ll);
		btn1.addActionListener(ll);
		
		//將內容加到面板上
		//賬號--面板1
		jpp_1.add(j2);
		jpp_1.add(jt1);
		//密碼--面板1
		jpp_1.add(j3);
		jpp_1.add(jp1);
		//按鈕--面板2
		jpp_2.add(btn);
		jpp_2.add(btn1);
		
		//將面板和標簽加入表單
		this.add(jpp_2,BorderLayout.SOUTH);//采用邊界布局放在南邊
		this.add(jpp_1,BorderLayout.CENTER);
		this.add(label,BorderLayout.NORTH);
		
		//設定可視化
		this.setVisible(true);
		
		
		//參考本類
		ll.setLoginUI(this);
		ll.setJTextField(jt1);
		ll.setJPasswordField(jp1);
		
		this.setLocationRelativeTo(null);
	
}
}

package com.xsx0813;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JOptionPane;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

public class LoginListener implements ActionListener{
	
	public LoginUI loginjf;
	public JTextField jt1;
	public JPasswordField jp1;


	public void setLoginUI(LoginUI loginjf) {this.loginjf=loginjf;}
	public void setJTextField(JTextField jt1) {this.jt1=jt1;}
	public void setJPasswordField(JPasswordField jp1) {this.jp1=jp1;}

	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		String btner=e.getActionCommand();
		if(btner.equals("登錄")) {
			String text1;
			String pwd;
			//獲取輸入框文本
			text1=jt1.getText();
			pwd=jp1.getText();
			//判斷密碼是否正確
			if(text1.equals("123")&&pwd.equals("123")) {
			loginjf.setVisible(false);
			StartUI.main(null);
			}else {
				JOptionPane.showMessageDialog(null, "賬號或密碼錯誤");
				}
		}
	}

}
package com.xsx0813;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class StartUI extends JFrame implements GoBaangConfig {
	
	private StartListener sl=new StartListener();
	
	public static void main(String[] args) {
		new StartUI().startUI();
		
	}
	public void startUI(){	
		
		//創建表單物件
		this.setTitle("66五子棋");
		this.setSize(400, 400);
		this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		this.setIconImage(new ImageIcon("image\\saierda.png").getImage());
		//設定插入圖片
		ImageIcon image=new ImageIcon("image\\saierda.png");
		
		//設定標簽
		JLabel label2=new JLabel(image);
		
		//設定面板
		JPanel jp1=new JPanel(new FlowLayout(FlowLayout.CENTER,100,10));
		jp1.setBackground(Color.gray);
		
		//設定按鈕
		JButton btn1=new JButton();
		JButton btn2=new JButton();
		JButton btn3=new JButton();
		JButton btn4=new JButton();
		//設定內容
		btn1.setText("人機模式");
		btn2.setText("雙人模式");
		btn3.setText("聯機對戰");
		btn4.setText("回傳登錄");
		btn1.setFont(new Font("STFangsong",1,15));
		btn2.setFont(new Font("STFangsong",1,15));
		btn3.setFont(new Font("STFangsong",1,15));
		btn4.setFont(new Font("STFangsong",1,15));
		
		//給按鈕加監聽器
		btn1.addActionListener(sl);
		btn2.addActionListener(sl);
		btn3.addActionListener(sl);
		btn4.addActionListener(sl);
		
		
		//設定尺寸
		Dimension dim1=new Dimension(150,30);
		Dimension dim2=new Dimension(100,170);
		Dimension dim3=new Dimension(200,200);
		
		//設定按鈕尺寸
		btn1.setPreferredSize(dim1);
		btn2.setPreferredSize(dim1);
		btn3.setPreferredSize(dim1);
		btn4.setPreferredSize(dim1);
		
		//設定面板尺寸
		jp1.setPreferredSize(dim2);
		
		//設定標簽尺寸
		label2.setPreferredSize(dim3);
					
		//將物件加到面板上
		jp1.add(btn1);
		jp1.add(btn2);
		jp1.add(btn3);
		jp1.add(btn4);
		
		
		//加入表單
		this.add(jp1,BorderLayout.SOUTH);
		this.add(label2,BorderLayout.NORTH);

		//可視化與傳地址
		sl.setStartUI(this);

		this.setVisible(true);
		this.setLocationRelativeTo(null);
		
		
		
	}
}
package com.xsx0813;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;

public class StartListener implements ActionListener {
	
	public StartUI startjf;
	
	public void setStartUI(StartUI startjf) {this.startjf=startjf;}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		String btner=e.getActionCommand();
		if(btner.equals("雙人模式")) {
			startjf.setVisible(false);
			WuZiqi.main(null);
			
		}
		
	}



}
package com.xsx0813;


import javax.swing.*; 
import java.awt.*;
public class WuZiqi extends JFrame implements GoBaangConfig{
	
	private static final Image bgimg=new ImageIcon("image\\yellow.png").getImage();
	private static final Image bg1img=new ImageIcon("image\\背景板.png").getImage();	
	//創建監聽器物件
	private  WuZiqiListener wl=new WuZiqiListener();
	
	//創建這一個物件只呼叫一個函式,讓其他類也可以使用這個方法
	public static void main(String[] args) {
		new WuZiqi().initUI();
	}
	//設定視窗體
	public  void initUI() {
		

		//設定視窗體屬性

		this.setTitle("五子棋0");
		this.setSize(1100, 1000);
		this.setIconImage(new ImageIcon("image\\saierda.png").getImage());
		
		
		//創建按鈕面板物件
		JPanel jp_1=new JPanel(new FlowLayout(FlowLayout.CENTER,20,10));
		jp_1.setBackground(Color.gray);
		JButton btn_1=new JButton();
		JButton btn_2=new JButton();
		JButton btn_3=new JButton();
		JButton btn_4=new JButton();
		JButton btn_5=new JButton();
		JButton btn_6=new JButton();
		JButton btn_7=new JButton();
		JButton btn_8=new JButton();
		
		//設定按鈕內容
		btn_1.setText("悔棋");
		btn_2.setText("回放");
		btn_3.setText("存檔");
		btn_4.setText("讀檔");
		btn_5.setText("回傳選單");
		btn_6.setText("開始錄制");
		btn_7.setText("停止錄制");
		btn_8.setText("重新開始");
		
		btn_1.setFont(new Font("SimSun",1,15));
		btn_2.setFont(new Font("SimSun",1,15));
		btn_3.setFont(new Font("SimSun",1,15));
		btn_4.setFont(new Font("SimSun",1,15));
		btn_5.setFont(new Font("SimSun",1,15));
		btn_6.setFont(new Font("SimSun",1,15));
		btn_7.setFont(new Font("SimSun",1,15));
		btn_8.setFont(new Font("SimSun",1,15));

		Dimension dim_1=new Dimension(1000,70);
		Dimension dim_2=new Dimension(100,40);
		
		//設定按鈕大小
		btn_1.setPreferredSize(dim_2);
		btn_2.setPreferredSize(dim_2);
		btn_3.setPreferredSize(dim_2);
		btn_4.setPreferredSize(dim_2);
		btn_5.setPreferredSize(dim_2);
		btn_6.setPreferredSize(dim_2);
		btn_7.setPreferredSize(dim_2);
		btn_8.setPreferredSize(dim_2);
		
		
		//設定面板大小
		jp_1.setPreferredSize(dim_1);
		//在面板上加入按鈕
		jp_1.add(btn_1);
		jp_1.add(btn_2);
		jp_1.add(btn_3);
		jp_1.add(btn_4);
		jp_1.add(btn_5);
		jp_1.add(btn_6);
		jp_1.add(btn_7);
		jp_1.add(btn_8);
		
		//給按鈕加上動作監聽器
		btn_1.addActionListener(wl);
		btn_2.addActionListener(wl);
		btn_3.addActionListener(wl);
		btn_4.addActionListener(wl);
		btn_5.addActionListener(wl);
		btn_6.addActionListener(wl);
		btn_7.addActionListener(wl);
		btn_8.addActionListener(wl);
		
		this.add(jp_1,BorderLayout.SOUTH);//將面板以邊界布局加到視窗上
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setLocationRelativeTo(null);
		this.setVisible(true);
		
		
		//使用方法傳址給監聽器
		wl.setWuZiqi(this);
		//獲取畫筆并將畫筆傳入監聽器
		wl.setGraphics(this.getGraphics());
			
		//加上監聽器
		this.addMouseListener(wl);


		
		
	}
	
	public void endUI1() {
		
		//設定視窗
		JFrame winjf=new JFrame();
		int [][] chessNumArr=wl.getchessNumArr();
		int chessx=wl.getchessx();
		int chessy=wl.getchessy();
		if(chessNumArr[chessx][chessy]==1) {
			winjf.setTitle("黑棋勝利");
		}else if(chessNumArr[chessx][chessy]==2) {
			winjf.setTitle("白棋勝利");
		} 
		winjf.setSize(500,400);
		winjf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		winjf.setIconImage(new ImageIcon("image\\saierda.png").getImage());
		
		//設定標簽以及影像
		ImageIcon image=new ImageIcon("image\\6.PNG");
		JLabel label=new JLabel(image);

		//創建按鈕和面板
		JButton btn_2=new JButton();
		JButton btn_3=new JButton();
		JButton btn_4=new JButton();
		JPanel jp_2=new JPanel(new FlowLayout(FlowLayout.CENTER,10,10));
//		jp_2.setBackground(Color.gray);
		
		//設定尺寸
		Dimension dim_2=new Dimension(300, 200);
		Dimension dim_3=new Dimension(100, 30);
		Dimension dim_4=new Dimension(200, 80);
		
		//設定面板標簽尺寸
		label.setPreferredSize(dim_2);
		jp_2.setPreferredSize(dim_4);

		//設定按鈕
		//設定按鈕大小
		btn_2.setPreferredSize(dim_3);
		btn_3.setPreferredSize(dim_3);
		btn_4.setPreferredSize(dim_3);
		//設定按鈕文字
		btn_3.setText("再來一把");
		btn_4.setText("回放");
		btn_2.setText("退出游戲");
		//將按鈕加上動作監聽器
		btn_3.addActionListener(wl);
		btn_4.addActionListener(wl);
		btn_2.addActionListener(wl);
		
		
		//將它加入面板
		jp_2.add(btn_4);
		jp_2.add(btn_3);
		jp_2.add(btn_2);
		winjf.add(jp_2,BorderLayout.SOUTH);
		winjf.add(label,BorderLayout.NORTH);

		winjf.setVisible(true);
		winjf.setLocationRelativeTo(null);
		wl.setwinjf(winjf);
		
					
	}
	
	public void paint(Graphics g) {
		//呼叫父類的表單繪制方法
		super.paint(g);
		
		//加入背景圖并且設計它的尺寸
		g.drawImage(bg1img, 0, 0, 1200, 920,null);
		g.drawImage(bgimg, X-SIZE, Y-SIZE, ROW*SIZE+2*SIZE, ROW*SIZE+2*SIZE, null);
		//設定棋盤網格
		for(int i=0;i<=ROW;i++) {
			
		g.drawLine(X, Y+i*SIZE, X+ROW*SIZE, Y+i*SIZE);
		g.drawLine(X+i*SIZE, Y, X+i*SIZE, Y+CLOUN*SIZE);
		}
		//獲取監聽器的陣列資料
		int [][] chessNumArr=wl.getchessNumArr();
		//利用棋盤布局來再次繪制棋盤
		for(int i=0;i<chessNumArr.length;i++) {
			for(int j=0;j<chessNumArr[i].length;j++) {
//				System.out.print(chessNumArr[j][i]+" ");
				int chessNum=chessNumArr[i][j];
				if(chessNum==2) {
					g.setColor(Color.white);
					g.fillOval(i*SIZE+X-SIZE/2, j*SIZE+Y-SIZE/2,SIZE, SIZE);
				}
				else if(chessNum==1) {
					g.setColor(Color.black);
					g.fillOval(i*SIZE+X-SIZE/2, j*SIZE+Y-SIZE/2,SIZE, SIZE);
				} else{
					
				}
				
			}
		}
		
		//重畫計數器
		int countblack=wl.getcountblack();
		int countwhite=wl.getcountwhite();
		
		//畫字體
		Font font=new Font("宋體",Font.BOLD,25);
		Color color=new Color(255,255,255,255);
		g.setColor(color.gray);
		g.fillRect(900, 70, 200, 150);
		g.setColor(color.ORANGE);
		g.setFont(font);
		g.drawString("黑棋:"+countblack, 960, 130);
		g.drawString("白棋:"+countwhite, 960, 170);
		
		g.setColor(color.gray);
		g.fillRect(900, 220, 200, 150);
		g.setColor(color.orange);
		g.setFont(font);
		g.drawString("下回合", 960, 280);
		if(countblack==countwhite) {
			g.setColor(color.orange);
			g.setFont(font);
			g.drawString("白棋", 960, 320);
			
		}else if(countblack<countwhite) {
			g.setColor(color.orange);
			g.setFont(font);
			g.drawString("黑棋", 960, 320);
		}
	}
	

	
}

}
package com.xsx0813;
import javax.swing.*;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class WuZiqiListener implements MouseListener,GoBaangConfig,ActionListener {		
		public WuZiqi wzqjf;	
		public void setWuZiqi(WuZiqi wzqjf) {this.wzqjf=wzqjf;}
		
		public JFrame winjf;	
		public void setwinjf(JFrame winjf) {this.winjf=winjf;}
		
		private Graphics g;
		public void setGraphics(Graphics g) {this.g=g;}
		//判斷下棋顏色
		int flag=0;
		
		//設定行列坐標
		int chessx;
		int chessy;
		//記錄黑白棋子資訊
		int countblack=0;
		int countwhite=0;
		
		//記錄存檔資訊
		int countblack1=0;
		int countwhite1=0;
		int[][] chessRecord=new int[ROW+1][CLOUN+1];
		//設定陣列來存盤棋盤資訊
		int chessNum=0;//設定棋盤資料表示棋盤布局黑棋:1、白棋:2、空:0
		int[][] chessNumArr=new int[ROW+1][CLOUN+1];
		//通過這個方法來傳值
		public int[][] getchessNumArr() {
			return chessNumArr;
		}
		public int getchessx() {
			return chessx;
		}
		public int getchessy() {
			return chessy;
		}
		//用這個方法來存盤下棋順序
		Chess[] chesslist=new Chess[ROW*CLOUN];
		int chessIndex;
		//傳值黑白棋數
		public int getcountwhite() {
			return countwhite;
		}
		public int getcountblack() {
			return countblack;
		}
		
	@Override
	public void actionPerformed(ActionEvent e) {
			// TODO Auto-generated method stub
		String btner=e.getActionCommand();
		if(btner.equals("存檔")) {
			System.out.println("存檔");
			//應用后面的方法來存資料
			for(int i=0;i<chessNumArr.length;i++) {
				for(int j=0;j<chessNumArr[i].length;j++) {
					chessRecord[i][j]=chessNumArr[i][j];
				}
			}
			countblack1=countblack;
			countwhite1=countwhite;


		}
		if(btner.equals("讀檔")){
			System.out.println("讀檔");
			for(int i=0;i<chessNumArr.length;i++) {
				for(int j=0;j<chessNumArr[i].length;j++) {
					chessNumArr[i][j]=chessRecord[i][j];
				}
			}
			countblack=countblack1;
			countwhite=countwhite1;

			wzqjf.repaint();
			}
		if(btner.equals("回傳選單")) {
			for(int i=0;i<chessNumArr.length;i++) {
				for(int j=0;j<chessNumArr[i].length;j++) {
					chessNumArr[i][j]=0;
				}
			}
			countblack=0;
			countwhite=0;
			wzqjf.setVisible(false);
			StartUI.main(null);
			
		}
		if(btner.equals("悔棋")) {
			System.out.println("撤回");
			//從存盤資料中取出這個棋子物件
			Chess chess=chesslist[chessIndex-1];
			if(chessNumArr[chess.row][chess.clun]==1) {
				countblack--;
			}else if(chessNumArr[chess.row][chess.clun]==2) {
				countwhite--;
			}
			//由這個棋子的行列值洗掉這個棋子在chessNumArr中的資料
			chessNumArr[chess.row][chess.clun]=0;
			//刪去它在資料中的值
			chesslist[chessIndex-1]=null;
			chessIndex--;
			wzqjf.repaint();
			
		}
		if(btner.equals("重新開始")) {
			for(int i=0;i<chessNumArr.length;i++) {
				for(int j=0;j<chessNumArr[i].length;j++) {
					chessNumArr[i][j]=0;
				}
			}
			countblack=0;
			countwhite=0;
			wzqjf.repaint();
		}
		if(btner.equals("再來一把")) {
			for(int i=0;i<chessNumArr.length;i++) {
				for(int j=0;j<chessNumArr[i].length;j++) {
					chessNumArr[i][j]=0;
				}
			}
			countblack=0;
			countwhite=0;
			wzqjf.repaint();
			winjf.setVisible(false);
	
			
		}
		if(btner.equals("退出游戲")) {
			System.exit(0);
		}
	}

	@Override
	public void mouseClicked(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub
		//獲取落點坐標
		int x=e.getX();
		int y=e.getY();
		
		//進行坐標轉化
		chessx=(x-X+SIZE/2)/SIZE;
		chessy=(y-Y+SIZE/2)/SIZE;
		
		//設定下棋邊界,做到不能在棋盤外下棋
		if(chessx<0||chessx>ROW) {
			return;
		}
		if(chessy<0||chessy>CLOUN) {
			return;
		}
		//設定不能重復下棋
		if(chessNumArr[chessx][chessy]!=0) {
		return;
	}
		//繪制棋子
 		if(flag==0) {
		g.setColor(Color.white);
		chessNum=2;
		chessNumArr[chessx][chessy]=chessNum;
		countwhite++;
		flag++;
		}
		else if(flag==1){
		g.setColor(Color.black);
		chessNum=1;
		chessNumArr[chessx][chessy]=chessNum;
		countblack++;
		flag--;
		}
 		g.fillOval(chessx*SIZE+X-SIZE/2, chessy*SIZE+Y-SIZE/2,SIZE, SIZE);
 		
		//用此來存盤一個棋子物件
		chesslist[chessIndex]=new Chess(chessIndex,chessNum,chessx,chessy);
		chessIndex++;
		
//		System.out.println("輸贏:"+WinChess.win(chessNumArr, chessx, chessy));
		if(WinChess.win(chessNumArr, chessx, chessy)==true) {
			if(chessNumArr[chessx][chessy]==1) {
				System.out.println("黑棋勝!");
				wzqjf.endUI1();
			}else {
				System.out.println("白棋勝!");
				wzqjf.endUI1();
			}
			
		}
		//顯示黑白棋數量
		chesson(countblack,countwhite);
	}
	
	public void chesson(int countblack,int countwhite) {
		Font font=new Font("宋體",Font.BOLD,25);
		Color color=new Color(255,255,255,255);
		g.setColor(color.gray);
		g.fillRect(900, 70, 200, 150);
		g.setColor(color.orange);
		g.setFont(font);
		g.drawString("黑棋:"+countblack, 960, 130);
		g.drawString("白棋:"+countwhite, 960, 170);
		
		g.setColor(color.gray);
		g.fillRect(900, 220, 200, 150);
		g.setColor(color.orange);
		g.setFont(font);
		g.drawString("下回合", 960, 280);
		if(countblack==countwhite) {
			g.setColor(color.orange);
			g.setFont(font);
			g.drawString("白棋", 960, 320);
			
		}else if(countblack<countwhite) {
			g.setColor(color.orange);
			g.setFont(font);
			g.drawString("黑棋", 960, 320);
		}
		
	}


	@Override
	public void mouseReleased(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}
	

}
	

效果圖

在這里插入圖片描述
登錄失敗
在這里插入圖片描述

在這里插入圖片描述
勝利界面

程式還需優化改進之處

  • 存檔讀檔之后悔棋不可以正常運行需要完善
  • 界面按鈕美化
  • 加入注冊界面
  • 設定賬號密碼庫以及對應的用戶
  • 加入人機對戰
  • 加入錄制回放功能
  • 加入聯網功能讓實作pvp

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/294054.html

標籤:其他

上一篇:關于打包pygame遇到的相關問題

下一篇:C實作三子棋及bug解決方法

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more