Java版AI五子棋游戏

本文实例为大家分享了java五子棋游戏的具体代码,供大家参考,具体内容如下

AI思路:通过判断棋盘上每个空位的分数,去分数最高的几个点,随机下棋
分数计算思路:能成5个说明能赢了,给最高分
不能成5个,对方能成5个,说明对方要赢了,给第二高分
能成活4,给第三高分
能成活3,给第四高分
能成冲4,给第五高分
能成冲3,给第六高分
能成活2,给第七高分
能成冲2,给第八高分
其他,给最低分
分数设定可自己定义。

因为是去年写的了,思路记得大概就是这样。最近根据书上写了个棋类游戏的设计框架,待完善后再发上来,应该会更新AI思路
下面是去年写的AI五子棋的代码:

package FivechessClient;

import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

/**
 *
 * @ClassName: Game
 * @Description: AI五子棋
 * @author xiaoxiong
 * @date 2015年7月3日 下午8:59:02
 *
 */
public class Game {
 BufferedImage table;
 BufferedImage black;
 BufferedImage white;

 BufferedImage selected;
 /**
 * 棋子个数
 */
 private static int BOARD_SIZE = 15;
 /**
 * 棋盘宽高
 */
 private final int TABLE_WIDTH = 535;
 private final int TABLE_HEIGHT = 536;
 /**
 * 棋盘15等分
 */
 private final int RATE = TABLE_WIDTH / BOARD_SIZE;
 /**
 * 棋盘外边距
 */
 private final int X_OFFSET = 5;
 private final int Y_OFFSET = 6;
 /**
 * 棋盘
 */
 private int[][] board = new int[BOARD_SIZE][BOARD_SIZE];
 /**
 * AI分数
 */
 private int[][] computerScore = new int[BOARD_SIZE][BOARD_SIZE];
 // private int[][] gamerScore = new int[BOARD_SIZE][BOARD_SIZE];

 JFrame f = new JFrame("五子棋--小熊");

 ChessBoard chessBoard = new ChessBoard();

 private static int selectedX = -1;
 private static int selectedY = -1;
 private static int computerX = -1;
 private static int computerY = -1;

 private static boolean flagGamer = false; // 记录玩家是否赢了
 private static boolean flagComputer = false; // 记录电脑是否赢了

 private static int computerscore = 0; // 电脑最大分数
 private static int comx, comy; // 玩家下子坐标

 private final int HUO = 1;
 private final int CHONG = 2;
 private static int chesscou = 0;
 /**
 * 记录找到的分数一样的棋子,随机下这些棋子中的一个,以防步法固定
 */
 private ArrayList<ChessXY> chessList = new ArrayList<ChessXY>();

 Random rand = new Random();

 /**
 *
 * @Title: initto @Description: 重置游戏 @param @return void @throws
 */
 public void initto() {
 for (int i = 0; i < BOARD_SIZE; ++i) {
 for (int j = 0; j < BOARD_SIZE; ++j) {
 board[i][j] = 0;
 computerScore[i][j] = 100000;
 }
 }
 chesscou = 0;
 computerX = -1;
 computerY = -1;
 flagGamer = false;
 flagComputer = false;
 }

 /**
 *
 * @Title: isRun @Description: 判断该位置是否可以走 @param @param x @param @param
 * y @param @return @return boolean @throws
 */
 public boolean isRun(int x, int y) {
 if (board[x][y] == 0) {
 return true;
 }
 return false;
 }

