java实现单机版五子棋(人人,人机)

团队成员

王春意 202203010080

朱振瑜 202203010082

设计思路

运行主类


public class YunXing {
    public static void main(String[] args) {
        new Test();
    }
}

胜负条件判断

   public  boolean iswin(int x,int y, int owner) {
        //创建一个变量用来记录同一方向上的相同棋子个数
        int account = 0;
        //判断水平
        //1.水平左侧
        for (int i = x-1; i >=0; i--) {
            if (location[i][y]==owner){
                account++;
            }
            else {
                break;
            }
        }
        //2.水平右侧
        for (int i = x+1; i < QiPan_Size; i++) {
            if (location[i][y]==owner){
                account++;
            }
            else {
                break;
            }
        }
        if (account >=4)
        {
            return true;
        }
        account=0;
        //判断垂直
        //1.垂直上方
        for (int i = y-1; i >=0; i--) {
            if (location[x][i]==owner){
                account++;
            }
            else {
                break;
            }
        }
        //2.垂直下方
        for (int i = y+1; i < QiPan_Size; i++) {
            if (location[x][i]==owner){
                account++;
            }
            else {
                break;
            }
        }
        if (account >=4)
        {
            return true;
        }
        account=0;
        //判断左上和右下
        //1.左上方
        for (int i = y-1, j = x-1; i >=0&&j>=0; i--,j--) {
            if (location[j][i]==owner){
                account++;
            }
            else {
                break;
            }
        }
        //2.右下方
        for (int i = y+1, j = x+1; i < QiPan_Size &&j< QiPan_Size; i++,j++) {
            if (location[j][i]==owner){
                account++;
            }
            else {
                break;
            }
        }
        if (account >=4)
        {
            return true;
        }
        account = 0;
        //判断右上和左下
        //1.右上方
        for (int i = y-1, j = x+1; i >=0&&j< QiPan_Size; i--,j++) {
            if (location[j][i]==owner){
                account++;
            }
            else {
                break;
            }
        }
        //2.左下方
        for (int i = y+1, j = x-1; i < QiPan_Size &&j>=0; i++,j--) {
            if (location[j][i]==owner){
                account++;
            }
            else {
                break;
            }
        }
        if (account >=4)
        {
            return true;
        }
        account = 0;
        return  false;
    }

