Java版AI五子棋游戏
作者:elims小熊
这篇文章主要为大家详细介绍了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经典小游戏》
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。