首页 > 其他分享 >五子棋5.0(完结)

五子棋5.0(完结)

时间:2024-07-20 15:56:38浏览次数:14  
标签:5.0 codeStr int cn1 五子棋 棋子 完结 chessArr SIZE

增加人机对战功能,以及该功能与原程序融合。

一、创建人机AIChess类。

1、AI原理解释

使用0、1、2表示该位置不同的棋子状态,使用哈希表赋给不同的分值,用于后续计算AI下棋的位置。

2、功能实现

(1)首先创建一个AIChess类

存储AI功能的代码,同时初始化一个行列值。

package gobangv4;


import java.awt.*;
import java.util.Arrays;
import java.util.HashMap;

public class AIChess implements Data{
    int r = 0;
    int c = 0;
}

(2)创建一个哈希表存储不同情况的分值

//存储得分
    int[][] codeArr = new int[16][16];
    //定义不同情况下的分值
    HashMap<String,Integer> map =new HashMap<>();
    {
        map.put("010", 10);
        map.put("0110", 100);
        map.put("01110", 1000);
        map.put("011110", 5000);

        map.put("020", 10);
        map.put("0220", 100);
        map.put("02220", 1000);
        map.put("022220", 5000);

        map.put("01", 5);
        map.put("011", 50);
        map.put("0111", 500);
        map.put("01111", 5000);

        map.put("02", 5);
        map.put("022", 50);
        map.put("0222", 500);
        map.put("02222", 5000);

    }

(3)获取每个无棋子的位置的分值

public void getCodeArr(int[][] chessArr){
        //遍历现在的棋盘,得到每个位置的棋子状态
        for (int i = 0; i < chessArr.length; i++) {
            for (int j = 0; j < chessArr.length; j++) {
                //首先判断是否为没有棋子的位置
                int cnum = chessArr[i][j];
                if (cnum == 0){
                    //分别向八个方向遍历
                    toLeft(chessArr,i,j);
                    toRight(chessArr,i,j);
                    toUp(chessArr,i,j);
                    toDown(chessArr,i,j);
                    toTopLeft(chessArr,i,j);
                    toTopRight(chessArr,i,j);
                    toBottomLeft(chessArr,i,j);
                    toBottomRight(chessArr,i,j);
                }
            }
        }
    }
