11°

Java五子棋小游戏(控制台纯Ai算法)

Java五子棋小游戏(控制台纯Ai算法)

继续之前的那个五子棋程序 修复了一些已知的小Bug

这里是之前的五子棋程序 原文链接

修复了一些算法缺陷 本次增加了AI算法
可以人机对战 也可以Ai对Ai看戏
本次Ai算法属于初级算法 稍微用点小套路还是可以干掉他的
以后会更新高级算法

本次还对程序进行了模块化 拆分成了几个文件

下面请看源码关联

程序架构图

下面请看源代码

GameApp.Java

游戏入口类

package main.game;
/** 游戏入口类 **/
public class GameApp {
/** 游戏入口 */
public static void main(String[] args) {

    Gobang game = new Gobang();
    //Player Vs Ai
    Player p1 = new Player("玩家",'彩');//就这么特殊 就用彩棋 热性!
    Player p2 = new AiPlayer("机器人",'白');

    //Player Vs Player 
    //Player p1 = new Player("玩家",'黑');
    //Player p2 = new Player("玩家2",'白');

    //Ai Vs Ai
    //Player p1 = new AiPlayer("玩家",'黑');
    //Player p2 = new AiPlayer("机器人",'白');

    game.createGame(p1,p2);
    game.start();
}

}

Gobang.java

游戏核心控制类
这里控制游戏核心算法 例如游戏的胜负算法

package main.game;
/**
 * 控制台五子棋游戏
 */
public class Gobang {
    private boolean gameover = false;
    //15*15棋盘
    private char[][] table = new char[16][16];
    //两个玩家
    private Player p1,p2;
    //回合
    private int huihe = 0;
public Player getP1() {
    return p1;
}

public Player getP2() {
    return p2;
}

public void createGame(Player p1, Player p2){
    this.p1=p1;
    this.p2=p2;
}

public char[][] getTable() {return table;}

/** 展示棋局 **/
private void show(){

    int xx =0;
    System.out.println("    0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 ");
    for(char[] cs :table){
        System.out.print(" "+xx+(xx>9?"":" ")+" ");
        for(char c : cs){
            if(c==0) System.out.print("·");
            System.out.print(c+" ");
        }
        System.out.println();
        xx++;
    }


}
/** 获取下一个走棋的 **/
private Player getPlayer(){
    //p1先走
    if (huihe==0) return p1;
    if (huihe%2!=0) return p2;
    return p1;
}
/** 判断是否获胜 **/
private boolean isWin(int x,int y,char c){
    /*
     x 和 y  代表坐标
    * xx :x方向需要增加的值
    * yy :y方向需要增加的值
    *
    * 例如xx = -1 yy= -1
    * 代表需要获取(x-1,y-1)的棋子颜色
    *
    *  xx = 1 yy= 1
    * 代表需要获取(x+1,y+1)的棋子颜色
    *
    * */
    int xx = 0,yy=0;
    for (int i =1 ;i<9 ;i++ ){
        switch (i){
            case 1:
                xx=-1;yy=-1;
                break;
            case 2:
                xx=-1;yy=1;
                break;
            case 3:
                xx=-1;yy=0;
                break;
            case 4:
                xx = 1;yy = -1;
                break;
            case 5:
                xx = 1;yy = 1;
                break;
            case 6:
                xx = 1 ;yy = 0;
                break;
            case 7:
                xx = 0;yy = -1;
                break;
            case 8:
                xx = 0;yy = 1;
                break;


        }

        int n = ishas(x,y,xx,yy,0,c)+ishas(x,y,-xx,-yy,0,c);
        if(n>=4)return true;

    }
    return false;
}



/**
 * 检测是否有棋子
 * @param x x坐标
 * @param y y坐标
 * @param xx x方向
 * @param yy y方向
 * @param size 缓存
 * @param c 颜色
 * @return 权重
 */
private int ishas(int x,int y,int xx,int yy,int size ,char c){
    if((x==0&&xx==-1)|| (x==15&&xx==1) || (y==0&&yy==-1) || (y== 15&&yy==1)) return size;

    if(table[x+xx][y+yy] == c){
        return ishas(x+xx,y+yy,xx,yy,size+1,c);
    }
    return size;
}



/** 下棋 **/
public boolean put(int x,int y,Player p){
    if (table[x][y]==Character.MIN_VALUE) {
        table[x][y] = p.getColor();

        if(isWin(x,y,p.color)){
            gameover = true;
            System.out.println(p.username+"("+p.color+")赢得了胜利");
        }
        return true;
    }
    return false;
}

/** 游戏运行 **/
public void start(){
    //本回合下子选手
    Player p = null;
    while (!gameover){
        //棋盘已满
        if(huihe/2+1 == 129)break;
        if(p==null)p=getPlayer();
        System.out.println("第"+(huihe/2+1)+"回合,下子方:"+p.getUsername()+"("+p.getColor()+")");
        System.out.println("请输入你要下的位置(空格隔开) 例如:10 5");
        int ps = p.run(this);
        //下子错误
        if (ps == 0)continue;
        //游戏结束 用户输入了exit
        else if( ps == 1)break;
        show();
        p=null;
        huihe++;
    }
    System.out.println("游戏结束");

}

}

Player.java

玩家类
这里是玩家使用控制台下棋算法

package main.game;

import java.util.Scanner;

public /** 玩家类 **/ class Player{ String username; char color; Scanner scan;

public Player(String username, char color) {
    this.username = username;
    this.color = color;
    System.out.println(username+"携带"+color+"颜色的棋子加入游戏");
    scan = new Scanner(System.in);
}

public String getUsername() {
    return username;
}

public char getColor() {
    return color;
}

/** 玩家需要获控制台输入的值 **/
public int run(Gobang app) {
    //下棋失败重新开始本回合

    String[] strArr ;

    String in = scan.nextLine().trim();
    if ("exit".equals(in)) return 1;
    try {
        strArr = in.split(" ");
        if (!app.put(Integer.parseInt(strArr[0]), Integer.parseInt(strArr[1]), this)) return 0;
    }catch (Exception e){
        return 0;
    }
    return -1;

}

}