 /**
 *
 * @Title: isWin @Description: 判断下该子是否能赢 @param @param f 颜色 @param @param x
 * 坐标 @param @param y @param @return @return boolean @throws
 */
 public boolean isWin(int f, int x, int y) {
 int i, count = 1;
 boolean up, down, right, left, rup, lup, rdown, ldown;
 up = down = right = left = rup = lup = rdown = ldown = true;
 /**
 *
 * 上下
 *
 */
 for (i = 1; i < 5; ++i) {
 if ((y + i) < BOARD_SIZE) {
 if (board[x][y + i] == f && down)
 count++;
 else
 down = false;
 }
 if ((y - i) >= 0) {
 if (board[x][y - i] == f && up)
 count++;
 else
 up = false;
 }
 }
 if (count >= 5) {
 return true;
 }
 count = 1;
 /**
 *
 * 左右
 *
 */
 for (i = 1; i < 5; ++i) {
 if ((x + i) < BOARD_SIZE) {
 if (board[x + i][y] == f && right)
 count++;
 else
 right = false;
 }
 if ((x - i) >= 0) {
 if (board[x - i][y] == f && left)
 count++;
 else
 left = false;
 }
 }
 if (count >= 5) {
 return true;
 }
 count = 1;
 /**
 *
 * 左上右下
 *
 */
 for (i = 1; i < 5; ++i) {
 if ((x + i) < BOARD_SIZE && (y + i) < BOARD_SIZE) {
 if (board[x + i][y + i] == f && rdown)
 count++;
 else
 rdown = false;
 }
 if ((x - i) >= 0 && (y - i) >= 0) {
 if (board[x - i][y - i] == f && lup)
 count++;
 else
 lup = false;
 }
 }
 if (count >= 5) {
 return true;
 }
 count = 1;
 /**
 *
 * 右上左下
 *
 */
 for (i = 1; i < 5; ++i) {
 if ((x + i) < BOARD_SIZE && (y - i) >= 0) {
 if (board[x + i][y - i] == f && rup)
 count++;
 else
 rup = false;
 }
 if ((x - i) >= 0 && (y + i) < BOARD_SIZE) {
 if (board[x - i][y + i] == f && ldown)
 count++;
 else
 ldown = false;
 }
 }
 if (count >= 5) {
 return true;
 }

 return false;
 }

 /**
 *
 * @Title: Computer_AI @Description: AI下棋 @param @return void @throws
 */
 public void Computer_AI() {
 computerscore = 0;
 for (int i = 0; i < BOARD_SIZE; ++i) {
 for (int j = 0; j < BOARD_SIZE; ++j) {
 computerScore[i][j] = 0;
 // gamerScore[i][j] = 0;
 }
 }
 getScore();
 for (int i = 0; i < BOARD_SIZE; ++i) {
 for (int j = 0; j < BOARD_SIZE; ++j) {
 if (computerScore[i][j] == computerscore) {
 ChessXY chess = new ChessXY(i, j);
 chessList.add(chess);
 }
 }
 }
 int n = rand.nextInt(chessList.size()); // 电脑根据分值一样的点随机走,防止每次都走相同的步数
 comx = chessList.get(n).x;
 comy = chessList.get(n).y;
 chessList.clear();
 }