//toLeft向左遍历
    public void toLeft(int[][] chessArr,int r,int c){
        if (c == 0) {
            //处于棋盘最左侧,无需向左遍历
            return;
        }
        int cn1 = chessArr[r][c-1];
        if (cn1 == 0) {
            //左侧第一位没有棋子
            return;
        }
        String codeStr = "0"+cn1;
        for (int i = c-2; i >= 0 ; i--) {
            if (chessArr[r][i] == cn1) {
                //左侧为相同颜色棋子
                codeStr += cn1;
            }else {
                if (chessArr[r][i] == 0){
                    //左侧一位没有棋子
                    codeStr += "0";
                }
                break;
            }
        }
        //根据哈希表获得该位置的分数
        int code = map.get(codeStr);
        System.out.println(codeStr + ":" + code);
        codeArr[r][c] += code;
    }
    //toright向右遍历
    public void toRight(int[][] chessArr,int r,int c){
        if (c == chessArr.length-1){
            //处于棋盘最右侧,无需向右遍历
            return;
        }
        int cn1 = chessArr[r][c+1];
        if (cn1 == 0) {
            //右侧第一位没有棋子
            return;
        }
        String codeStr = "0" + cn1;
        for (int i = c+2; i < chessArr.length ; i++) {
            if (chessArr[r][i] == cn1) {
                //右侧为相同颜色棋子
                codeStr += cn1;
            }else {
                if (chessArr[r][i] == 0){
                    //右侧一位没有棋子
                    codeStr += "0";
                }
                break;
            }
        }
        //根据哈希表获得该位置的分数
        System.out.println(codeStr);
        int code = map.get(codeStr);
        System.out.println(codeStr + ":" + code);
        codeArr[r][c] += code;
    }
    //toup向上遍历
    public void toUp(int[][] chessArr,int r,int c){
        if (r == 0){
            //处于棋盘最上侧,无需向上遍历
            return;
        }
        int cn1 = chessArr[r-1][c];
        if (cn1 == 0){
            //上侧第一位没有棋子
            return;
        }
        String codeStr = "0" + cn1;
        for (int i = r-2; i >= 0 ; i--) {
            if (chessArr[i][c] == cn1){
                //上侧为相同颜色棋子
                codeStr += cn1;
            }else {
                if (chessArr[i][c] == 0){
                    //上侧一位没有棋子
                    codeStr += "0";
                }
                break;
            }
        }
        int code = map.get(codeStr);
        System.out.println(codeStr + ":" + code);
        codeArr[r][c] += code;
    }
    //todown向下遍历
    public void toDown(int[][] chessArr,int r,int c){
        if (r == chessArr.length-1){
            //处于棋盘最下侧,无需向下遍历
            return;
        }
        int cn1 = chessArr[r+1][c];
        if (cn1 == 0){
            //下侧第一位没有棋子
            return;
        }
        String codeStr = "0" + cn1;
        for (int i = r+2; i < chessArr.length ; i++) {
            if (chessArr[i][c] == cn1){
                //下侧为相同颜色棋子
                codeStr += cn1;
            }else {
                if (chessArr[i][c] == 0){
                    //下侧一位没有棋子
                    codeStr += "0";
                }
                break;
            }
        }
        int code = map.get(codeStr);
        System.out.println(codeStr + ":" + code);
        codeArr[r][c] += code;
    }
    //totopLeft左上侧遍历
    public void toTopLeft(int[][] chessArr,int r,int c){
        if (r == 0 || c == 0){
            //棋子在最左侧、最上侧和左上角顶点
            return;
        }
        int cn1 = chessArr[r-1][c-1];
        if (cn1 == 0){
            //左上侧一位无棋子
            return;
        }
        String codeStr = "0" + cn1;
        int i = r-2;
        int j = c-2;
        while(i >= 0 && j >= 0){
            if (chessArr[i][j] == cn1){
                //左上侧为相同颜色棋子
                codeStr += cn1;
                i--;
                j--;
            }else {
                if (chessArr[i][j] == 0){
                    //左上侧一位没有棋子
                    codeStr += "0";
                }
                break;
            }
        }
        int code = map.get(codeStr);
        System.out.println(codeStr + ":" + code);
        codeArr[r][c] += code;
    }
    //totopRight右上侧遍历
    public void toTopRight(int[][] chessArr,int r,int c){
        if (r == 0 || c == chessArr.length-1){
            //棋子在最右侧、最上侧和右上角顶点
            return;
        }
        int cn1 = chessArr[r-1][c+1];
        if (cn1 == 0){
            //右上侧一位无棋子
            return;
        }
        String codeStr = "0" + cn1;
        int i = r-2;
        int j = c+2;
        while(i >= 0 && j < 16){
            if (chessArr[i][j] == cn1){
                //右上侧为相同颜色棋子
                codeStr += cn1;
                i--;
                j++;
            }else {
                if (chessArr[i][j] == 0){
                    //右上侧一位没有棋子
                    codeStr += "0";
                }
                break;
            }
        }
        int code = map.get(codeStr);
        System.out.println(codeStr + ":" + code);
        codeArr[r][c] += code;
    }
    //toBottomLeft左下侧遍历
    public void toBottomLeft(int[][] chessArr,int r,int c){
        if (r == chessArr.length-1 || c == 0){
            //棋子在最左侧、最下侧和左下角顶点
            return;
        }
        int cn1 = chessArr[r+1][c-1];
        if (cn1 == 0){
            //左下侧一位无棋子
            return;
        }
        String codeStr = "0" + cn1;
        int i = r+2;
        int j = c-2;
        while(i < 16 && j >= 0){
            if (chessArr[i][j] == cn1){
                //左下侧为相同颜色棋子
                codeStr += cn1;
                i++;
                j--;
            }else {
                if (chessArr[i][j] == 0){
                    //左下侧一位没有棋子
                    codeStr += "0";
                }
                break;
            }
        }
        System.out.println(codeStr);
        int code = map.get(codeStr);
        System.out.println(codeStr + ":" + code);
        codeArr[r][c] += code;
    }
    //toBottomRight右下侧遍历
    public void toBottomRight(int[][] chessArr,int r,int c){
        if (r == chessArr.length-1 || c == chessArr.length-1){
            //棋子在最右侧、最下侧、右下角顶点
            return;
        }
        int cn1 = chessArr[r+1][c+1];
        if (cn1 == 0){
            //右下侧一位无棋子
            return;
        }
        String codeStr = "0" + cn1;
        int i = r+2;
        int j = c+2;
        while(i < 16 && j < 16){
            if (chessArr[i][j] == cn1){
                //右下侧为相同颜色棋子
                codeStr += cn1;
                i++;
                j++;
            }else {
                if (chessArr[i][j] == 0){
                    //右下侧一位没有棋子
                    codeStr += "0";
                }
                break;
            }
        }
        int code = map.get(codeStr);
        System.out.println(codeStr + ":" + code);
        codeArr[r][c] += code;
    }