AiPlayer.java

Ai机器人算法类
这里有ai机器人下棋算法思路
本算发用点套路还是可以很轻松的干掉Ai的
本算法属于初级算法 后期会更新高级的

package main.game;

import java.util.*;

public /** 机器人 / class AiPlayer extends Player { private Random r = new Random(); private List<Piece> pieces = new LinkedList<>(); private char p2 ; private char[][] table; / 创建Ai机器人 **/ public AiPlayer(String username, char color) { super(username, color); }

@Override
/** Ai机器人的算法 **/
public int run(Gobang app){
    if (p2 == Character.MIN_VALUE || app.getP1()==this){

        this.p2 = app.getP2().color;
    }else{
        this.p2= app.getP1().color;
    }

    Piece args = up(app);
    System.out.println("智能下棋("+args.x+","+args.y+")");
    try {
        if (!app.put(args.x, args.y, this)) return 0;
    }catch (Exception e){
        return 0;
    }
    return -1;
}

/** 测试用,随缘下棋 **/
private Piece test(){
    for (int i =0;i&lt;3;i++){
        int x = r.nextInt(3)+6;
        int y = r.nextInt(3)+6;
        if(table[x][y] == Character.MIN_VALUE){
            return new Piece(x,y,0,this.color);
        }
    }
    while (true){
        int x = r.nextInt(16);
        int y = r.nextInt(16);
        if(table[x][y] == Character.MIN_VALUE){
            return new Piece(x,y,0,this.color);
        }
    }
}


/** 智能算法下棋 **/
private Piece up(Gobang app){
    pieces.clear();
    table = app.getTable();
    for (int x = 0;x &lt;16; x++){
        for (int y = 0;y &lt;16; y++){

            //判断空余地方获胜几率
            if (table[x][y] == Character.MIN_VALUE){
                //判断自己权重
                sub(x,y,this.color);
                //判断对手权重
                sub(x,y,p2);
            }
        }
    }
  return get();
}

/** 计算权重 **/
private void sub(int x,int y,char c){

    char m = this.color;
    int xx = 0,yy=0;
    int num = 0 ;
    for (int i =0 ;i&lt;8 ;i++ ){
        switch (i){
            case 0:
                xx = 0;yy = 1;
                break;
            case 1:
                xx=-1;yy=-1;
                break;
            case 2:
                xx=-1;yy=1;
                break;
            case 3:
                xx=-1;yy=0;
                break;
            case 4:
                xx = 1;yy = -1;
                break;
            case 5:
                xx = 1;yy = 1;
                break;
            case 6:
                xx = 1 ;yy = 0;
                break;
            case 7:
                xx = 0;yy = -1;
                break;

        }
        if(c == this.color){
            //查自己下子权重
            int a = ishas(x, y, xx, yy, 0,this.color,p2)+ishas(x, y, -xx, -yy, 0,this.color,p2);
            if (a&gt;num)num=a;
            m = this.color;

// num += ishas(x, y, xx, yy, 0,this.color,p2)+ishas(x, y, -xx, -yy, 0,this.color,p2);

        }else{
            //检测对手威胁权重
            int a = ishas(x, y, xx, yy, 0,p2,this.color)+ishas(x, y, -xx, -yy, 0,p2,this.color);
            if (a&gt;num)num=a;
            m=p2;

// num +=ishas(x, y, xx, yy, 0,p2,this.color)+ishas(x, y, -xx, -yy, 0,p2,this.color); }

    }
    pieces.add(new Piece(x,y,num,m));
}


/** 检测周围有没有棋子 **/
private Piece get(){

// 挑选权重最大的 pieces.sort(new Comparator<Piece>() { @Override public int compare(Piece o1, Piece o2) { return o1.info< o2 .info ? 1:(o1.info == o2.info ? 0: -1); } }); //随缘棋子 System.out.println(pieces); if(pieces.size()==0 || pieces.get(0).info == 0)return test(); int max = pieces.get(0).info; Piece index = pieces.get(0); for(Piece ps : pieces ){

        if(ps.info&lt;max){
            return index;
        }
        index = ps;

    }
    return index ;
}


/** 检测棋子 **/
private int ishas(int x,int y,int xx,int yy,int size ,char c,char c2){
    if((x==0&amp;&amp;xx==-1)|| (x==15&amp;&amp;xx==1) || (y==0&amp;&amp;yy==-1) || (y== 15&amp;&amp;yy==1)) return size;
    if(table[x+xx][y+yy] == c){
        return ishas(x+xx,y+yy,xx,yy,size+1,c,c2);
    }else if(table[x+xx][y+yy] == c2){
        return size&gt;3 ? size+2:size-1;
    }
    return size;
}




/**判断危机**/

}

Piece.java

棋子类 这里没啥可用的 就是写Ai算法时候调用方便

package main.game;
/** Ai算法棋子类 **/
public class Piece {
    //坐标
    int x;
    int y;
char color;

//权重
int info;

public Piece(int x, int y, int info,char color) {
    this.x = x;
    this.y = y;
    this.info = info;
    this.color = color;
}

@Override
public String toString() {
    return "Piece"+color+"{" +
            "x=" + x +
            ", y=" + y +
            ", info=" + info +
            '}';
}

}

本文转载自博客园,原文链接:https://www.cnblogs.com/xiaoshuai123/p/12189631.html

全部评论: 0

    我有话说: