Main主类:

背景图片和音乐就不传了

package application;import java.util.Optional;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TextArea;
import javafx.scene.control.ToggleGroup;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.scene.text.Font;/* ----------------------* 南昌大学 计科142级 周天钜毕业设计 基于α-β剪枝树的五子棋人机博弈系统完成时间 2018.4.1------------------------*/public class Main extends Application {public static Board[][] board = new Board[14][14]; // 绘制棋盘 大小14X14public static boolean AIPlay = true; // 为false为人人对战,为true时为和电脑下棋public static boolean AIToken = false; // 为false电脑执白,为true电脑执黑public static char whoseTurn = ' '; // 判断是哪方下棋,在后面的代码中会先置whoseTurn为'B'即默认为黑棋先下public static TextArea textArea = new TextArea(); // 文本域 输出消息用  public static Circle[][] arrayCircle = new Circle[14][14];// 将棋子存入arrayCircle中,便于后面的重新开始及悔棋操作public static int step = 0; // 用于标记当前落子的步数public static AI robot = new AI(); // AI类private Image image = new Image("timg.jpg"); // 背景图片private Media media = new Media(getClass().getClassLoader().getResource("BGM.mp3").toString());private Button btSet = new Button("游戏设置");private Button btStart = new Button("开始游戏");private Button btRegret = new Button("悔    棋");private Button btSurrender = new Button("认    输");private Button btExit = new Button("结束游戏");// 弹出式窗口,分别为点击游戏设置、游戏投降即退出游戏时弹出一个确认窗口private Alert startConfirm = new Alert(AlertType.CONFIRMATION, "该局对战尚未结束,是否开始新游戏?");private Alert setConfirm = new Alert(AlertType.INFORMATION);private Alert surrenderConfirm = new Alert(AlertType.CONFIRMATION, "是否认输?");private Alert exitConfirm = new Alert(AlertType.CONFIRMATION, "是否退出游戏?");private Alert winner = new Alert(AlertType.INFORMATION);@Override // 主面板public void start(Stage primaryStage) {try {// 背景图片Pane pane = new Pane();pane.getChildren().add(new ImageView(image));//背景音乐MediaPlayer mediaPlayer = new MediaPlayer(media);mediaPlayer.setVolume(30);mediaPlayer.setCycleCount(MediaPlayer.INDEFINITE);mediaPlayer.setAutoPlay(true);//初始化棋盘GridPane gridPane = new GridPane();for (int i = 0; i < 14; i++)for (int j = 0; j < 14; j++)gridPane.add(board[i][j] = new Board(i, j), i, j);// 把棋盘 放在pane中间gridPane.setLayoutX(150);gridPane.setLayoutY(30);// 绘制按钮 添加到VBOX中 VBOX在后续会添加到Pane的左侧VBox vBox = new VBox(50);vBox.setPadding(new Insets(20, 20, 20, 20));vBox.setLayoutY(100);vBox.getChildren().addAll(btSet, btStart, btRegret, btSurrender, btExit);// 游戏设置按钮btSet.setOnAction(e -> {// 点击 游戏设置按钮 弹出一个新的面板 游戏的所有设置在此面板中调节// 只允许在游戏未开始时进行设置if (whoseTurn == ' ') {Stage settingStage = new Stage();Pane settingPane = new Pane();ToggleGroup group1 = new ToggleGroup();// group1对应radioButton1、2// 对应label1ToggleGroup group2 = new ToggleGroup();ToggleGroup group3 = new ToggleGroup();Label label1 = new Label("对战模式");Label label2 = new Label("人机对战设置");Label label3 = new Label("游戏难度");label1.setLayoutX(30);label1.setLayoutY(15);label2.setLayoutX(30);label2.setLayoutY(100);label3.setLayoutX(30);label3.setLayoutY(190);// 添加单选按钮 这一块为对战模式设置 默认为人人对战RadioButton rb1 = new RadioButton("人机对战");RadioButton rb2 = new RadioButton("人人对战");rb1.setLayoutX(50);rb1.setLayoutY(50);rb2.setLayoutX(200);rb2.setLayoutY(50);// 将rb1 rb2加入group中rb1.setToggleGroup(group1);rb2.setToggleGroup(group1);rb1.setSelected(true);Line line1 = new Line(0, 80, 350, 80);// 这一块为人机对战设置 默认为电脑执白RadioButton rb3 = new RadioButton("电脑执黑");RadioButton rb4 = new RadioButton("电脑执白");rb3.setLayoutX(50);rb3.setLayoutY(130);rb4.setLayoutX(200);rb4.setLayoutY(130);rb3.setToggleGroup(group2);rb4.setToggleGroup(group2);rb4.setSelected(true);Line line2 = new Line(0, 165, 350, 165);// 这一块为游戏难度设置RadioButton rb5 = new RadioButton("简单");RadioButton rb6 = new RadioButton("正常");RadioButton rb7 = new RadioButton("困难");rb5.setLayoutX(50);rb5.setLayoutY(220);rb6.setLayoutX(200);rb6.setLayoutY(220);rb7.setLayoutX(50);rb7.setLayoutY(250);rb5.setToggleGroup(group3);rb5.setSelected(true);rb6.setToggleGroup(group3);rb7.setToggleGroup(group3);Line line3 = new Line(0, 280, 350, 280);// 确认按钮与取消按钮Button confirm = new Button("确认");Button cancel = new Button("取消");confirm.setLayoutX(90);confirm.setLayoutY(315);cancel.setLayoutX(190);cancel.setLayoutY(315);// 添加按钮事件 点击确认将修改游戏参数 点击取消直接关闭设置窗口confirm.setOnAction(event -> {// 若选中第一个radioButton则为人机对战,否则为人人对战if (rb1.isSelected() == true) {AIPlay = true;rb1.setSelected(true);} else if (rb2.isSelected() == true) {AIPlay = false;rb2.setSelected(true);}// 若选中第三个按钮则为电脑执黑 ,否则为电脑执白if (rb3.isSelected() == true) {AIToken = true;rb3.setSelected(true);} else if (rb4.isSelected() == true) {AIToken = false;rb4.setSelected(true);}settingStage.close();});cancel.setOnAction(event -> {settingStage.close();});settingPane.getChildren().addAll(label1, rb1, rb2, line1, label2, rb3, rb4, line2, label3, rb5, rb6,rb7, line3, confirm, cancel);Scene settingScene = new Scene(settingPane);settingScene.getStylesheets().add(getClass().getResource("textStyle.css").toExternalForm());settingStage.setHeight(400);settingStage.setWidth(350);settingStage.setScene(settingScene);settingStage.setTitle("游戏设置");settingStage.setResizable(false); // 设置面板大小不可变settingStage.show();} else {setConfirm.setHeaderText(null);setConfirm.setContentText("请先结束这局游戏后再进行游戏设置!");setConfirm.showAndWait();}});// 游戏开始按钮 点击此按钮初始化棋盘开始游戏btStart.setOnAction(e -> {// 点击此按钮前whoseTurn=' '无法在棋盘上落子if (whoseTurn != ' ') {startConfirm.setTitle("开始游戏");startConfirm.setHeaderText(null);Optional<ButtonType> result = startConfirm.showAndWait();if (result.isPresent() && result.get() == ButtonType.OK)reSet();}reSet();});// 悔棋按钮btRegret.setOnAction(e -> {// 若为人机对战 则点一次悔棋退两步 即电脑退一步 人退一步if (AIPlay == true && step > 2 && whoseTurn != ' ') {regret();regret();}// 若为人人对战则点一次悔棋退一步if (AIPlay == false && step > 1 && whoseTurn != ' ') {regret();}if (step % 2 == 0)// 若当前步数为奇数 则黑棋下 否则白棋下whoseTurn = 'B';else if (step % 2 == 1)whoseTurn = 'W';});// 投降按钮btSurrender.setOnAction(e -> {surrenderConfirm.setTitle("认输");surrenderConfirm.setHeaderText(null);if (whoseTurn == 'B') { // 如果当前是黑子下 认输时输出白棋获胜Optional<ButtonType> result = surrenderConfirm.showAndWait();// 点击确认按钮则认输if (result.isPresent() && result.get() == ButtonType.OK) {textArea.insertText(0, "白棋获胜!" + '\n' + '\n');winner.setContentText("白棋获胜!!!");winner.setHeaderText(null);winner.showAndWait();}} else if (whoseTurn == 'W') {Optional<ButtonType> result = surrenderConfirm.showAndWait();if (result.isPresent() && result.get() == ButtonType.OK) {textArea.insertText(0, "黑棋获胜!" + '\n' + '\n');winner.setContentText("黑棋获胜!!!");winner.setHeaderText(null);winner.showAndWait();}}whoseTurn = ' ';});// 游戏结束按钮btExit.setOnAction(e -> {exitConfirm.setTitle("退出游戏");exitConfirm.setHeaderText(null);Optional<ButtonType> result = exitConfirm.showAndWait();// 点击确认按钮则退出游戏if (result.isPresent() && result.get() == ButtonType.OK)System.exit(-1);});// 绘制文本框 文字大小为16号字体 规定最大宽度和最小高度 放在pane右侧textArea.setFont(new Font(16));textArea.setMaxWidth(315);textArea.setMinHeight(500);textArea.setLayoutX(860);textArea.setLayoutY(100);textArea.setEditable(false);textArea.insertText(0, "点击开始游戏进行游戏!" + '\n' + '\n');pane.getChildren().addAll(vBox, gridPane, textArea);Scene scene = new Scene(pane);// 使用buttonStyle中的按钮样式scene.getStylesheets().add(getClass().getResource("buttonStyle.css").toExternalForm());primaryStage.setScene(scene);primaryStage.setTitle("五子棋Demo");primaryStage.setResizable(false); // 设置棋盘大小不可变primaryStage.show();} catch (Exception e) {e.printStackTrace();}}// 重置棋盘函数public void reSet() {textArea.insertText(0, "游戏开始!" + '\n' + '\n');for (int i = 0; i < 14; i++)for (int j = 0; j < 14; j++) {board[i][j].getChildren().remove(arrayCircle[i][j]);board[i][j].token = ' ';}whoseTurn = 'B';step = 0;// 若为人机对战且电脑执黑子 电脑第一子落在行7竖7if (AIToken == true) {board[6][6].setToken(whoseTurn, 6, 6, true);whoseTurn = 'W';}}// --------------悔棋函数-------------------public void regret() {for (int i = 0; i < 14; i++) {for (int j = 0; j < 14; j++) {if (board[i][j].thisStep == step) { // 若棋子当前步数为所下步数则清除该棋子board[i][j].getChildren().remove(arrayCircle[i][j]);board[i][j].token = ' ';if (whoseTurn == 'W' && AIPlay == false)// 若下一步为白棋下即当前是黑棋下完,则在文本框输出黑方悔棋textArea.insertText(0, "黑方悔棋!" + '\n' + '\n');else if (whoseTurn == 'B' && AIPlay == false)textArea.insertText(0, "白方悔棋!" + '\n' + '\n');}}}step--;}public static void main(String[] args) {launch(args);}
}