 /**
 *
 * @Title: getScore @Description: 评分 @param @return void @throws
 */
 public void getScore() {
 for (int i = 0; i < BOARD_SIZE; ++i) {
 for (int j = 0; j < BOARD_SIZE; ++j) {
 if (board[i][j] == 0) {
 if (isWin(2, i, j)) // 电脑能赢,故给分最高,因为可以结束,所以不再检测
 {
 computerscore = 13;
 computerScore[i][j] = 13;

 return;
 } else if (isWin(1, i, j)) // 电脑不能赢,玩家能赢,要阻止,所以给12分
 {
 computerscore = 12;
 computerScore[i][j] = 12;
 } else if (isHuoOrChong(2, i, j, 4, HUO)) // 电脑玩家都不能赢,电脑能形成活四,给11分
 {
 computerscore = (computerscore > 11 ? computerscore : 11);
 computerScore[i][j] = 11;
 } else if (isHuoOrChong(2, i, j, 4, CHONG)) // 电脑玩家都不能赢,电脑能形成冲四,给10分
 {
 computerscore = (computerscore > 10 ? computerscore : 10);
 computerScore[i][j] = 10;
 } else if (isHuoOrChong(1, i, j, 4, HUO)) // 电脑玩家都不能赢,玩家能形成活四,给9分
 {
 computerscore = (computerscore > 9 ? computerscore : 9);
 computerScore[i][j] = 9;
 } else if (isHuoOrChong(2, i, j, 3, HUO)) // 电脑玩家都不能赢,电脑能形成活三,给8分
 {
 computerscore = (computerscore > 8 ? computerscore : 8);
 computerScore[i][j] = 8;
 } else if (isHuoOrChong(1, i, j, 4, CHONG)) // 电脑玩家都不能赢,玩家能形成冲四,给7分
 {
 computerscore = (computerscore > 7 ? computerscore : 7);
 computerScore[i][j] = 7;
 } else if (isHuoOrChong(2, i, j, 3, CHONG)) // 电脑玩家都不能赢,电脑能形成冲三,给6分
 {
 computerscore = (computerscore > 6 ? computerscore : 6);
 computerScore[i][j] = 6;
 } else if (isHuoOrChong(2, i, j, 2, HUO)) // 电脑玩家都不能赢,电脑能形成活二,给5分
 {
 computerscore = (computerscore > 5 ? computerscore : 5);
 computerScore[i][j] = 5;
 } else if (isHuoOrChong(1, i, j, 3, CHONG)) // 电脑玩家都不能赢,玩家能形成冲三,给4分
 {
 computerscore = (computerscore > 4 ? computerscore : 4);
 computerScore[i][j] = 4;
 } else if (isHuoOrChong(1, i, j, 2, HUO)) // 电脑玩家都不能赢,玩家能形成活二,给3分
 {
 computerscore = (computerscore > 3 ? computerscore : 3);
 computerScore[i][j] = 3;
 } else if (isHuoOrChong(2, i, j, 2, CHONG)) // 电脑玩家都不能赢,电脑能形成冲二,给2分
 {
 computerscore = (computerscore > 2 ? computerscore : 2);
 computerScore[i][j] = 2;
 } else if (isHuoOrChong(1, i, j, 2, CHONG)) // 电脑玩家都不能赢,玩家能形成冲二,给1分
 {
 computerscore = (computerscore > 1 ? computerscore : 1);
 computerScore[i][j] = 1;
 } else {
 computerScore[i][j] = 0;
 }
 }
 }
 }
 }

