java五子棋(AI)

硅谷探秘者 2091 0 0

java实现五子棋人机对战

menu.saveimg.savepath20190320192020.jpg

package fir;
import java.awt.*;  
import javax.swing.JPanel;  
/** 
 * 有背景图片的Panel类 
 * @author tntxia 
 */  
public class BackgroundPanel extends JPanel {  
    private static final long serialVersionUID = -6352788025440244338L;  
    private Image image = null;  
    public BackgroundPanel(Image image) {  
        this.image = image;  
    }  
    // 固定背景图片,允许这个JPanel可以在图片上添加其他组件  
    protected void paintComponent(Graphics g) {  
        g.drawImage(image, 0, 0, this.getWidth(), this.getHeight(), this);  
    }  
}
package fir;
/**
 * 初始化
 * @author Administrator
 */
public class Ready {
	private int x;
	private int y;
	private int count;
	
	public int getCount(){
		return this.count;
	}
	/**
	 * 计算所有赢法种类
	 * @return
	 */
	public Ready(int x,int y){
		this.x=x;
		this.y=y;
		count=initCount();
	}
	private int initCount(){
		int count=0;
		for (int i = 0; i < x; i++) {
			for (int j = 0; j < y-4; j++) {
				count++;
			}
		}
		// 横线上
		for (int i = 0; i < x; i++) {
			for (int j = 0; j < y-4; j++) {
				count++;
			}
		}
		// 斜线上
		for (int i = 0; i < x-4; i++) {
			for (int j = 0; j < y-4; j++) {
				count++;
			}
		}
		// 反斜线上
		for (int i = 0; i < x-4; i++) {
			for (int j = y-1; j > 3; j--) {
				count++;
			}
		}
		return count;
	}
	/**
	 * 初始化所有赢法
	 * @param c
	 * @return
	 */
	public boolean[][][] initChess(){
		boolean wins[][][]=new boolean[15][15][this.count];
		int count=0;
		for (int i = 0; i < x; i++) {
			for (int j = 0; j < y-4; j++) {
				for (int k = 0; k < 5; k++) {
					wins[i][j + k][count] = true;
				}
				count++;
			}
		}
		for (int i = 0; i < x; i++) {
			for (int j = 0; j < y-4; j++) {
				for (int k = 0; k < 5; k++) {
					wins[j + k][i][count] = true;
				}
				count++;
			}
		}
		for (int i = 0; i < x-4; i++) {
			for (int j = 0; j < y-4; j++) {
				for (int k = 0; k < 5; k++) {
					wins[i + k][j + k][count] = true;
				}
				count++;
			}
		}
		for (int i = 0; i < x-4; i++) {
			for (int j = y-1; j > 3; j--) {
				for (int k = 0; k < 5; k++) {
					wins[i + k][j - k][count] = true;//记录赢得可能性
				}
				count++;
			}
		}
		return wins;
	}
	
	public int[] getMyWin(){
		int []myWin=new int[count];
		return myWin;
	}
	
	public int[] getConputerWin(){
		int []conputer=new int[count];
		return conputer;
	}
	/**
	 * 初始化棋盘
	 * @return
	 */
	public int[][] getChessBorad(){
		int [][]chessBorad=new int[x][y];
		return chessBorad;
	}
}
package fir;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Image;
import java.awt.Toolkit;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.ActionEvent;
import javax.swing.border.BevelBorder;
import javax.swing.JLabel;
import java.awt.Color;
/**
 * 五子棋
 * @author Administrator
 * 
 * 棋子的大小为46像素(宽/高)
 * 棋盘的大小为690像素(宽/高)
 * 有效棋子总量(14*14)
 */
public class Fir extends JFrame {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private JPanel contentPane;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Fir frame = new Fir();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	
	public static int s=0;
	
	public static boolean wins[][][];//五子棋的所有赢法,前两维代表棋盘,第三位代表所有赢法,每一个棋子都可以有多种赢法。
	public static int[] myWin;//我方第i中赢法中,有n颗棋子,如果有5颗棋子代表已经赢了,例如:myWin[5]=2;代表第5中赢法中,已经有2颗棋子,
	public static int[] computerWin;//计算机方第i中赢法中,有n颗棋子
	public static int[][] chessBorad;//代表棋盘,值0代表没有下棋子,其他值代表已经下棋子了。
	
	public Ready re=new Ready(15,15);//初始化数据
	
	public boolean me=true;//true代表应该我方下棋
	public boolean over=false;//游戏是否结束
	