MyCircle棋子类

package application;import javafx.scene.effect.DropShadow;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;public class MyCircle extends Circle{MyCircle(){       }MyCircle(int radius, Color color){//设置半径 颜色 以及阴影效果super.setRadius(radius);super.setStroke(color);super.setFill(color);DropShadow ds = new DropShadow();ds.setOffsetX(3.0);super.setEffect(ds);}
}

Board棋盘类

package application;import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.layout.Pane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.paint.Color;public class Board extends Pane {public char token = ' '; // token B 表示black黑棋 W表示whitepublic int thisStep;// 用于标记当前落子步数private Alert winner = new Alert(AlertType.INFORMATION);private Media moveSong = new Media(getClass().getClassLoader().getResource("put.mp3").toString());private Media winSong = new Media(getClass().getClassLoader().getResource("win.wav").toString());private MyCircle circle = null;// 构造方法 每个格子大小为15x15 为每个格子注册一个鼠标事件public Board(){}public Board(int x, int y) {setStyle("-fx-border-color:black");this.setPrefSize(50, 50);this.setOnMouseClicked(e -> {handleMouseClick(x, y);});}// 鼠标点击事件 判断是否获胜 若没有人获胜 则改变棋子颜色继续下子public void handleMouseClick(int x, int y) {// whoseTure一开始为空 当点击开始游戏按钮时置为'B' 即黑棋开始下棋 进入下面的if分支// 若不点击开始游戏按钮,即whoseTurn为空 则无法进入下面的if分支 即无法开始游戏if (token == ' ' && Main.whoseTurn != ' ' && Main.AIPlay == false) {// 此处为当人下了一子后 若AIPlay为true 电脑开始下棋 即人机对战 否则为人人对战setToken(Main.whoseTurn, x, y,true);Main.textArea.insertText(0, "估值:" + Main.robot.Evaluate(x, y, Main.whoseTurn) + " ");if (judge(Main.whoseTurn, x, y) == true)printWinner();elseMain.whoseTurn = (Main.whoseTurn == 'B') ? 'W' : 'B'; // 改变落子者MediaPlayer mediaPlayer = new MediaPlayer(moveSong);mediaPlayer.setVolume(50);mediaPlayer.play();}//若AIPlay为True 则为人机对战if (token == ' ' && Main.whoseTurn != ' ' && Main.AIPlay == true) {if (Main.whoseTurn != ' ') {setToken(Main.whoseTurn, x, y,true);Main.textArea.insertText(0, "估值:" + Main.robot.Evaluate(x, y, Main.whoseTurn) + " ");if (judge(Main.whoseTurn, x, y) == true)printWinner();elseMain.whoseTurn = (Main.whoseTurn == 'B') ? 'W' : 'B'; // 改变落子者MediaPlayer mediaPlayer = new MediaPlayer(moveSong);mediaPlayer.setVolume(50);mediaPlayer.play();}//若whoseTurn不为空 即未分出胜负,则执行搜索函数,根据人下的子,搜索AI的下一步落子if (Main.whoseTurn != ' ')Main.robot.search(x,y);           }}// setToken函数 若token为B则在棋盘上鼠标点击位置绘制黑子 为W则绘制白子public void setToken(char c, int x, int y,boolean flag) {token = c;MyCircle circle = null;int row = x + 1, column = y + 1;// 行数 列数Main.step++;Main.board[x][y].thisStep = Main.step;// 落一子步数+1 thisStep用于判断悔棋的操作if (token == 'B') {circle = new MyCircle(20, Color.BLACK);// 在textArea上输出相应的落子位置 具体效果为——步数:1 黑棋: 行 3, 列 10if(flag==true)Main.textArea.insertText(0, "步数:" + Main.step + " 黑棋:行" + column + ",列" + row + '\n' + '\n');} else if (token == 'W') {circle = new MyCircle(20, Color.WHITE);if(flag==true)Main.textArea.insertText(0, "步数:" + Main.step + " 白棋:行" + column + ",列" + row + '\n' + '\n');}// 将圆心绑定到落子的方格中间circle.centerXProperty().bind(Main.board[x][y].widthProperty().divide(2));circle.centerYProperty().bind(Main.board[x][y].heightProperty().divide(2));Main.board[x][y].getChildren().add(circle);Main.board[x][y].token = c;Main.arrayCircle[x][y] = circle;}/** -------胜 负 判 断函数----------*/public boolean judge(char whoseTurn, int x, int y) {boolean flag = false;if (checkCount(whoseTurn, x, y, 1, 0) >= 5)flag = true;else if (checkCount(whoseTurn, x, y, 0, 1) >= 5)flag = true;else if (checkCount(whoseTurn, x, y, 1, -1) >= 5)flag = true;else if (checkCount(whoseTurn, x, y, 1, 1) >= 5)flag = true;return flag;}// 判断连子函数public int checkCount(char whoseTurn, int x, int y, int xChange, int yChange) {int count = 1;int tempX = xChange;int tempY = yChange;while (x + xChange >= 0 && x + xChange < 14 && y + yChange >= 0 && y + yChange < 14&& whoseTurn == Main.board[x + xChange][y + yChange].token) {count++;if (xChange != 0)xChange++;if (yChange != 0) {if (yChange > 0)yChange++;elseyChange--;}}xChange = tempX;yChange = tempY;while (x - xChange >= 0 && x - xChange < 14 && y - yChange >= 0 && y - yChange < 14&& whoseTurn == Main.board[x - xChange][y - yChange].token) {count++;if (xChange != 0)xChange++;if (yChange != 0) {if (yChange > 0)yChange++;elseyChange--;}}return count;}// 在文本域输出是谁获胜 若无人获胜则改变下棋方继续游戏public void printWinner() {//输出胜利音效MediaPlayer mediaPlayer = new MediaPlayer(winSong);mediaPlayer.setVolume(50);mediaPlayer.play();if (Main.whoseTurn == 'B') {Main.whoseTurn = ' ';Main.textArea.insertText(0, "黑棋获胜!点击开始游戏进行新对战!" + '\n' + '\n');winner.setContentText("黑棋获胜!!!");winner.setHeaderText(null);winner.showAndWait();} else if (Main.whoseTurn == 'W') {Main.whoseTurn = ' ';Main.textArea.insertText(0, "白棋获胜!点击开始游戏进行新对战!" + '\n' + '\n');winner.setContentText("白棋获胜!!!");winner.setHeaderText(null);winner.showAndWait();}        }
}

AI类

package application;public class AI {int[][] temp = new int[14][14];int AIx = 0, AIy = 0;boolean level = true;// level为true 则该层是max层 若level为false则该层是min层public AI() {}public int getEvaluate(int x, int y, char whoseTurn) {int score = 0; // 落子权值score = evaluate(x, y, whoseTurn) + evaluate(x, y, (char) (153 - whoseTurn));return score;}public int Evaluate(int x, int y, char whoseTurn) {// 第一个getValue为当前落子的人的估值 第二个getValue是若对手在此落子的估值 (可理解为防守估值)// 153为unicode编码 153-'B'='W' 153-'W'='B'return evaluate(x, y, whoseTurn) + evaluate(x, y, (char) (153 - whoseTurn));}//估值函数 棋型判断private int evaluate(int x, int y, char whoseTurn) {int value = 0;for (int i = 1; i <= 8; i++) { // 8个方向// 活四 01111* *代表当前空位置 0代表其他空位置 下同if (getLine(x, y, i, -1) == whoseTurn && getLine(x, y, i, -2) == whoseTurn&& getLine(x, y, i, -3) == whoseTurn && getLine(x, y, i, -4) == whoseTurn&& getLine(x, y, i, -5) == ' '){value += 300000;if((Main.AIToken==false&&whoseTurn=='W')||(Main.AIToken==true&&whoseTurn=='B'))value+=100000;//避免出现当电脑和人都出现四连子的时候电脑去拦截而不是直接获胜的选择}// 死四A 21111*if (getLine(x, y, i, -1) == whoseTurn && getLine(x, y, i, -2) == whoseTurn&& getLine(x, y, i, -3) == whoseTurn && getLine(x, y, i, -4) == whoseTurn&& (getLine(x, y, i, -5) == (char) (153 - whoseTurn) || getLine(x, y, i, -5) == 'E')){value += 250000;if((Main.AIToken==false&&whoseTurn=='W')||(Main.AIToken==true&&whoseTurn=='B'))value+=100000;}// 死四B 111*1if (getLine(x, y, i, -1) == whoseTurn && getLine(x, y, i, -2) == whoseTurn&& getLine(x, y, i, -3) == whoseTurn && getLine(x, y, i, 1) == whoseTurn) {value += 240000;if((Main.AIToken==false&&whoseTurn=='W')||(Main.AIToken==true&&whoseTurn=='B'))value+=100000;}            // 死四C 11*11 if (getLine(x, y, i, -1) == whoseTurn && getLine(x, y, i, -2) == whoseTurn&& getLine(x, y, i, 1) == whoseTurn && getLine(x, y, i, 2) == whoseTurn) {value += 115000; //这里因为顺序关系会计算两遍value 实际value是115000*2=230000if((Main.AIToken==false&&whoseTurn=='W')||(Main.AIToken==true&&whoseTurn=='B'))value+=50000;}// 活三 近3位置 0111*0if (getLine(x, y, i, -1) == whoseTurn && getLine(x, y, i, -2) == whoseTurn&& getLine(x, y, i, -3) == whoseTurn) {if (getLine(x, y, i, 1) == ' '&&getLine(x, y, i, -4) == ' ') //若两边都有空位 value += 30000;else if ((getLine(x, y, i, 1) == (char) (153 - whoseTurn) || getLine(x, y, i, 1) == 'E')&&(getLine(x, y, i, -4) == (char) (153 - whoseTurn) || getLine(x, y, i, -4) == 'E')) value -= 100;elsevalue+=3000;}// 活三 远3位置 1110*if (getLine(x, y, i, -1) == ' ' && getLine(x, y, i, -2) == whoseTurn && getLine(x, y, i, -3) == whoseTurn&& getLine(x, y, i, -4) == whoseTurn){if(getLine(x, y, i, 1)==' '&&getLine(x, y, i, -5)==' '){if(Main.whoseTurn==whoseTurn)//可以理解为进攻方value+=28000;else//否则防守方的估值不高value+=2850;}else{if(Main.whoseTurn==whoseTurn)value+=2800;elsevalue+=1400;}}// 死三 11*1if (getLine(x, y, i, -1) == whoseTurn && getLine(x, y, i, -2) == whoseTurn&& getLine(x, y, i, 1) == whoseTurn) {if (getLine(x, y, i, -3) == ' ' && getLine(x, y, i, 2) == ' ') value += 29000;else if ((getLine(x, y, i, -3) == (char) (153 - whoseTurn) || getLine(x, y, i, -3) == 'E')&& (getLine(x, y, i, 2) == (char) (153 - whoseTurn) || getLine(x, y, i, 2) == 'E')) value -= 100;else value+=2900;}//10*11if (getLine(x, y, i, 1) == whoseTurn && getLine(x, y, i, 2) == whoseTurn&& getLine(x, y, i, -2) == whoseTurn && getLine(x, y, i, -1) == ' ') {if (getLine(x, y, i, 3) == ' '){if(Main.whoseTurn==whoseTurn)value += 27000;elsevalue+=2750;}                  else if (getLine(x, y, i, 3) == (char) (153 - whoseTurn) || getLine(x, y, i, 3) == 'E'){if(Main.whoseTurn==whoseTurn)value+=2700;elsevalue+=1350;}}// 101*1if (getLine(x, y, i, 1) == whoseTurn && getLine(x, y, i, -1) == whoseTurn&& getLine(x, y, i, -3) == whoseTurn && getLine(x, y, i, -2) == ' ') {if (getLine(x, y, i, 2) == ' '){if(Main.whoseTurn==whoseTurn)value+=26000;elsevalue+=2650;}               else if (getLine(x, y, i, 2) == (char) (153 - whoseTurn) || getLine(x, y, i, 2) == 'E'){if(Main.whoseTurn==whoseTurn)value+=2600;elsevalue+=1300;}                  }// 1*011if (getLine(x, y, i, 2) == whoseTurn && getLine(x, y, i, 3) == whoseTurn&& getLine(x, y, i, -1) == whoseTurn && getLine(x, y, i, 1) == ' ') {if (getLine(x, y, i, -2) == ' ' && getLine(x, y, i, 4) == ' '){if(Main.whoseTurn==whoseTurn)value+=25000;elsevalue+=2550;}                    else{if(Main.whoseTurn==whoseTurn)value+=2500;elsevalue+=1250;}                   }// 011*0if (getLine(x, y, i, -1) == whoseTurn && getLine(x, y, i, -2) == whoseTurn) {if (getLine(x, y, i, -3) == ' ' && getLine(x, y, i, 1) == ' ')value += 6000;else if ((getLine(x, y, i, -3) == (char) (153 - whoseTurn) || getLine(x, y, i, -3) == 'E')&& (getLine(x, y, i, 1) == (char) (153 - whoseTurn) || getLine(x, y, i, 1) == 'E'))value -= 100;//两边都被堵了 估值-100 落子没有意义elsevalue += 600;}// 01*10if (getLine(x, y, i, -1) == whoseTurn && getLine(x, y, i, 1) == whoseTurn) {if (getLine(x, y, i, -2) == ' ' && getLine(x, y, i, 2) == ' ')value += 5000;else if ((getLine(x, y, i, -2) == (char) (153 - whoseTurn) || getLine(x, y, i, -2) == 'E')&& (getLine(x, y, i, 2) == (char) (153 - whoseTurn) || getLine(x, y, i, 2) == 'E'))value -= 100;elsevalue += 500;}// 110*if (getLine(x, y, i, -2) == whoseTurn && getLine(x, y, i, -3) == whoseTurn && getLine(x, y, i, -1) == ' ') {if (getLine(x, y, i, 1) == ' ' && getLine(x, y, i, -4) == ' ')value += 4000;else if ((getLine(x, y, i, -4) == (char) (153 - whoseTurn) || getLine(x, y, i, -4) == 'E')&& (getLine(x, y, i, 1) == (char) (153 - whoseTurn) || getLine(x, y, i, 1) == 'E'))value -= 100;elsevalue += 400;}//10*1if (getLine(x, y, i, -2) == whoseTurn && getLine(x, y, i, 1) == whoseTurn && getLine(x, y, i, -1) == ' ') {if (getLine(x, y, i, 2) == ' ' && getLine(x, y, i, -3) == ' ')value += 3500;else if ((getLine(x, y, i, -3) == (char) (153 - whoseTurn) || getLine(x, y, i, -3) == 'E')&& (getLine(x, y, i, 2) == (char) (153 - whoseTurn) || getLine(x, y, i, 2) == 'E'))value -= 100;elsevalue += 350;}// 1*if (getLine(x, y, i, -1) == whoseTurn) {if (getLine(x, y, i, 1) == ' ' && getLine(x, y, i, -2) == ' ')value += 200;else if ((getLine(x, y, i, 1) == (char) (153 - whoseTurn) || getLine(x, y, i, 1) == 'E')&& (getLine(x, y, i, -2) == (char) (153 - whoseTurn) || getLine(x, y, i, -2) == 'E'))value -= 100;elsevalue += 20;}// 10*if (getLine(x, y, i, -2) == whoseTurn && getLine(x, y, i, -1) == ' ') {if (getLine(x, y, i, 1) == ' ' && getLine(x, y, i, -3) == ' ')value += 150;else if ((getLine(x, y, i, 1) == (char) (153 - whoseTurn) || getLine(x, y, i, 1) == 'E')&& (getLine(x, y, i, -3) == (char) (153 - whoseTurn) || getLine(x, y, i, -3) == 'E'))value -= 100;elsevalue += 15;}// 100*if (getLine(x, y, i, -3) == whoseTurn && getLine(x, y, i, -2) == ' ' && getLine(x, y, i, -1) == ' ') {if (getLine(x, y, i, 1) == ' ' && getLine(x, y, i, -4) == ' ')value += 100;else if ((getLine(x, y, i, 1) == (char) (153 - whoseTurn) || getLine(x, y, i, 1) == 'E')&& (getLine(x, y, i, -4) == (char) (153 - whoseTurn) || getLine(x, y, i, -4) == 'E'))value -= 100;elsevalue += 10;}}
/*          // 活二的个数if (getLine(x, y, i, -1) == whoseTurn && getLine(x, y, i, -2) == whoseTurn&& getLine(x, y, i, -3) != (char) (153 - whoseTurn)&& getLine(x, y, i, 1) != (char) (153 - whoseTurn)) {numoftwo++;}// 其余散棋int numOfplyer = 0; // 因为方向会算两次?for (int k = -4; k <= 0; k++) { // ++++* +++*+ ++*++ +*+++ *++++int temp = 0;for (int l = 0; l <= 4; l++) {if (getLine(x, y, i, k + l) == whoseTurn) {temp++;} else if (getLine(x, y, i, k + l) == (char) (153 - whoseTurn)|| getLine(x, y, i, k+1) == 'E') {temp = 0;break;}}numOfplyer += temp;}value += numOfplyer * 15;if (numOfplyer != 0) {}if(numoftwo==1)value+=100;if (numoftwo >= 2) value += 3000;*/// 给棋盘的每个格子一个估值 越接近中心估值越高 越接近边界估值越低if ((x == 0 || x == 13) && y != 0 && y != 13)value += 1;else if (y == 0 || y == 13)value += 1;else if ((x == 1 || x == 12) && y != 1 && y != 12)value += 2;else if (y == 1 || y == 12)value += 2;else if ((x == 2 || x == 11) && y != 2 && y != 11)value += 3;else if (y == 2 || y == 11)value += 3;else if ((x == 3 || x == 10) && y != 3 && y != 10)value += 4;else if (y == 3 || y == 10)value += 4;else if ((x == 4 || x == 9) && y != 5 && y != 9)value += 5;else if (y == 4 || y == 9)value += 5;else if ((x == 5 || x == 8) && y != 6 && y != 8)value += 6;else if (y == 5 || y == 8)value += 6;elsevalue += 7;return value;}private char getLine(int x, int y, int i, int j) { // i:方向 j:相对x,y的顺序值// x,y:当前点switch (i) {case 1:x = x + j;break;case 2:x = x + j;y = y + j;break;case 3:y = y + j;break;case 4:x = x - j;y = y + j;break;case 5:x = x - j;break;case 6:x = x - j;y = y - j;break;case 7:y = y - j;break;case 8:x = x + j;y = y - j;}if (x < 0 || y < 0 || x > 13 || y > 13) { // 越界处理return 'E';// Error 越界}return Main.board[x][y].token;}// X Y为人下的子,电脑根据xy得到要下的子public void search(int x, int y) {if (Main.step == 1) {// 规定电脑落的第一颗子 跳过搜索 提高效率if (x >= 0 && x <= 7 && y >= 7 && y <= 14)Main.board[x + 1][y + 1].setToken(Main.whoseTurn, x + 1, y + 1, true);elseMain.board[x - 1][y - 1].setToken(Main.whoseTurn, x - 1, y - 1, true);Main.whoseTurn = (Main.whoseTurn == 'B') ? 'W' : 'B'; // 改变落子者} else {int val = 0;Alpha_Beta(0, -10000000, 10000000, x, y, Main.whoseTurn);for (int i = 0; i < 14; i++) {for (int j = 0; j < 14; j++) {if ((val < temp[i][j]) && Main.board[i][j].token == ' ') {val = temp[i][j];AIx = i;AIy = j;}}}Main.board[AIx][AIy].setToken(Main.whoseTurn, AIx, AIy, true);Main.textArea.insertText(0, "估值:" + Main.robot.Evaluate(AIx, AIy, Main.whoseTurn) + " ");if (Main.board[AIx][AIy].judge(Main.whoseTurn, AIx, AIy) == true)Main.board[AIx][AIy].printWinner();elseMain.whoseTurn = (Main.whoseTurn == 'B') ? 'W' : 'B';}}// negaMax模式的递归α-β剪枝树private int Alpha_Beta(int depth, int alpha, int beta, int x, int y, char whoseTurn) {if (depth == 3 || Main.board[x][y].judge(whoseTurn, x, y) == true) {temp[x][y] = Evaluate(x, y, whoseTurn);return Evaluate(x, y, whoseTurn);}for (int i = 0; i < 14; i++) {for (int j = 0; j < 14; j++) {if (Main.board[i][j].token != ' ')continue;Main.board[i][j].setToken(whoseTurn, i, j, false);whoseTurn = (whoseTurn == 'B') ? 'W' : 'B';int value = -Alpha_Beta(depth + 1, -beta, -alpha, i, j, whoseTurn);unMove(i, j);if (value > alpha) {if (value >= beta) {return beta;}}alpha = value;}}return alpha;}private void unMove(int i, int j) {Main.board[i][j].getChildren().remove(Main.arrayCircle[i][j]);Main.board[i][j].token = ' ';Main.step--;}
}

这段α-β剪枝树应该还有能改进的地方,只能做到搜索到3层,搜索5层的时候eclipse会卡死

CSS样式

#actiontarget {  -fx-fill: FIREBRICK;  -fx-font-weight: bold;  -fx-effect: dropshadow( gaussian , rgba(255.0,255.0,255.0,0.5) , 0.0,0.0,0.0,1.0 );
}  .button{
-fx-background-color:#d0d0d0;
-fx-background-radius: 5.0px;
-fx-text-fill:#fff;
-fx-pref-height: 30.0px;
-fx-pref-width: 100.0px;
-fx-font-size:16px;-fx-font-weight: bold;-fx-font-family:"微软雅黑";
}
.button:hover{
-fx-background-color:#ADADAD;
-fx-cursor:hand ;
}
.label {  -fx-font-size: 14.0px;  -fx-font-weight: bold;  -fx-text-fill: #333333;  -fx-effect: dropshadow( gaussian , rgba(255.0,255.0,255.0,0.5) , 0.0,0.0,0.0,1.0 );
}  #welcome-text {  -fx-font-size: 32.0px;  -fx-font-family: "Arial Black";  -fx-fill: #818181;  -fx-effect: innershadow( three-pass-box , rgba(0.0,0.0,0.0,0.7) , 6.0, 0.0 , 0.0 , 2.0 );
}  