 /**
 *
 * @Title: isHuoOrChong @Description: 判断是否为活 @param @param f @param @param
 * x @param @param y @param @param num @param @param
 * hORc @param @return @return boolean @throws
 */
 private boolean isHuoOrChong(int f, int x, int y, int num, int hORc) // 活
 {

 num += 1;
 int i, count = 1;
 boolean terminal1 = false;
 boolean terminal2 = false;
 boolean up, down, right, left, rup, lup, rdown, ldown;
 up = down = right = left = rup = lup = rdown = ldown = true;
 /**
 *
 * 上下
 *
 */
 for (i = 1; i < num; ++i) {
 if ((y + i) < BOARD_SIZE) {
 if (board[x][y + i] == f && down)
 count++;
 else {
 if (board[x][y + i] == 0 && down) {
 terminal1 = true;
 }
 down = false;
 }
 }
 if ((y - i) >= 0) {
 if (board[x][y - i] == f && up)
 count++;
 else {
 if (board[x][y - i] == 0 && up) {
 terminal2 = true;
 }
 up = false;
 }
 }
 }
 if (count == num - 1 && hORc == HUO && terminal1 && terminal2) {
 return true;
 }
 if (count == num - 1 && hORc == CHONG && ((terminal1 && !terminal2) || (!terminal1 && terminal2))) {
 return true;
 }
 count = 1;
 terminal1 = false;
 terminal2 = false;
 /* 左右 */
 for (i = 1; i < num; ++i) {
 if ((x + i) < BOARD_SIZE) {
 if (board[x + i][y] == f && right)
 count++;
 else {
 if (board[x + i][y] == 0 && right) {
 terminal1 = true;
 }
 right = false;
 }
 }
 if ((x - i) >= 0) {
 if (board[x - i][y] == f && left)
 count++;
 else {
 if (board[x - i][y] == 0 && left) {
 terminal2 = true;
 }
 left = false;
 }
 }
 }
 if (count == num - 1 && hORc == HUO && terminal1 && terminal2) {
 return true;
 }
 if (count == num - 1 && hORc == CHONG && ((terminal1 && !terminal2) || (!terminal1 && terminal2))) {
 return true;
 }
 count = 1;
 terminal1 = false;
 terminal2 = false;
 /**
 *
 * 左上右下
 *
 */
 for (i = 1; i < num; ++i) {
 if ((x + i) < BOARD_SIZE && (y + i) < BOARD_SIZE) {
 if (board[x + i][y + i] == f && rdown)
 count++;
 else {
 if (board[x + i][y + i] == 0 && rdown) {
 terminal1 = true;
 }
 rdown = false;
 }
 }
 if ((x - i) >= 0 && (y - i) >= 0) {
 if (board[x - i][y - i] == f && lup)
 count++;
 else {
 if (board[x - i][y - i] == 0 && lup) {
 terminal2 = true;
 }
 lup = false;
 }
 }
 }
 if (count == num - 1 && hORc == HUO && terminal1 && terminal2) {
 return true;
 }
 if (count == num - 1 && hORc == CHONG && ((terminal1 && !terminal2) || (!terminal1 && terminal2))) {
 return true;
 }
 count = 1;
 terminal1 = false;
 terminal2 = false;
 /**
 *
 * 右上左下
 *
 */
 for (i = 1; i < num; ++i) {
 if ((x + i) < BOARD_SIZE && (y - i) >= 0) {
 if (board[x + i][y - i] == f && rup)
 count++;
 else {
 if (board[x + i][y - i] == 0 && rup) {
 terminal1 = true;
 }
 rup = false;
 }
 }
 if ((x - i) >= 0 && (y + i) < BOARD_SIZE) {
 if (board[x - i][y + i] == f && ldown)
 count++;
 else {
 if (board[x - i][y + i] == 0 && ldown) {
 terminal2 = true;
 }
 ldown = false;
 }
 }
 }
 if (count == num - 1 && hORc == HUO && terminal1 && terminal2) {
 return true;
 }
 if (count == num - 1 && hORc == CHONG && ((terminal1 && !terminal2) || (!terminal1 && terminal2))) {
 return true;
 }

 return false;
 }