	JPanel panel=null;
	public Fir() {//初始化界面
		wins=re.initChess();
		myWin=re.getMyWin();
		computerWin=re.getConputerWin();
		chessBorad=re.getChessBorad();
		
		setTitle("fir");
		
		Toolkit kit = Toolkit.getDefaultToolkit(); // 定义工具包 
		Dimension screenSize = kit.getScreenSize(); // 获取屏幕的尺寸 
		int screenWidth = screenSize.width; // 获取屏幕的宽
		int screenHeight = screenSize.height; // 获取屏幕的高
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds((screenWidth-700)/2, (screenHeight-780)/2, 715, 770);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);
		
		this.setResizable(false);
		
		Image image=new ImageIcon("image/background.jpg").getImage();
		panel = new BackgroundPanel(image);//初始化背景面板
		panel.setForeground(Color.BLACK);
		panel.setBorder(new BevelBorder(BevelBorder.LOWERED, null, null, null, null));
		panel.setBounds(10, 10, 690, 690);
		contentPane.add(panel);
		panel.setLayout(null);
		
		JButton btnBegin = new JButton("begin");
		btnBegin.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
			}
		});
		btnBegin.setBounds(10, 710, 93, 23);
		contentPane.add(btnBegin);
		
		JButton btnRestart = new JButton("restart");
		btnRestart.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
			}
		});
		btnRestart.setBounds(113, 710, 93, 23);
		contentPane.add(btnRestart);
		
		JButton btnClose = new JButton("close");//退出
		btnClose.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
		});
		btnClose.setBounds(216, 710, 93, 23);
		contentPane.add(btnClose);
		
		/**
		 * 鼠标点击事件
		 */
		panel.addMouseListener(new MouseListener() {
			public void mouseReleased(MouseEvent e) { }//鼠标抬起			
			public void mousePressed(MouseEvent e) { }//鼠标按下			
			public void mouseExited(MouseEvent e) { }//鼠标离开		
			public void mouseEntered(MouseEvent e) { }//鼠标进入		
			public void mouseClicked(MouseEvent e) {//鼠标点击
				if(!me||over){//如果不该我方下棋或已结束,则返回
					return;
				}
				/**
				 * 计算点击时棋盘位置,坐标位置
				 */
				int i=e.getX();//棋盘位置(像素)
				int j=e.getY();//棋盘位置(像素)
				
				int px=i%46;//通过鼠标点击的位置计算棋子应该下的位置
				int py=j%46;//通过鼠标点击的位置计算棋子应该下的位置
				i=i-(px)+(px<=23?-23:23);//通过鼠标点击的位置计算棋子应该下的位置
				j=j-(py)+(py<=23?-23:23);//通过鼠标点击的位置计算棋子应该下的位置
				
				int x=(i+23)/46;//坐标位置(数组)
				int y=(j+23)/46;//坐标位置(数组)
				if(x==0||y==0||x>=15||y>=15){//规则:第一行,第一列不能下棋。
					return ;
				}
				myStep(i,j,x,y);//我方下棋,
			}
		});
	}
	/**
	 * 我下棋
	 * @param i
	 * @param j
	 * @param x
	 * @param y
	 */
	public void myStep(int i,int j,int x,int y){
		if (chessBorad[x][y] == 0) {
			play(i,j);
			chessBorad[x][y] = 1;
			for (int k = 0; k < re.getCount(); k++) {
				if (wins[x][y][k]) {
					myWin[k]++;
					computerWin[k] = 999;
					if (myWin[k] == 5) {
						System.out.println("my win");
						over=true;
						return;
					}
				}
			}
		}
		me=!me;
		computerStep();
	}
	/**
	 * 计算机下棋
	 */
	public void computerStep(){
		if(over){//游戏结束
			return;
		}
		int myScore[][] = new int[15][15];//评估我方评分
		int computerScore[][] = new int[15][15];//评估计算机评分
		int max = 0;
		int x = 0;
		int y = 0;
		// 遍历棋盘
		for (int i = 1; i < 15; i++) {//x轴
			for (int j = 1; j < 15; j++) {//y轴
				if (chessBorad[i][j] == 0) {// 当前可落子,如果不等于0代表已经有棋子
					for (int k = 0; k < re.getCount(); k++) { // 每个点都在 多种赢法中,所以要遍历所有赢法
						if (wins[i][j][k]) {// 计算他在K赢法中的 重要性
							switch (myWin[k]) {//我方棋路,当前赢法中已经连上了几颗棋子
								case 1:
									myScore[i][j] += 200;
									break;
								case 2:
									myScore[i][j] += 400;
									break;
								case 3:
									myScore[i][j] += 2000;
									break;
								case 4:
									myScore[i][j] += 10000;
									break;
							}
							switch (computerWin[k]) {//计算机棋路,当前赢法中已经连上了几颗棋子
								case 1:
									computerScore[i][j] += 300;
									break;
								case 2:
									computerScore[i][j] += 500;
									break;
								case 3:
									computerScore[i][j] += 3000;
									break;
								case 4:
									computerScore[i][j] += 20000;
									break;
							}
						}
					}
					// 玩家最重要的落点
					if (myScore[i][j] > max) {
						max = myScore[i][j];
						x = i;
						y = j;
					} else if (myScore[i][j] == max) {
						if (computerScore[i][j] > computerScore[x][y]) { // 
							x = i;
							y = j;
						}
					}
					// AI最重要的落点
					if (computerScore[i][j] > max) {
						max = computerScore[i][j];
						x = i;
						y = j;
					} else if (computerScore[i][j] == max) {
						if (myScore[i][j] > myScore[x][y]) {
							x = i;
							y = j;
						}
					}
				}
			}
		}
		play(x*46-23,y*46-23);//下棋
		chessBorad[x][y] = 2;//棋盘标记已下棋
		for (int k = 0; k < re.getCount(); k++) {//遍历所有的赢法
			if (wins[x][y][k]) {//如果(x,y)这个点在某一种赢法中
				computerWin[k]++; 	//那么该种赢法中有多了一个棋子
				myWin[k] = 999; 	//那么我方的这种赢法就不可能赢了,设一个异常的值
				if (computerWin[k] == 5) { //如果计算机在某种赢法上连上了五个子,那么计算机就赢了,我方就输了
					System.err.println("lose");
					over = true; //结束游戏
					return;
				}
			}
		}
		if (!over) {//如果没有结束游戏
			me = !me;//换我方下棋
		}
	}
	/***
	 * 把棋子放入棋盘
	 * @param x
	 * @param y
	 */
	public void play(int x,int y){
		Icon icon;
		if(s%2==0){
			icon=new ImageIcon("image/black.png");//黑棋
		}else{
			icon=new ImageIcon("image/white.png");//白旗
		}
		s++;
		JLabel lblNewLabel = new JLabel(icon);
		lblNewLabel.setBounds(x,y, 46, 46);
		panel.add(lblNewLabel);
		panel.repaint();
	}
}