JAVAFX基于α-β剪枝树的五子棋人机博弈相关推荐

  1. 基于QT的五子棋人机博弈问题设计与实现 文档+任务书+答辩PPT+演示视频+项目源码

    资源下载地址:https://download.csdn.net/download/sheziqiong/85948720 资源下载地址:https://download.csdn.net/downl ...

  2. 五子棋——人机博弈(Java实现)

    1引言 本文档是考试系统项目的内容汇总,其主要内容包括: 项目说明 需求分析 项目设计 编码与实现 测试说明 课程设计体会与总结 2项目说明 2.1项目要求 五子棋是全国智力运动会竞技项目之一,是一种 ...

  3. 基于人工神经网络的五子棋博弈(Details)

    感兴趣的朋友可以在git上查看该项目: https://github.com/jimth001/my-Gobang-game-base-AI-algorithm.git 研 究 报 告 作品名称 基于 ...

  4. 五子棋java程序=权值法_五子棋(人机对弈)——Java权值法五子棋博弈

    五子棋人机博弈 五子棋,人与人之间博弈,我们不用考虑太多,都是玩家自动思考. 但是如果我们要玩一个单机的五子棋,实现人机的对战,那么我就得"帮"电脑考虑下走哪步了. 实现的方法大概 ...

  5. 五子棋(人机对弈)——Java权值法五子棋博弈

    五子棋人机博弈 五子棋,人与人之间博弈,我们不用考虑太多,都是玩家自动思考. 但是如果我们要玩一个单机的五子棋,实现人机的对战,那么我就得"帮"电脑考虑下走哪步了. 实现的方法大概 ...

  6. 基于Alpha-Beta剪枝树的井字棋人机博弈实现

    1 Alpha-Beta剪枝树的简单介绍 Alpha-Beta剪枝的本质就是基于极小化极大算法的一种改进算法.因此先简单地介绍下极小化极大算法,这样有利于我们更好的理解Alpha-Beta剪枝算法. ...

  7. C++毕业设计——基于C+++EasyX+剪枝算法的能人机对弈的五子棋游戏设计与实现(毕业论文+程序源码)——五子棋游戏

    基于C+++EasyX+剪枝算法的能人机对弈的五子棋游戏设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于C+++EasyX+剪枝算法的能人机对弈的五子棋游戏设计与实现,文章末尾附有本毕业设 ...

  8. Python+PyQt5实现五子棋游戏(人机博弈+深搜+α-β剪枝)

    Python+PyQt5实现五子棋游戏(人机博弈+深搜+α-β剪枝) 一.问题描述 1.五子棋 五子棋是全国智力运动会竞技项目之一,是一种两人对弈的纯策略型棋类游戏. 五子棋的棋具与围棋通用,是一种传 ...

  9. 基于QT实现的alpha-beta剪枝算法搜索的象棋人机博弈游戏

    中国象棋是一个古老的而富有智慧的游戏,而中国象棋博弈程序是将计算机知识和中国象棋知识结合起来的一种新型的游戏方式.它以一种全新的人机博弈方式突破了以往传统象棋游戏只能人与人对战的限制,使得这个古老的游 ...

