Java五子棋小游戲(控制台純Ai演算法) 繼續之前的那個五子棋程式 修複了一些已知的小Bug 這裡是之前的五子棋程式 "原文鏈接" 修複了一些演算法缺陷 本次增加了AI演算法 可以人機對戰 也可以Ai對Ai看戲 本次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<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 <16; x++){
for (int y = 0;y <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<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>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>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<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&&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,c2);
}else if(table[x+xx][y+yy] == c2){
return size>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 +
'}';
}
}
Ai vs Ai的話可能會出現這樣的場景
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
0 黑 白 白 黑 黑 黑 黑 白 白 黑 白 黑 白 黑 白 黑
1 黑 白 黑 黑 白 白 白 黑 黑 白 黑 黑 黑 白 白 白
2 黑 黑 白 白 白 黑 白 白 白 黑 黑 白 黑 白 黑 白
3 白 白 黑 黑 白 黑 白 黑 白 黑 白 白 黑 黑 黑 白
4 黑 黑 白 白 白 黑 黑 白 白 白 白 黑 白 黑 白 黑
5 黑 白 黑 白 黑 黑 白 黑 黑 白 黑 黑 白 黑 白 白
6 黑 白 白 黑 黑 白 白 白 黑 白 黑 黑 白 白 黑 黑
7 白 黑 白 白 黑 白 黑 黑 黑 白 黑 白 黑 白 白 黑
8 黑 白 黑 白 黑 白 黑 黑 黑 黑 白 白 白 黑 黑 黑
9 白 黑 黑 白 白 白 白 黑 白 黑 白 黑 黑 白 白 白
10 白 黑 白 黑 黑 黑 白 白 白 白 黑 白 白 白 黑 黑
11 白 黑 白 黑 黑 黑 黑 白 黑 黑 白 白 白 白 黑 黑
12 黑 白 黑 白 白 白 黑 白 白 白 黑 黑 黑 白 白 黑
13 黑 白 黑 白 黑 白 白 白 白 黑 黑 黑 白 黑 黑 黑
14 黑 黑 黑 黑 白 白 黑 黑 黑 白 白 白 黑 白 白 白
15 白 白 白 黑 黑 黑 白 白 黑 白 黑 白 黑 白 黑 黑
游戲結束