机器寻找最佳落子位置

 //机器落子
    public  Location searchlocation() {
        //初始化score评分,遍历棋盘所有位置
        for (int i = 0; i < QiPan_Size; i++) {
            for (int j = 0; j < QiPan_Size; j++) {
                score[i][j] = 0;
            }
        }

        //每次机器落子都重新计算一次评分
        //寻找五元组
        int hunmanchessmannum = 0;//五元组中机器棋子数目
        int machinechessmannum = 0;//五元组中人类棋子数目
        int tuplescoretmp = 0;//临时得分(临时变量
        //目标位置坐标
        int goalX = -1;
        int goalY = -1;
        //利用计分方法求最大分数
        int maxscore = -1;
        //1.纵向十五行的五元组
        // 每行的横坐标不变,纵坐标增加至10,用k来确定五元组并计分
        for (int i = 0; i < 15; i++) {
            for (int j = 0; j < 11; j++) {
                int k=j;
                while (k<j+5){
                    //切换到下一个五元组
                    if (location[i][k]==-1)machinechessmannum++;
                    else if(location[i][k]==1)hunmanchessmannum++;
                    k++;
                }
                //求出五元组中人类和机器的棋子数后进行计分赋给当前位置
                tuplescoretmp=tuplescore(hunmanchessmannum,machinechessmannum);
                for (k = j;  k< j+5; k++) {
                    score[i][k]+=tuplescoretmp;
                }
                //参数置零
                hunmanchessmannum=0;
                machinechessmannum=0;
                tuplescoretmp=0;
            }
        }
        //2.横向15行,遍历,类似
        for (int i = 0; i < 15; i++) {
            for (int j = 0; j < 11; j++) {
                int k=j;
                while (k<j+5){
                    if (location[k][i]==-1)machinechessmannum++;
                    else if(location[k][i]==1)hunmanchessmannum++;
                    k++;
                }
                tuplescoretmp=tuplescore(hunmanchessmannum,machinechessmannum);
                for (k = j;  k< j+5; k++) {
                    score[k][i]+=tuplescoretmp;
                }
                hunmanchessmannum=0;
                machinechessmannum=0;
                tuplescoretmp=0;
            }
        }
         //3.右上到左下上侧
        //i横坐标,j纵坐标,i--,j++,
        for (int i = 14; i >=4 ; i--) {
            for (int k=i,j = 0; j <15&&k>=0 ; k--,j++) {
                int m=k;
                int n=j;
                while (m>k-5&&k-5>=-1){
                    if(location[m][n]==-1) machinechessmannum++;
                    else if(location[m][n]==1)hunmanchessmannum++;
                    m--;
                    n++;
                }
                //角落附近可能构不成五元组,k的取值没有限制,排除无法构成五元组的位置
                if(m==k-5){
                    tuplescoretmp=tuplescore(hunmanchessmannum,machinechessmannum);
                    for (m=k,n=j;  m>k-5 ; m--,n++) {
                        score[m][n]+=tuplescoretmp;
                    }
                }
                hunmanchessmannum=0;
                machinechessmannum=0;
                tuplescoretmp=0;
            }
        }
        //4.扫描右上到坐下的下侧
        for (int i = 1; i <15 ; i++) {
            for (int k=i,j = 14; j>=0&&k<15 ; j--,k++) {
                int m=k;
                int n=j;
                while (m<k+5&&k+5<=15){
                    if(location[n][m]==-1) machinechessmannum++;
                    else if(location[n][m]==1)hunmanchessmannum++;
                    m++;
                    n--;
                }
                //角落附近可能构不成五元组
                if(m==k+5){
                    tuplescoretmp=tuplescore(hunmanchessmannum,machinechessmannum);
                    for (m=k,n=j;  m<k+5 ; m++,n--) {
                        score[n][m]+=tuplescoretmp;
                    }
                }
                hunmanchessmannum=0;
                machinechessmannum=0;
                tuplescoretmp=0;
            }
        }

//5.扫描左上到右下上侧
        for (int i = 0; i <11 ; i++) {
            for (int k=i,j = 0; j<15&&k<15 ; j++,k++) {
                int m=k;
                int n=j;
                while (m<k+5&&k+5<=15){
                    if(location[m][n]==-1) machinechessmannum++;
                    else if(location[m][n]==1)hunmanchessmannum++;
                    m++;
                    n++;
                }
                if(m==k+5){
                    tuplescoretmp=tuplescore(hunmanchessmannum,machinechessmannum);
                    for (m=k,n=j;  m<k+5 ; m++,n++) {
                        score[m][n]+=tuplescoretmp;
                    }
                }
                hunmanchessmannum=0;
                machinechessmannum=0;
                tuplescoretmp=0;
            }
        }
        //6.扫描左上到右下下测
        for (int i = 1; i <11 ; i++) {
            for (int k=i,j = 0; j<15&&k<15 ; j++,k++) {
                int m=k;
                int n=j;
                while (m<k+5&&k+5<=15){
                    if(location[n][m]==-1) machinechessmannum++;
                    else if(location[n][m]==1)hunmanchessmannum++;
                    m++;
                    n++;
                }
                if(m==k+5){
                    tuplescoretmp=tuplescore(hunmanchessmannum,machinechessmannum);
                    for (m=k,n=j;  m<k+5 ; m++,n++) {
                        score[n][m]+=tuplescoretmp;
                    }
                }
                hunmanchessmannum=0;
                machinechessmannum=0;
                tuplescoretmp=0;
            }
        }
        //从剩余位置中找得分最大点
        for (int i=0;i<15;i++){
            for (int  j=0;j<15;j++){
                if (location[i][j]==0&&score[i][j]>maxscore){
                    goalX = i;
                    goalY = j;
                    maxscore = score[i][j];
                }
            }
        }
        if (goalX !=-1 && goalY != -1){
            return new Location(goalX,goalY,-1);
        }
        //无最大值则平局
        return new  Location(0,0,15);
    }
    /*用计分板给每一个五元组计分
    五元组的得分由每一个位置的得分构成
    每个位置的得分即是其八个方向的得分之和
    * */

    private int tuplescore(int hunmanchessmannum, int machinechessmannum) {
        //既有人类棋子又有机器棋子,判分0
        if (hunmanchessmannum>0&&machinechessmannum>0){
            return 0;
        }
        //全部为空,无落子,判分7
        if (hunmanchessmannum==0 && machinechessmannum == 0){
            return 7;
        }
        //机器1子,判分35
        if (machinechessmannum == 1){
            return 35;
        }
        //机器2子,判分800
        if (machinechessmannum == 2){
            return 800;
        }
        //机器3子,判分1500
        if (machinechessmannum == 3){
            return 15000;
        }
        //机器4子,判分800000
        if (machinechessmannum == 4){
            return 800000;
        }
        //人类1子,判分15
        if (hunmanchessmannum == 1){
            return 15;
        }
        //人类2子,判分400
        if (hunmanchessmannum == 2){
            return 400;
        }
        //人类3子,判分1800
        if (hunmanchessmannum == 3){
            return 1800;
        }
        //人类4子,判分100000
        if (hunmanchessmannum == 4){
            return 100000;
        }
        return -1;
    }

鼠标监听,一个用来画棋子,一个用来选择模式

public class Game implements ActionListener {
    private String Moshi;
    public Game(String s){
        Moshi= s;
    }
    public void actionPerformed(ActionEvent event){
        //ActionEvent对应按钮点击、菜单选择、选择列表项或在文本框中ENTER
        if (Moshi.equals("人机模式")){
            new Ui().init();
        }
        else if (Moshi.equals("双人对战")){
            new pk().init();
        }
    }

}
qipan.addMouseListener(new MouseAdapter() {//qipan就是棋盘对象
            @Override
            public void mouseClicked(MouseEvent e) {
                super.mouseClicked(e);
                //调用画棋子的方法(封装方法play
                play(e);
            }
        });
    }
    //处理鼠标点击事件的方法
    private void play(MouseEvent e) {
        //将鼠标的位置转成棋盘坐标的位置,需要格子的大小
        int cellSize = qipan.getCellsize();
        //保证棋子落在正中间
        int x = (e.getX()-5)/cellSize;
        int y = (e.getY()-5)/cellSize;

运行效果

github地址:GitHub - jik5/-: 五子棋

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值