(4)创建主函数进行测试

public static void main(String[] args) {
        GameListener gameListener;
        //模拟测试棋盘
        int[][] chessArr = {

                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 1, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},


        };
        AIChess aiChess = new AIChess();
        aiChess.getCodeArr(chessArr);

    }

3、AI功能与源代码适配

(1)源代码优化

1>创建一个ChessUtils类,将人机对战、人人对战、悔棋以及新增的一些优化功能加入其中
public class ChessUtils implements Data {

    int chessStatus = 0;
    Graphics g;
    int[][] chessArr = new int[ROW + 1][COL + 1];
    ToWin toWin = new ToWin();
    int chessSize = 0;
    Chess[] chessList = new Chess[256];
    String gameModel = "人人对战";
    int agame = 0;
}
2>添加前置条件的检查
public boolean check(int x, int y) {
        // 计算行列值
        int r = (y - Y + SIZE / 2) / SIZE;
        int c = (x - X + SIZE / 2) / SIZE;

        if (chessStatus == 0) {
            JOptionPane.showMessageDialog(null,
                    "请先开始新的对局~");
            return false;
        }

        if (r > ROW || c > COL || x < X - SIZE / 2 || y < Y - SIZE / 2) {
            JOptionPane.showMessageDialog(null,
                    "请在棋盘内落子~");
            return false;
        }
        if (chessArr[r][c] != 0) {
            JOptionPane.showMessageDialog(null, "此处已有棋子~");
            return false;
        }
        return true;
    }
3>人人对战
// 人人对战
    public void pvpPlay(int x, int y) {
        // 计算行列值
        int r = (y - Y + SIZE / 2) / SIZE;
        int c = (x - X + SIZE / 2) / SIZE;

        if (!check(x, y)) {
            return;
        }
        chessArr[r][c] = chessStatus;
        Chess chess = new Chess(chessStatus,r,c);
        chessList[chessSize] = chess;
        chessSize++;
        // 判断落子颜色
        if (chessStatus == 1) {
            g.setColor(Color.BLACK);
            chessStatus = 2;
        } else if (chessStatus == 2) {
            g.setColor(Color.WHITE);
            chessStatus = 1;
        }
        // 根据行列值还原标准坐标
        int chessX = c * SIZE + X - SIZE / 2;
        int chessY = r * SIZE + Y - SIZE / 2;
        // 绘制棋子
        g.fillOval(chessX, chessY, SIZE, SIZE);
        if (toWin.isWin(chessArr,r, c)) {
            JOptionPane.showMessageDialog(null, chessStatus== 1 ? "白棋胜利" : "黑棋胜利");
            //将棋子状态归为0,使得后续不能再下棋。
            chessStatus = 0;
        }
    }
