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 白 白 白 黑 黑 黑 白 白 黑 白 黑 白 黑 白 黑 黑
游戏结束

Java五子棋小游戏(控制台纯Ai算法)的更多相关文章

  1. Java 五子棋小游戏

    package Day8_06; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import ...

  2. Java太阳系小游戏分析和源代码

    Java太阳系小游戏分析和源代码 -20150809 近期看了面向对象的一些知识.然后跟着老师的解说做了一个太阳系各行星绕太阳转的小游戏,来练习巩固一下近期学的知识: 用到知识点:类的继承.方法的重载 ...

  3. Java 坦克小游戏心得

    原本是闲得慌无聊才去尝试做这个项目的,因为小时候玩小霸王的游戏机,那个时候经常玩这个游戏吧,特别是喜欢那种自定义地图的模式,觉得自由度非常不错.总之关于这个游戏,想说的一大堆.鉴于能有个空闲的时间,打 ...

  4. Java猜拳小游戏(剪刀、石头、布)

    1.第一种实现方法,调用Random数据包,直接根据“1.2.3”输出“剪刀.石头.布”.主要用了9条输出判断语句. import java.util.Random; import java.util ...

  5. 从零开始学java(小游戏 石头剪刀布)

    Game.java package com.java;import java.util.Scanner;public class Game {        private Player player ...

  6. Java石头剪刀布小游戏

    package com.neusoft.test; import java.awt.BorderLayout; import java.awt.Choice; import java.awt.Colo ...

  7. Java开发小游戏 用键盘控制精灵在游戏中上下左右跑动 窗体小游戏可打包下载,解压后双击start运行

    package com.swift; import java.awt.Point; import java.awt.event.KeyEvent; import com.rupeng.game.Gam ...

  8. Java经典小游戏——贪吃蛇简单实现(附源码)

    一.使用知识 Jframe GUI 双向链表 线程 二.使用工具 IntelliJ IDEA jdk 1.8 三.开发过程 3.1素材准备 首先在开发之前应该准备一些素材,已备用,我主要找了一个图片以 ...

  9. jQuery网页版五子棋小游戏源码下载

    体验效果:http://hovertree.com/texiao/game/4/ 网页五子棋源代码: <!DOCTYPE html> <html> <head> & ...

随机推荐

  1. excel求和结果不对

    excel求和结果不对 Excel求和功能是excel中最常用的功能,但是很多时候会碰到各种错误,比如求和结果总是0.公式求和结果和用计算器敲出来的结果不一样.更新了数据但是求和结果没有变等等.本经验 ...

  2. fastclick使用与 fastclick ios11.3相关bug原因(ios输入框点击变得不灵敏,ios input失焦后,页面上移,点击不了)

    FastClick 移动设备上的浏览器默认会在用户点击屏幕大约延迟300毫秒后才会触发点击事件,这是为了检查用户是否在做双击.为了能够立即响应用户的点击事件,就有了FastClick. 安装fastc ...

  3. Python--day63--单表的增删改查/GET和POST/request相关知识点回顾

  4. 2018-8-10-win10-uwp-后台获取资源

    title author date CreateTime categories win10 uwp 后台获取资源 lindexi 2018-08-10 19:17:19 +0800 2018-2-13 ...

  5. win10 uwp 依赖属性

    本文告诉大家如何使用依赖属性,包括在 UWP 和 WPF 如何使用. 本文不会告诉大家依赖属性的好处,只是简单告诉大家如何使用 在 UWP 和 wpf ,如果需要创建自己的依赖属性,可以使用代码片,在 ...

  6. H3C FTP双TCP连接方式

  7. H3C根路径开销

  8. dotnet 获取程序所在路径的方法

    在 dotnet 有很多方法可以获取当前程序所在的路径,但是这些方法获取到的路径有一点不相同,特别是在工作路径不是当前的程序所在的路径的时候 通过下面几个方法都可以拿到程序所在的文件夹或程序文件 Ap ...

  9. dotnet 通过 WMI 拿到显卡信息

    本文告诉大家如何通过 WMI 拿到显卡信息 如果使用的是 dotnet core 请先引用 Microsoft.Windows.Compatibility 才可以使用 WMI 代码 通过下面的代码可以 ...

  10. KETTLE4个工作中有用的复杂实例--1、数据定时自动(自动抽取)同步作业

    今天呕心沥血花了8个小时给大家带来kettle工作中最常见的四种复杂实例,90%的项目用到这4种实例都可以解决. 4种实例种还有2种通用kettle工具,使用这两种通用工具实例,可以直接修改相应的配置 ...