智能五子棋
好久没有写技术博客啦,先附图一张以表喜悦😎
目录:
- 简单五子棋的实现
- AI五子棋
- 技术总结
前言:
回到了长沙,又回归了阴雨天的怀抱。就是想抱怨一下长沙为啥要一直下雨呢!!!就没有几天是晴天。本来还想晚上去南校操场跑跑步,然而设想很美好,现实很苦楚。看着身边强者如云,学习编程语言稍微有一丢丢起色的我打算开始备战面试,而AI五子棋正好作为我半年未打代码的练手项目。希望我的博客可以帮助到正在学习Java的编程小白,希望各位小哥哥,小姐姐可以给我写的博客点个赞( •̀ ω •́ )✧, 你们的赞就是我写博客的无穷动力 !!!
1.简单五子棋的实现(自下)
在编写代码之前我们要理解实现五子棋的简单步骤:
- 画出棋盘
- 点击棋盘会在棋盘下一个子
- 再次点击(白字和黑子交替下)
- 判断是否连接成五子,得出输赢
技术点:
- 下子需要鼠标监听器,获取鼠标点击位置并定位到网格上
- 判断输赢需要检测当前该子上下左右斜边是否连成五子(核心算法)
- 为了避免下子闪屏和界面刷新,需要提供双缓冲和重绘机制
废话不多的说,先上代码:
//代码基本都给了注释ヾ(•ω•`)o
//初始化下棋界面
public void paint(Graphics g){
//搭载双缓冲技术
BufferedImage bufferedImage=new BufferedImage(jf.getWidth(),jf.getHeight(),BufferedImage.TYPE_INT_BGR);
Graphics g1=bufferedImage.createGraphics();//创建双缓冲画笔
g1.setColor(Color.BLACK);
g1.setFont(new Font("黑体", Font.BOLD, 50));
//画背景
g1.drawImage(imageBackGround, 0, 0, 1050, 1020, this);
//上边功能区背景
g1.setColor(Color.darkGray);
g1.fill3DRect( 0, 0, 1050, 100, true);
//设置线的粗细(全局)
Graphics2D g2=(Graphics2D)g1;
g2.setStroke(new BasicStroke(2f));
//画棋盘,具体位置根据自己的背景来
g1.setColor(Color.BLACK);
for(int i=1;i<=ROW;i++){
g1.drawLine( 180, 110+i*50, 880, 110+i*50);//画横线
g1.drawLine( 130+i*50, 160, 130+i*50, 860);//画竖线
}
//上方状态信息区
g1.setColor(Color.WHITE);
g1.setFont(new Font("粗体", Font.BOLD,40));
g1.drawString("游戏信息:",110,80);
g1.setColor(Color.BLUE);
g1.drawString(message,300,80);
//右边功能区
g1.setColor(Color.BLUE);
g1.drawRect(950,130,85,30);
g1.setColor(Color.BLACK);
g1.setFont(new Font("粗体", Font.BOLD,18));
g1.drawString(isRestart, 955, 150);
g1.setColor(Color.BLUE);
g1.drawRect(950,170,85,30);
g1.setColor(Color.BLACK);
g1.setFont(new Font("粗体", Font.BOLD,18));
g1.drawString("游戏说明", 955, 190);
g1.setColor(Color.BLUE);
g1.drawRect(950,210,85,30);
g1.setColor(Color.BLACK);
g1.setFont(new Font("粗体", Font.BOLD,18));
g1.drawString("游戏设置", 955, 230);
g1.setColor(Color.BLUE);
g1.drawRect(950,250,85,30);
g1.setColor(Color.BLACK);
g1.setFont(new Font("粗体", Font.BOLD,18));
g1.drawString("悔棋", 955, 270);
g1.setColor(Color.BLUE);
g1.drawRect(950,290,85,30);
g1.setColor(Color.BLACK);
g1.setFont(new Font("粗体", Font.BOLD,18));
g1.drawString("认输", 955, 310);
g1.setColor(Color.BLUE);
g1.drawRect(950,330,85,30);
g1.setColor(Color.BLACK);
g1.setFont(new Font("粗体", Font.BOLD,18));
g1.drawString("退出游戏", 955, 350);
先看效果:
当然界面不是最主要的,但是界面做的好看也是我们程序员对美的追求,你们可以自己换上一些好看的背景图片,棋子也可以用图标代替,实现多样棋子的选择。
接下来就是关键的部分,下子和判断输赢,核心代码:
//画棋子
for(int i=0;i<ROW;i++){
for(int j=0;j<Column;j++){
//[1画黑子,2画白子]
if(allChess[i][j]==1){
int x=i*50+180-chessSize/2;
int y=j*50+160-chessSize/2;
g1.setColor(Color.BLACK);
g1.fillOval( x, y, chessSize, chessSize);
}
//[1画黑子,2画白子]
if(allChess[i][j]==2){
int x=i*50+180-chessSize/2;
int y=j*50+160-chessSize/2;
g1.setColor(Color.WHITE);
g1.fillOval( x, y, chessSize, chessSize);
}
}
}
//判断输赢
public boolean isWin(){
boolean flag=false;
//连成棋子初始个数
int count=1;
int color=allChess[X][Y];
//米字形判断
count=this.checkChess(1,0,color);
if(count>=5){
flag=true;
}else{
count=this.checkChess(0,1,color);
if(count>=5){
flag=true;
}else{
count=this.checkChess(1,-1,color);
if(count>=5){
flag=true;
}else{
count=this.checkChess(1,1,color);
if(count>=5){
flag=true;
}
}
}
}
//返回是否连成五子
return flag;
}
//检测棋子是否连成五子
public int checkChess(int xChange,int yChange,int color){
int count=1;
int temX=xChange;
int temy=yChange;
//米字型遍历
while(X+xChange>=0 && X+xChange<ROW && Y+yChange>=0 && Y+yChange<Column && color==allChess[X+xChange][Y+yChange]){
count++;
if(xChange!=0) {
if(xChange>0){
xChange++;
}else{
xChange--;
}
}
if(yChange!=0){
if(yChange!=0){
if(yChange>0){
yChange++;
}else{
yChange--;
}
}
}
}
//反方向,恢复初始值
xChange=temX;
yChange=temy;
//米字型遍历
while(X-xChange>=0 && X-xChange<ROW && Y-yChange>=0 && Y-yChange<Column && color==allChess[X-xChange][Y-yChange]){
count++;
if(xChange!=0){
if(xChange>0){
xChange++;
}else{
xChange--;
}
}
if(yChange!=0){
if(yChange>0){
yChange++;
}else{
yChange--;
}
}
}
return count;
}
可能大家看了上面的代码觉得是不是有很多地方有缺失,完整代码我会放在后面!!!只希望各位代码爱好者给个收藏。上面代码是整个下棋的核心,接下来就是一些下棋界面的配置代码:如播放音乐,悔棋,认输等等,下面就是完整代码希望大家能多多关注我(一个不懂编程还假装自己很强的菜鸡)。
全部代码
package ChineseChess;
import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.net.MalformedURLException;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
/**
* 智能五子棋
* @author 梦想少年
* 1.界面
* 2.基本下棋
* 3.悔棋、认输、重来
* 4.音乐、更换下棋背景和棋子
* 5.人机对战
*/
@SuppressWarnings("serial")
public class MainUI extends JFrame implements MouseListener{
//棋盘的相关属性设定
Image imageBackGround=new ImageIcon("D:\\常用\\图片\\Camera Roll\\image\\back.png").getImage();//图片
public static final int ROW=15;//行数
public static final int Column=15;//列数
public static final int chessSize=40;//棋子大小
//下棋及棋子相关属性
String isRestart="开始游戏";
boolean isStartGame=false;//是否开始游戏
String message="黑方先行";//游戏提示信息
boolean isBlack=true;//当前是否下黑子
//保存已下棋子的位置数组,悔棋的时候使用
int[] chessX=new int[225];
int[] chessY=new int[225];
//已下棋子数
int countX;
int countY;
//记录棋子位置
int X=1;
int Y=1;
//保存棋盘上目前棋子的状态数组[0表示无棋子,1表示黑子,2表示白子]
int[][] allChess=new int[15][15];
//音乐类
AudioClip audioClip;
//主方法
public static void main(String[] args){
new MainUI().initUI();
}
//初始化窗体
JFrame jf=this;
public void initUI(){