评论区
请写下您的评论...
暂无评论...
猜你喜欢
weblog 2121 exe文件:http://photo.jiajiajia.club/file/wuziqi.exe 扫雷exe文件:http://photo.jiajiajia.club/file
五子棋 游戏 算法 数据结构 c 1089 下篇分享c#源码~
c# 游戏 数据结构 算法 五子棋 1635 部分代码voidwinJudge(intx,inty){//下之前记住改变的状态States;//s=newState();if(states.count=6){s
java基础 2755 java静态代理示例packageclub.jiajiajia.test.staticproxy;publicinterfaceBuyHouse{voidbuyHosue();//买房
official 816 线程的种基本状态:初始化、可运行、运行、阻塞、终止阻塞状态分为:等待阻塞、同步阻塞、其他阻塞三种方式等待阻塞:调用某锁对象的wait方法可使当前线程进入等待阻塞状态,并且该线程放弃所有资源(包括
其他 9314 在一本书上看到过类可以重载父类的方法,关于这一点有点疑惑,个人重载是发生在同一个类中。网上关于这个也存在争议。先暂时作为一个问题记录在此下面这张图片引用自《疯狂java讲义第三版》关于重写,遵循以
数据结构与算法 5251 十种排序算法理解(前)1.冒泡排序冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。算法描述:比较相邻的元素。如果第一个比第二个大,就
百度api 999 百度文档:https://ai.baidu.com/ai-doc/OCR/Sk3h7xyadimportjava.io.BufferedInputStream
归档
2018-11  12 2018-12  33 2019-01  28 2019-02  28 2019-03  32 2019-04  27 2019-05  33 2019-06  6 2019-07  12 2019-08  12 2019-09  21 2019-10  8 2019-11  15 2019-12  25 2020-01  9 2020-02  5 2020-03  16 2020-04  4 2020-06  1 2020-07  7 2020-08  13 2020-09  9 2020-10  5 2020-12  3 2021-01  1 2021-02  5 2021-03  7 2021-04  4 2021-05  4 2021-06  1 2021-07  7 2021-08  2 2021-09  8 2021-10  9 2021-11  16 2021-12  14 2022-01  7 2022-05  1 2022-08  3 2022-09  2 2022-10  2 2022-12  5 2023-01  3 2023-02  1 2023-03  4 2023-04  2 2023-06  3 2023-07  4 2023-08  1 2023-10  1 2024-02  1 2024-03  1 2024-04  1
标签
算法基础 linux 前端 c++ 数据结构 框架 数据库 计算机基础 储备知识 java基础 ASM 其他 深入理解java虚拟机 nginx git 消息中间件 搜索 maven redis docker dubbo vue 导入导出 软件使用 idea插件 协议 无聊的知识 jenkins springboot mqtt协议 keepalived minio mysql ensp 网络基础 xxl-job rabbitmq haproxy srs 音视频 webrtc javascript
目录
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。