 public void init() throws Exception {
 table = ImageIO.read(new File("image/board.jpg"));
 black = ImageIO.read(new File("image/black.gif"));
 white = ImageIO.read(new File("image/white.gif"));
 selected = ImageIO.read(new File("image/selected.gif"));

 for (int i = 0; i < BOARD_SIZE; ++i) {
 for (int j = 0; j < BOARD_SIZE; ++j) {
 board[i][j] = 0;
 computerScore[i][j] = 0;
 }
 }
 chessBoard.setPreferredSize(new Dimension(TABLE_WIDTH, TABLE_HEIGHT));

 chessBoard.addMouseListener(new MouseAdapter() {
 public void mouseClicked(MouseEvent e) {
 int xPos = (int) ((e.getX() - X_OFFSET) / RATE);
 int yPos = (int) ((e.getY() - Y_OFFSET) / RATE);
 // System.out.println("1 " + xPos + " " + yPos);
 if (isRun(xPos, yPos)) {
 flagGamer = isWin(1, xPos, yPos);
 board[xPos][yPos] = 1;
 chesscou++;
 // do //电脑下棋,随机
 // {
 // comx = (rand.nextInt(535) - X_OFFSET) / RATE;
 // comy = (rand.nextInt(536) - Y_OFFSET) / RATE;
 // } while (!isRun(comx, comy));
 if (chesscou == (BOARD_SIZE * BOARD_SIZE)) {
 JOptionPane.showMessageDialog(null, "不相上下!!!\n再来一盘吧!!!", "结束", JOptionPane.ERROR_MESSAGE);
 initto();
 } else {
 Computer_AI(); // 电脑下棋,AI算法
 chesscou++;
 // System.out.println("2 " + comx + " " + comy);
 flagComputer = isWin(2, comx, comy);
 board[comx][comy] = 2;
 computerX = comx;
 computerY = comy;
 }
 }
 chessBoard.repaint();
 if (flagGamer) {
 JOptionPane.showMessageDialog(null, "厉害厉害!!!\n你赢了!!!", "结束", JOptionPane.ERROR_MESSAGE);
 initto();
 } else if (flagComputer) {
 JOptionPane.showMessageDialog(null, "哈哈哈哈!!!\n你输了!!!", "结束", JOptionPane.ERROR_MESSAGE);
 initto();
 }
 }

 public void mouseExited(MouseEvent e) {
 selectedX = -1;
 selectedY = -1;
 chessBoard.repaint();
 }
 });
 chessBoard.addMouseMotionListener(new MouseMotionAdapter() {
 public void mouseMoved(MouseEvent e) {
 selectedX = (e.getX() - X_OFFSET) / RATE;
 selectedY = (e.getY() - Y_OFFSET) / RATE;

 chessBoard.repaint();
 }
 });
 f.add(chessBoard);
 f.setCursor(new Cursor(Cursor.HAND_CURSOR));
 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 f.setResizable(false);
 f.pack();
 f.setVisible(true);
 }

 public static void main(String[] args) throws Exception {
 Game game = new Game();
 game.init();
 }

 @SuppressWarnings("serial")
 class ChessBoard extends JPanel {
 public void paint(Graphics g) {
 g.drawImage(table, 0, 0, null);
 if (selectedX >= 0 && selectedY >= 0) {
 g.drawImage(selected, selectedX * RATE + X_OFFSET, selectedY * RATE + Y_OFFSET, null);
 }
 if (computerX >= 0 && computerY >= 0) {
 g.drawImage(selected, computerX * RATE + X_OFFSET, computerY * RATE + Y_OFFSET, null);
 }
 for (int i = 0; i < BOARD_SIZE; ++i) {
 for (int j = 0; j < BOARD_SIZE; ++j) {
 if (board[i][j] == 1) {
 g.drawImage(black, i * RATE + X_OFFSET, j * RATE + Y_OFFSET, null);
 }
 if (board[i][j] == 2) {
 g.drawImage(white, i * RATE + X_OFFSET, j * RATE + Y_OFFSET, null);
 }
 }
 }
 }
 }
}

class ChessXY {
 int x;
 int y;

 public ChessXY(int x, int y) {
 this.x = x;
 this.y = y;
 }
}