4>人机对战
// 人机对战
    public void pvAPlay(int x, int y) {
        //人落子
        if (!check(x, y)) {
            return;
        }
        // 计算行列值
        int r = (y - Y + SIZE / 2) / SIZE;
        int c = (x - X + SIZE / 2) / SIZE;
        chessArr[r][c] = 1;
        Chess chess = new Chess(1, r, c);
        chessList[chessSize] = chess;
        // 根据行列值还原标准坐标
        int chessX = c * SIZE + X - SIZE / 2;
        int chessY = r * SIZE + Y - SIZE / 2;
        // 绘制棋子
        g.setColor(Color.BLACK);
        g.fillOval(chessX, chessY, SIZE, SIZE);
        chessSize++;
        //判断输赢
        if (toWin.isWin(chessArr, r, c)) {
            JOptionPane.showMessageDialog(null, "玩家胜利");
            //将棋子状态归为0,使得后续不能再下棋。
            chessStatus = 0;
        }

        //AI落子
        AIChess aiChess = new AIChess();
        aiChess.playAI(chessArr, g);
        int ar = aiChess.r;
        int ac = aiChess.c;
        chessArr[ar][ac] = 2;
        Chess achess = new Chess(2, ar, ac);
        chessList[chessSize] = achess;
        chessSize++;

        if (toWin.isWin(chessArr, ar, ac)) {
            JOptionPane.showMessageDialog(null, "AI胜利");
            //将棋子状态归为0,使得后续不能再下棋。
            chessStatus = 0;
        }
    }
5>悔棋功能
public void goBack() {

        if (chessSize <= 0) {
            return;
        }
        int count = 1;
        if (gameModel.equals("人机对战")) {
            count = 2;
        }
        for (int i = 0; i < count; i++) {
            //获取最后一个棋子
            Chess chess = chessList[chessSize - 1];
            //将悔棋去除的棋子位置设置为无棋子
            chessArr[chess.r][chess.c] = 0;
            //表明这个位置现在没有棋子对象
            chessList[chessSize - 1] = null;
            //确保下次落子棋子的颜色正确
            chessStatus = chess.chessflag;
            //去除悔棋的棋子的数量
            chessSize--;
            //重绘棋盘
            drawChessPad();
            //按照悔棋后的棋子位置画出棋子
            drawChess();
        }

    }
6>赋予开局和结束对局条件
public void initGame() {
        chessStatus = 1;
        agame = 1;
        chessArr = new int[ROW + 1][COL + 1];
    }

    public void end() {
        chessStatus = 0;
        agame = 0;
    }
7>人人对战和人机对战的切换
GameLietener中mousePressed部分优化为以下代码:
@Override
    public void mousePressed(MouseEvent e) {
        super.mousePressed(e);

        //得到点击坐标
        int x = e.getX();
        int y = e.getY();
        chessUtils.play(x,y);
    }
play部分代码如下:
public void play(int x, int y) {
        if (gameModel.equals("人人对战")) {
            pvpPlay(x, y);
        } else if (gameModel.equals("人机对战")) {
            pvAPlay(x, y);
        }
    }
8>控制对局期间无法切换人人对战和人机对战功能

GameLietener中actionPerformed部分改动为:

else if (ac.equals("人机对战")) {
            //获取按下的按钮,将其文本内容改为“结束对局”,背景色改为粉色
            JButton btn = (JButton) e.getSource();
            btn.setText("人人对战");
            btn.setBackground(Color.pink);
//            将棋盘中每个位置的状态归为0
//            chessUtils.chessArr = new int[16][16];
            chessUtils.setGameModel(ac);
        }else if (ac.equals("人人对战")) {
            //获取按下的按钮,将其文本内容改为“开始游戏”,背景色改为天蓝色
            JButton btn = (JButton) e.getSource();
            btn.setText("人机对战");
            btn.setBackground(Color.cyan);
            chessUtils.setGameModel(ac);
        }

ChessUtils部分为:

public void setGameModel(String gameModel) {
        if (agame == 0) {
            this.gameModel = gameModel;
        }
    }

标签:5.0,codeStr,int,cn1,五子棋,棋子,完结,chessArr,SIZE
From: https://blog.csdn.net/kunkundui6/article/details/140572133

