java五子棋人机代码_Java五子棋AI实现代码
思路:
①五子棋界面的实现
②交互下棋的实现
③重绘
④AI,实现人机对战
五子棋和简单AI的实现:
首先将五子棋的界面写出来。
首先我们写一个接口类,定义好棋盘的数据(目的是方便修改)。
public interface Config {
public static final int X0=50;//左上角起点X值
public static final int Y0=50;//左上角起点Y值
public static final int ROWS=15;//横向线数
public static final int COLUMNS=15;//纵向线数
public static final int CHESSSIZE=40;//棋子直径
public static final int SIZE=50;//单元格大小
}
再来写五子棋的界面。写界面的方法和画图板是一样的。
public class FiveChessUI extends JFrame implements Config {
static FiveChessUI fcUI = new FiveChessUI();
public static void main(String[] args){
fcUI.initUI();
}
private int [][] chesses = new int[ROWS][COLUMNS];//创建一个二维数组用来标记棋盘上的位置
/**
* 初始化五子棋窗体的方法
*/
public void initUI(){
ChessListener listener = new ChessListener(chesses,fcUI);
this.setTitle("五子棋v1.0");
this.setSize(900, 800);//设置界面尺寸
this.setResizable(false);//界面不可改变大小
this.setLocationRelativeTo(null);//设置界面居中
this.setDefaultCloseOperation(3);//设置退出进程
BorderLayout bl = new BorderLayout();//设置界面布局为窗体式布局
this.setLayout(bl);
JPanel jp = new JPanel();
jp.setPreferredSize(new Dimension(100,0));
this.add(jp,BorderLayout.EAST);
String [] name ={"重新开始","黑棋先下","白棋先下","悔棋","人机对战","人人对战"};
for(int i=0;i
JButton jbu = new JButton(name[i]);
jbu.setPreferredSize(new Dimension(95,30));
jp.add(jbu);
jbu.addActionListener(listener);
}
this.setVisible(true);//设置可见
listener.gr = this.getGraphics();
this.addMouseListener(listener);//给界面加上鼠标监听
}
/**
* 重写绘制窗体的方法
*/
public void paint(Graphics g){
super.paint(g);
//在重绘的同时绘制棋盘
drawChessTable(g);
//在重绘的同时绘制棋子
drawChess(g);
}
public void drawChess(Graphics g){
ImageIcon bai = new ImageIcon("C:\\Users\\Administrator\\Pictures\\五子棋\\baizi.png");//添加白子图片
ImageIcon hei = new ImageIcon("C:\\Users\\Administrator\\Pictures\\五子棋\\heizi.png");//添加黑子图片
for(int i=0;i
for(int j=0;j
if(chesses[i][j]==1){
g.drawImage(hei.getImage(), X0 + SIZE * i - Config.CHESSSIZE / 2, Y0 + SIZE * j - Config.CHESSSIZE / 2, Config.CHESSSIZE,
Config.CHESSSIZE, null);
}else if(chesses[i][j]==-1){
g.drawImage(bai.getImage(), X0 + SIZE * i - Config.CHESSSIZE / 2, Y0 + SIZE * j - Config.CHESSSIZE / 2, Config.CHESSSIZE,
Config.CHESSSIZE, null);
}
}
}
}
public void drawChessTable(Graphics g){
//添加背景图片
ImageIcon img= new ImageIcon("C:\\Users\\Administrator\\Pictures\\chesstable.jpg");
g.drawImage(img.getImage(), 0, 0, 800, 800,null);
//画棋盘横线
for(int i=0;i
g.drawLine(X0, Y0+i*SIZE, X0+(COLUMNS-1)*SIZE, Y0+i*SIZE);
}
//画棋盘竖线
for(int j=0;j
g.drawLine(X0+j*SIZE, Y0, X0+j*SIZE,Y0+(ROWS-1)*SIZE );
}
}
}
监听器类代码如下:
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.HashMap;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
public class ChessListener extends MouseAdapter implements Config, ActionListener {
public Graphics gr;
private int count = 0;// 计数器
private int[][] chesses;// 创建一个二维数组用来存放棋子的坐标
private String name;
private int t, r;
private int cl = 0, AI=2;
private int i, j, x, y, z = 0, w = 0,zz=0,ww=0;
private FiveChessUI fc;// 声明FiveChessUI类的一个对象
private int setX[] = new int[ROWS * COLUMNS];// 创建一维数组setX[]
private int setY[] = new int[ROWS * COLUMNS];// 创建一维数组setY[]
private int[][] chessValue = new int[ROWS][COLUMNS];
private int index = 0;// 创建数组的下标
HashMap hm = new HashMap();//创建权值表
public ChessListener(int[][] chesses, FiveChessUI fc) {
this.fc = fc;
this.chesses = chesses;
//权值设置,这个需要自己慢慢调,小编写的一般,AI有时会出问题
hm.put("1", 20);
hm.put("11", 60);
hm.put("111", 200);
hm.put("1111", 1000);
hm.put("-1", 20);
hm.put("-1-1", 60);
hm.put("-1-1-1", 200);
hm.put("-1-1-1-1", 1000);
hm.put("1-1", 20);
hm.put("11-1", 30);
hm.put("111-1", 80);
hm.put("1111-1", 1000);
hm.put("-11", 20);
hm.put("-111", 30);
hm.put("-1111", 80);
hm.put("-11111", 1000);
hm.put("1-1", 20);
hm.put("-1-11", 30);
hm.put("-1-1-11", 80);
hm.put("-1-1-1-11", 1000);
hm.put("1-1", 20);
hm.put("1-1-1", 30);
hm.put("1-1-1-1", 80);
hm.put("1-1-1-1-1", 1000);
}
public void mouseReleased(MouseEvent e) {
// 得到鼠标事件发生的时候光标的位置
int x1 = e.getX();
int y1 = e.getY();
// 按行遍历棋盘,坐标(i,j)
for (j = 0; j < ROWS; j++) {
for (i = 0; i < ROWS; i++) {// 得到交叉点的坐标
x = X0 + SIZE * i;// 横坐标
y = Y0 + SIZE * j;// 纵坐标
// 与圆心的误差为size/3
if (x1 > x - SIZE * 5 / 12 && x1 < x + SIZE * 5 / 12 && y1 > y - SIZE * 5 / 12
&& y1 < y + SIZE * 5 / 12) {
ImageIcon bai = new ImageIcon("C:\\Users\\Administrator\\Pictures\\baizi5.png");
ImageIcon hei = new ImageIcon("C:\\Users\\Administrator\\Pictures\\heizi4.png");
if (AI == 0) { // 人人对战
if (chesses[i][j] == 0) {// 如果选的位置没有棋子
if (count == 0) {
chesses[i][j] = 1;// 如果是黑子,就为1
count++;
gr.drawImage(hei.getImage(), X0 + SIZE * i - CHESSSIZE / 2,
Y0 + SIZE * j - CHESSSIZE / 2, CHESSSIZE, CHESSSIZE, null);
cl = 0;
} else {
chesses[i][j] = -1;// 如果是白子就为-1
count--;
gr.drawImage(bai.getImage(), X0 + SIZE * i - CHESSSIZE / 2,
Y0 + SIZE * j - CHESSSIZE / 2, CHESSSIZE, CHESSSIZE, null);
cl = 1;
}
setX[index] = i;// 将下的棋子的横坐标存入setX[]
setY[index] = j;// 将下的棋子的纵坐标存入setY[]
index++;// 存入一个坐标,一维数组角标加1
// 以交叉点画圆
checkRow(i, j);
z = 1;
w = 1;
return;
}
}
if (AI == 1) { // 人机对战
if (chesses[i][j] == 0) {// 如果选的位置没有棋子
if (count == 0) {
// 玩家下棋
chesses[i][j] = 1;// 如果是黑子,就为1
// count++;
gr.drawImage(hei.getImage(), X0 + SIZE * i - CHESSSIZE / 2,
Y0 + SIZE * j - CHESSSIZE / 2, CHESSSIZE, CHESSSIZE, null);
cl = 0;
count++;
checkRow(i, j);//判断是否胜利
setX[index] = i;// 将下的棋子的横坐标存入setX[]
setY[index] = j;// 将下的棋子的纵坐标存入setY[]
index++;// 存入一个坐标,一维数组角标加1
}
this.AI();
if (count == 1) {
// 输出所有点的权值
for (int j = 0; j < chessValue.length; j++) {
for (int i = 0; i < chessValue.length; i++) {
System.out.print(chessValue[i][j] + " ");
}
System.out.println();
}
// 电脑下棋
// 筛选出chessValue最大值的交点坐标, 该坐标电脑下棋
for (int j = 0; j < chessValue.length; j++) {
for (int i = 0; i < chessValue.length; i++) {
if (chessValue[0][0] < chessValue[i][j]) {
chessValue[0][0] = chessValue[i][j];
t = i;
r = j;
}
}
}
count--;
chesses[t][r] = -1;
gr.drawImage(bai.getImage(), X0 + SIZE * t - CHESSSIZE / 2,
Y0 + SIZE * r - CHESSSIZE / 2, CHESSSIZE, CHESSSIZE, null);
cl = 1;
setX[index] = r;// 将下的棋子的横坐标存入setX[]
setY[index] = t;// 将下的棋子的纵坐标存入setY[]
index++;// 存入一个坐标,一维数组角标加1
checkRow(t, r);//判断是否胜利
zz = 1;//
ww = 1;
// 清空value
for (int i = 0; i < chessValue.length; i++) {
for (int j = 0; j < chessValue.length; j++) {
chessValue[i][j] = 0;
}
}
}
}
}
}
}
}
}
// 判断胜利的条件
public int checkRow(int x, int y) {
int count1 = 0, count2 = 0, count3 = 0, count4 = 0;// 定义4个棋子计数器,分别计数水平,竖直、斜向右下、斜向左下
for (int i = x + 1; i < chesses.length; i++) {
if (chesses[i][y] == chesses[x][y]) {
count1++;
} else
break;
}
for (int i = x; i >= 0; i--) {
if (chesses[i][y] == chesses[x][y]) {
count1++;
} else
break;
}
for (int j = y + 1; j < chesses.length; j++) {
if (chesses[x][j] == chesses[x][y]) {
count2++;
} else
break;
}
for (int j = y; j >= 0; j--) {
if (chesses[x][y] == chesses[x][j]) {
count2++;
} else
break;
}
for (int i = x + 1, j = y + 1; i < chesses.length && j < chesses.length; i++, j++) {
if (chesses[i][j] == chesses[x][y]) {
count3++;
} else
break;
}
for (int i = x, j = y; i >= 0 && j >= 0; i--, j--) {
if (chesses[i][j] == chesses[x][y]) {
count3++;
} else
break;
}
for (int i = x, j = y; i < chesses.length && j >= 0; i++, j--) {
if (chesses[i][j] == chesses[x][y]) {
count4++;
} else
break;
}
for (int i = x - 1, j = y + 1; i >= 0 && j < chesses.length; i--, j++) {
if (chesses[i][j] == chesses[x][y]) {
count4++;
} else
break;
}
if (count1 >= 5 || count2 >= 5 || count3 >= 5 || count4 >= 5) {
count = 0;
if (cl == 0) {
JOptionPane.showMessageDialog(null, "黑棋赢!");
for (int i = 0; i < chesses.length; i++) {
for (int j = 0; j < chesses.length; j++) {
chesses[i][j] = 0;
}
}
fc.repaint();
}
if (cl == 1) {
JOptionPane.showMessageDialog(null, "白棋赢!");
for (int i = 0; i < chesses.length; i++) {
for (int j = 0; j < chesses.length; j++) {
chesses[i][j] = 0;
}
}
fc.repaint();
}
}
return count;
}
public void actionPerformed(ActionEvent e) {
name = e.getActionCommand();
if ("重新开始".equals(name)) {
count = 0;
z = 0;
w = 0;
for (int i = 0; i < chesses.length; i++) {
for (int j = 0; j < chesses.length; j++) {
chesses[i][j] = 0;
}
}
fc.repaint();
}
if ("白棋先下".equals(name)) {
if (z == 0) {
count = 1;
z = 1;
}
}
if ("黑棋先下".equals(name)) {
if (w == 0) {
count = 0;
w = 1;
}
}
if ("悔棋".equals(name)) {
this.huiqi();
}
if ("人机对战".equals(name)) {
if(w==0){
AI = 1;
ww=1;
}
}
if ("人人对战".equals(name)) {
if(z==0){
AI = 0;
}
}
}
public void huiqi() {
if (index >= 0) {
index--;
if (index < 0) {
index = 0;
}
x = setX[index];
y = setY[index];
if (chesses[x][y] == 1) {
chesses[x][y] = 0;
count = 0;
}
if (chesses[x][y] == -1) {
chesses[x][y] = 0;
count = 1;
}
if(chesses[t][r]==-1){
chesses[t][r]=0;
count=1;
}
fc.repaint();
}
}
public void AI() {
for (int i = 0; i < chesses.length; i++) {
for (int j = 0; j < chesses.length; j++) {
if (chesses[i][j] == 0) {// 判断当前位置是否有棋子
// 定义两个变量分别保存棋局,颜色
String code = "";
int color = 0;
// 向右
for (int k = i + 1; k < chesses.length; k++) {
if (chesses[k][j] == 0) {
break;
} else {
if (color == 0) {// 右边第一颗棋子
color = chesses[k][j];// 保存颜色
code += chesses[k][j];// 保存棋局
} else if (chesses[k][j] == color) {// 右边第二,第三同颜色棋子
code += chesses[k][j];// 保存棋局
} else { // 右边不同颜色
code += chesses[k][j];
break;
}
}
}
// 根据code取出hm对应的权值
Integer value = hm.get(code);
if (value != null) {
chessValue[i][j] += value;
}
// 向左方向
code = "";
color = 0;
for (int k = i - 1; k >= 0; k--) {
if (chesses[k][j] == 0) {
break;
} else {
if (color == 0) {// 右边第一颗棋子
color = chesses[k][j];// 保存颜色
code += chesses[k][j];// 保存棋局
} else if (chesses[k][j] == color) {// 右边第二,第三同颜色棋子
code += chesses[k][j];// 保存棋局
} else { // 右边不同颜色
code += chesses[k][j];
break;
}
}
}
// 根据code取出hm对应的权值
Integer value2 = hm.get(code);
if (value2 != null) {
chessValue[i][j] += value2;
}
// 向上方向
code = "";
color = 0;
for (int k = j - 1; k >= 0; k--) {
if (chesses[i][k] == 0) {
break;
} else {
if (color == 0) {// 右边第一颗棋子
color = chesses[i][k];// 保存颜色
code += chesses[i][k];// 保存棋局
} else if (chesses[i][k] == color) {// 右边第二,第三同颜色棋子
code += chesses[i][k];// 保存棋局
} else { // 右边不同颜色
code += chesses[i][k];
break;
}
}
}
// 根据code取出hm对应的权值
Integer value3 = hm.get(code);
if (value3 != null) {
chessValue[i][j] += value3;
}
// 向下方向
code = "";
color = 0;
for (int k = j + 1; k < chesses.length; k++) {
if (chesses[i][k] == 0) {
break;
} else {
if (color == 0) {// 右边第一颗棋子
color = chesses[i][k];// 保存颜色
code += chesses[i][k];// 保存棋局
} else if (chesses[i][k] == color) {// 右边第二,第三同颜色棋子
code += chesses[i][k];// 保存棋局
} else { // 右边不同颜色
code += chesses[i][k];
break;
}
}
}
// 根据code取出hm对应的权值
Integer value4 = hm.get(code);
if (value4 != null) {
chessValue[i][j] += value4;
}
// 右上方向
code = "";
color = 0;
for (int k = j + 1, l = i - 1; l >= 0 && k < chesses.length; l--, k++) {
if (chesses[l][k] == 0) {
break;
} else {
if (color == 0) {// 右边第一颗棋子
color = chesses[l][k];// 保存颜色
code += chesses[l][k];// 保存棋局
} else if (chesses[l][k] == color) {// 右边第二,第三同颜色棋子
code += chesses[l][k];// 保存棋局
} else { // 右边不同颜色
code += chesses[l][k];
break;
}
}
}
// 根据code取出hm对应的权值
Integer value6 = hm.get(code);
if (value6 != null) {
chessValue[i][j] += value6;
}
// 左下方向
code = "";
color = 0;
for (int k = i + 1, l = j - 1; l >= 0 && k < chesses.length; k++, l--) {
if (chesses[k][l] == 0) {
break;
} else {
if (color == 0) {// 右边第一颗棋子
color = chesses[k][l];// 保存颜色
code += chesses[k][l];// 保存棋局
} else if (chesses[k][l] == color) {// 右边第二,第三同颜色棋子
code += chesses[k][l];// 保存棋局
} else { // 右边不同颜色
code += chesses[k][l];
break;
}
}
}
// 根据code取出hm对应的权值
Integer value7 = hm.get(code);
if (value7 != null) {
chessValue[i][j] += value7;
}
// 右下方向
code = "";
color = 0;
for (int k = i - 1, l = j - 1; l >= 0 && k >= 0; l--, k--) {
if (chesses[k][l] == 0) {
break;
} else {
if (color == 0) {// 右边第一颗棋子
color = chesses[k][l];// 保存颜色
code += chesses[k][l];// 保存棋局
} else if (chesses[k][l] == color) {// 右边第二,第三同颜色棋子
code += chesses[k][l];// 保存棋局
} else { // 右边不同颜色
code += chesses[k][l];
break;
}
}
}
// 根据code取出hm对应的权值
Integer value8 = hm.get(code);
if (value8 != null) {
chessValue[i][j] += value8;
}
// 左上方向
code = "";
color = 0;
for (int k = i + 1, l = j + 1; k < chesses.length && l < chesses.length; l++, k++) {
if (chesses[k][l] == 0) {
break;
} else {
if (color == 0) {// 右边第一颗棋子
color = chesses[k][l];// 保存颜色
code += chesses[k][l];// 保存棋局
} else if (chesses[k][l] == color) {// 右边第二,第三同颜色棋子
code += chesses[k][l];// 保存棋局
} else { // 右边不同颜色
code += chesses[k][l];
break;
}
}
}
// 根据code取出hm对应的权值
Integer value5 = hm.get(code);
if (value5 != null) {
chessValue[i][j] += value5;
}
}
}
}
}
}
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。如果你想了解更多相关内容请查看下面相关链接
java五子棋人机代码_Java五子棋AI实现代码相关推荐
- java swing人机对战五子棋(含背景音乐)
一.项目简介 本项目是一套基于java swing的人机对战五子棋系统,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者. 包含:项目源码.数据库脚本等,该项目附带全部源码可 ...
- java中人机猜拳_Java实现人机猜拳游戏
本文实例为大家分享了Java实现人机猜拳游戏的具体代码,供大家参考,具体内容如下 实现: User类 public class User { private String name; private ...
- java 生产者消费者代码_Java生产者和消费者代码
java 生产者消费者代码 This also helps us to understand the concept of synchronised multi-threading in java, ...
- java gui构造工具_Java Web框架 静态代码块、构造代码块、构造函数、普通代码块 执行顺序 Decompiler JD-GUI 反编译工具...
1.下载jd-gui-windows-1.4.0. http://jd.benow.ca/ 2.通过jd-gui.exe查看.class文件,用于分析类编译过程. 3.源文件. // 加载相应的 He ...
- java 连珠五子棋.现代职业_java 五子棋游戏
五子棋游戏 一,1.五子棋的基本常识 与任何一种竞技棋一样,五子棋的每一局棋也分为三个阶段:开局,中局和残局. 五子棋的开始阶段称为开局,或称布局.其开局阶段是十分短暂的,大约在七着与十几着之间.在这 ...
- java五子棋的报告_Java五子棋实现报告
用java 写的五子棋报告.... 一.实验目的 (1) 使用Java编写五子棋程序 (2) 掌握编写过程的一些类和类成员的使用,并且了解五子棋制作过 程的一些步骤和了解一些算法. 二.实验环境 在电 ...
- java全面的计算器代码_Java实现计算器的代码
用java 实现的计算器,原理看代码注释,具体内容如下 public class mycalculator { public static void main(string[] args) { str ...
- java 实现自旋锁_java自旋锁的代码实现
自旋锁:spinlock 是指尝试获取锁的线程不会立即阻塞,而是采用循环的方式获取锁,这样的好处是减少线程上下文切换的消耗,缺点是循环好用CPU 代码: import java.util.concur ...
- java调c++代码_Java中调用C++代码的实现 | 学步园
JNI为 Java Native Interface 即Java本地接口,使用此种方式可以对C/C++代码进行调用,其在本质上是对C/C++生成的动态库进行调用而不是直接对C/C++代码进行调用 J ...
- java构造函数重载继承_Java基础-继承 - 写代码换盆的个人空间 - OSCHINA - 中文开源技术交流社区...
访问权限 Java 中有三个访问权限修饰符:private.protected 以及 public,如果不加访问修饰符,表示包级可见. 可以对类或类中的成员(字段和方法)加上访问修饰符. 类可见表示其 ...
最新文章
- mysql一个死锁分析
- putty/xshell/Secure CRT远程工具详解
- springcloud(四):熔断器Hystrix
- vs2008 添加头文件路径
- 软件构造学习笔记-第九周、第十周
- 操作系统大作业模拟实现命令解释器_06 初识shell之系统命令基础
- 现在90后程序员有必要考证吗?
- iOS 热敏打印机打印位图
- 老师让小宁同学查看一个网页的源代码,但小宁同学发现鼠标右键好像不管用了
- Leetcode刷题 2021.02.15
- Asset Pricing:Asset Pricing Formula
- 历时一个月整理2021金三银四Java面试题汇总,足足127页!
- mysql 汉字转成拼音
- 京东购物车(html+css+js)
- 两台计算机都使用远程桌面,远程桌面设置及使用
- C语言之#error/#warning
- c语言组建怎样变成编译,c语言编译【处理流程】
- scrapy框架连接MongoDB数据库
- VB.NET实现DirectSound9 (8) 音效控制器
- python3.6打包成exe文件_详解如何将python3.6软件的py文件打包成exe程序