最新文章

  1. hibernate 继承映射
  2. 混合模型的推荐算法(ACM暑校-案例学习)
  3. 用HTML编写教学评估系统,在线教学质量评价系统的设计与实现
  4. linux访问windows共享目录开机自动挂载
  5. 【BZOJ4516】生成魔咒,后缀数组+Splay
  6. bianma 水平 技巧
  7. REX-Ray 了解
  8. wpa_supplicant配置
  9. 全球网络安全行业全景图与中国网络安全行业全景图-2022
  10. 红米note3总显示无服务器,红米note3死机了怎么办 具体解决措施【图文】
  11. IDEA 2019.1离线安装lombok
  12. Basketball Dribbling
  13. 运行veins示例步骤
  14. Python strip()方法
  15. 大数据 端到端_成为数据科学家的端到端指南
  16. flex布局属性的伸展、收缩、基准属性
  17. 实验3、顺序与选择结构
  18. 整理MAC下Eclipse的常用快捷键
  19. linux 文件修复工具,Linux环境下几个好用的文件恢复工具
  20. 已知圆心,半径,角度,求圆上的点坐标。

热门文章

  1. win7 host 中 vbox 虚拟机无法 attach USB device的问题
  2. 如何评价范冰新书《增长黑客》?
  3. Skippr – 轻量、快速的 jQuery 幻灯片插件
  4. 使用AD软件绘制PCB的过程
  5. The Moon and Sixpence摘抄
  6. Android日常开发问题总结:这些问题火候不够,随时变成删库跑路!
  7. Ceph Calamari安装问题汇总
  8. 使用teamviewer和向日葵时Visual studio等软件显示全白或者全黑的解决办法!
  9. 企业微信组织架构同步教程
  10. unity3d 鼠标点击事件处理 处理鼠标点击