相关文章

  • 7-电子商务系统规划(完结)
    系统规划的方法很多,这里主要介绍关键成功因素法(CriticalSuccessFactors,CSF)、战略目标集转化法(StrategySetTransformation,SST)和企业系统规划法(BusinessSystemPlanning,BSP),这是用得最多的三种方法。其他还有企业信息分析与集成技术(BIAIT)、产出/方法分析(E/MA)、投资回收法(ROI)、征费法、......
  • Beyond Compare v5.0.0.29773 破解版
    BeyondCompare是一款文件及文件夹(目录)的对比工具。BeyondCompare不仅可以快速比较出两个目录的不同,还可以比较每个文件的内容,而且可以任意显示比较结果。BeyondCompare程序内建了文件浏览器,方便您对文件、文件夹、压缩包、FTP网站之间的差异比对以及资料同步。软件截图:使用......
  • 大一菜鸡QT大作业之五子棋
    作者本人为大一即将结束的菜鸡一枚,刚刚完成了暑期课程,上交了自己的QT编程项目----五子棋游戏,较为简陋,由于不打算投入大量时间(只投入了不到一个星期),且不会五子棋人机对战的算法,所以本人的项目是由自己在开源网站上搜索到的两个五子棋项目修改而成,该五子棋具有人人对战,人机对战,联......
  • 华为高斯数据库openGauss_5.0.2 企业版部署学习
    系统环境欧拉系统官方下载链接openEuler-22.03-LTS-SP4-x86_64-dvd.iso https://mirrors.tuna.tsinghua.edu.cn/openeuler/openEuler-22.03-LTS-SP4/ISO/x86_64/openEuler-22.03-LTS-SP4-x86_64-dvd.iso openEuler下载|openEulerISO镜像|openEuler社区官网 数据库安......
  • LocalSend v1.15.0:一款免费的跨平台局域网文件传输工具
    今天电脑天空向大家介绍一款实用的开源跨平台局域网文件传输工具——LocalSendv1.15.0。这款工具能够帮助我们在不同的操作系统之间快速、安全地传输文件,非常适合开发者和IT专业人员使用。以下是LocalSend的详细介绍和使用指南。工具简介LocalSend是一款基于Web技术的文件......
  • 浔川AI五子棋v5.0预告——浔川总社部
    《浔川AI五子棋v5.0预告》亲爱的棋友们,大家好!我们怀着无比激动的心情,向您预告即将震撼登场的浔川AI五子棋v5.0版本!这一次,我们将为您带来前所未有的五子棋体验,让您在智慧的博弈中感受更多的乐趣与挑战。一、更强大的AI对手在v5.0版本中,我们对AI算法进行了......
  • T113-i最新发布Tina5.0系统!支持3大新特性!
    创龙科技全志T113-i双核[email protected]全国产工业核心板(含税79元)一经面世,就以超高性价比受到全行业关注。而创龙科技再次为T113-i处理器平台进行软件系统完善,正式适配Tina5.0系统,大大满足了全志T113-i用户的不同场景需求,让工业应用更简单。Tina5.0系统说明Tina5.0支持OpenWrt......
  • Python 潮流周刊第 2 季完结了,分享几项总结
    我订阅了很多的周刊/Newsletter,但是发现它们都有一个共同的毛病:就是缺乏对往期内容的整理,它们很少会对内容数据作统计分析,更没有将内容整理成合集的习惯。在自己开始连载周刊后,我就想别开生面,除了每周更新正刊外,还计划定期做一些盘点。我认为过往周刊值得被串联起来,形成合集后,既......
  • 使用 Python 处理 Lumerical 导出的 .txt 文件(完结)
    使用Python处理Lumerical导出的.txt文件引言正文以,隔开的波长与透射率以\t隔开的波长与透射率引言之前在添加链接描述一文中我们已经介绍了如何将Lumerical仿真中的S参数相关数据导出为.txt文件。这里我们来分享如何使用Python对这些......
  • dremio 25.0.5 docker 镜像
    就在今天dremio提供了25.0.5社区版的下载地址,但是目前docker镜像暂时还没提供,以下是基于eclipse-temurin:11.0.23_9-jdk基础镜像的一个可用镜像DockerfileFROMeclipse-temurin:11.0.23_9-jdk LABELmaintainer=Dremio COPYdremio-community-25.0.5-2......