更多精彩游戏,请参考专题《java经典小游戏》

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • java实现斗地主游戏

    感想: 第一次写博客,感觉编辑器挺复杂厉害的,感觉自己的内容挺简单的.有什么问题请多多指教! 思路: 1.创建一个扑克牌的实体类Poker,设置了四个参数:花色.数字.牌值(判断大小).是否地主牌,实现getset方法和构造方法: 2.创建一个玩家的实体类Player,设置了四个参数: 初始牌集合,排序后牌集合,牌值集合,是否地主,实现getset方法和构造方法: 3.洗牌:循环嵌套花色数组跟数字数组生成52个Poker,手动加入大小王Poker,放进map(int,Poker)里面,利用Col

  • java实现flappy Bird小游戏

    本文实例为大家分享了java实现flappy Bird游戏的具体代码,供大家参考,具体内容如下 整个游戏由3个类构成.Bird类,Pipe类,stage类 第一步:首先写一个Bird类 //鸟类 public class Bird { private int flyHeight;//飞行高度 private int xpos;//距离y轴(窗口左边缘)的位置, public static int Up=1;//向上飞 public static int Down=-1;//向下飞 public

  • Java实现的打地鼠小游戏完整示例【附源码下载】

    本文实例讲述了Java实现的打地鼠小游戏.分享给大家供大家参考,具体如下: 这里涉及到java线程和GUI的相关知识,一个简单的java小游戏打地鼠,有兴趣的朋友可以优化一下.先来看看运行效果: 具体代码: Mouse.java: import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Image; import java.awt.Toolkit; import java.awt

  • java连连看游戏菜单设计

    本文实例为大家分享了java连连看游戏菜单的具体实现代码,供大家参考,具体内容如下 先写GUI. 首先初始化框架,菜单,按钮,需要把菜单和按钮都添加在框架中.注意添加的顺序,首先要设置菜单,再设置框架,再设置按钮,如果交换了设置菜单和框架的顺序,会导致菜单显示不出,被框架挡住.对菜单设置了三个选项,第一个选项有五个下拉按键,用循环添加,第二个和第三个选项的下拉按键直接添加. GUI代码如下: package gui; import java.awt.Font; import javax.swin

  • java实现猜拳游戏

    本文实例为大家分享了java实现猜拳游戏的具体代码,供大家参考,具体内容如下 package com.farsight.session7; import java.util.Scanner; /** * 根据输入的数字,判断数组strs的值 然后进行逻辑判断 */ public class 猜拳 { public static void main(String[] args) { String[] strs = { "石头", "剪刀", "布"

  • java实现简单扫雷小游戏

    本文实例为大家分享了java实现扫雷游戏的具体代码,供大家参考,具体内容如下 import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.GridLayout; import java.awt.Insets; import java.awt.Label; import java.awt.event.ActionEvent; import java.awt.event

  • java实现24点游戏

    游戏规则 从扑克中每次取出4张牌.使用加减乘除,第一个能得出24者为赢.(其中,J代表11,Q代表12,K代表13,A代表1),按照要求编程解决24点游戏. 基本要求 随机生成4个代表扑克牌牌面的数字字母,程序自动列出所有可能算出24的表达式 列出表达式无重复 用户初始生命值为一给定值(比如3),初始分数为0.随机生成4个代表扑克牌牌面的数字或字母,由用户输入包含这4个数字或字母的运算表达式(可包含括号),如果表达式计算结果为24则代表用户赢了此局. 使用计时器要求用户在规定时间内输入表达式,如

  • 小伙熬夜用Java重现经典超级马里奥代码实例

    说起Java,很多人都想问,Java这么火但是Java能干什么呢?Java主要是做企业级的应用开发,其实Java还可以做游戏开发,Java不仅开发过电脑端的游戏,手游也有开发过,经典的游戏有很多,比如<我的世界>.<吃豆>等等,今天小编来分享一个用Java开发超级马里奥. 游戏界面展示: 游戏代码如下: 以上所述是小编给大家介绍的Java重现经典超级马里奥详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的.在此也非常感谢大家对我们网站的支持!

  • Java Swing实现扫雷小游戏

    swing设计扫雷心得,供大家参考,具体内容如下 最近学习swing学习之余做了一个小游戏:扫雷 1.前期设计 2.实现 其实完成这个游戏的核心就在于对数组的操纵,下面贴主要代码Main.java: package first; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.GridLayout; import java.awt.Image; import java.

  • Java实现Flappy Bird游戏源码

    本文实例为大家分享了Java实现Flappy Bird游戏的具体代码,供大家参考,具体内容如下 1.首先在mainActivity.xml中放置一个View,ID为viewDraw 2.开始编程,程序中自定义一个View类的子类,与viewDraw关联,程序除了放置如一个view控件,没有其他控件,程序上面的所有图片都是通过控制canvas画图实现 3.游戏是依据flappybird的游戏过程重新写的算法,功能与原版游戏相似,可能有些地方不足,完全是学习练习编程而已,做的不好见谅 4.原图片大小

随机推荐