流程图
包截图
GUI界面
主菜单界面
运行五子棋程序,出现开始界面,如下图所示
代码如下:
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
import javafx.stage.Stage;
public class BeginStage extends Application {
final Button btBeginGame = new Button("开始游戏");
final Button btQuitGame = new Button("退出游戏");
Pane pane1 = new Pane();//开始面板
Scene scene1 = new Scene(pane1);//开始界面
Stage stage1 = new Stage();//游戏界面
public BeginStage(){
//设置开始界面
//绑定“开始游戏”的位置
btBeginGame.layoutYProperty().bind(pane1.heightProperty().divide(1.1));
btBeginGame.layoutXProperty().bind(pane1.widthProperty().divide(4));
btBeginGame.setScaleX(1.5);
btBeginGame.setScaleY(1.5);
btBeginGame.setStyle("-fx-background-radius:15;");
//绑定“退出游戏”的位置
btQuitGame.layoutYProperty().bind(pane1.heightProperty().divide(1.1));
btQuitGame.layoutXProperty().bind(pane1.widthProperty().divide(1.58));
btQuitGame.setScaleX(1.5);
btQuitGame.setScaleY(1.5);
btQuitGame.setStyle("-fx-background-radius:15;");
//设置开始界面的背景图片
ImageView beginBack = new ImageView(new Image(getClass().getResourceAsStream("sample/5.png")));
beginBack.fitHeightProperty().bind(pane1.heightProperty());
beginBack.fitWidthProperty().bind(pane1.widthProperty());
pane1.getChildren().addAll(beginBack,btBeginGame,btQuitGame);
stage1.setTitle("五子棋");
stage1.setScene(scene1);
//开始界面按钮添加事件处理
btBeginGame.setOnAction(e -> {
ChooseStage chooseStage = new ChooseStage();
chooseStage.stage.show();
stage1.close();
});
btQuitGame.setOnAction(e ->{
stage1.close();
}
);
}
public void start(Stage stage){
BeginStage beginStage = new BeginStage();
beginStage.stage1.show();
}
}
模式选择界面
点击开始游戏后,出现主菜单,以及对战选项,如下图所示
效果展示
代码如下:
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
public class ChooseStage {
private Button btDouble = new Button("双人对战");
private Button btOne = new Button("人机对战");
private Button btNet = new Button("联机对战");
private Button btServer = new Button("创建服务器");
private Button btQuit = new Button("返回");
ImageView backGround = new ImageView(new Image(getClass().getResourceAsStream("sample/52.jpg")));
private Pane pane = new Pane();
public Stage stage = new Stage();
Scene scene = new Scene(pane);
public ChooseStage(){
pane.getChildren().addAll(backGround,btDouble,btNet,btOne,btServer,btQuit);
backGround.fitHeightProperty().bind(pane.heightProperty());
backGround.fitWidthProperty().bind(pane.widthProperty());
btDouble.setLayoutX(300);
btDouble.setLayoutY(300);
btDouble.setScaleX(1.3);
btDouble.setScaleY(1.3);
btNet.setLayoutX(300);
btNet.setLayoutY(360);
btNet.setScaleX(1.3);
btNet.setScaleY(1.3);
btOne.setLayoutX(300);
btOne.setLayoutY(420);
btOne.setScaleX(1.3);
btOne.setScaleY(1.3);
btServer.setLayoutX(293);
btServer.setLayoutY(480);
btServer.setScaleX(1.3);
btServer.setScaleY(1.3);
btQuit.setLayoutX(313);
btQuit.setLayoutY(540);
btQuit.setScaleX(1.3);
btQuit.setScaleY(1.3);
btDouble.setOnAction(event -> {
});
btNet.setOnMouseClicked(event -> {
});
btOne.setOnMouseClicked(event -> {
});
btQuit.setOnMouseClicked(event -> {
stage.close();
BeginStage beginStage = new BeginStage();
beginStage.stage1.show();
});
btDouble.setOnMouseClicked(event -> {
});
stage.setScene(scene);
stage.setTitle("五子棋");
stage.setResizable(false);
}
}
棋盘初始化
对原paint代码进行覆盖,进行导入背景图、画出棋盘线条、画出棋子、标出最新下的棋子的位置等操作
代码如下:
计算出每个格子的边长,画出横线纵线,画出棋盘,并表明棋盘中的五点
原始代码为利用java工具画出棋子原型,再对棋子进行填充,代码如下
由于运行之后棋子边界并不光滑,视觉效果不好因此改进代码如下
利用棋子图片原型,直接将图面贴至棋盘,使视觉效果更佳
对战界面选项设置
首先创建游戏界面窗口和菜单栏,并创建菜单栏中的“选项”菜单,把“重玩一盘”、“玩家1先手”、“玩家2先手”加入“选项”下拉项中
处理鼠标点击事件
利用鼠标监听事件e交替监听玩家一与玩家二的落子情况,分别下出黑子与白字
public void mouseClicked(MouseEvent e){
//鼠标点击引发下棋事件
if(flag) {
play(e);
flag=false;
}
else {
play2(e);
flag=true;
}
}
人机对战
机器落子
机器落子,采用五元组评分算法,对处于空白处的棋位进行判定,最后判断分数最高的棋子位置.
for(int i = 0; i < 15; i++){
for(int j = 0; j < 15; j++){
if(chessboard[i][j] == 0 && score[i][j] > maxScore){
goalX = i;
goalY = j;
maxScore = score[i][j];
}
}
}
由于考虑到在下棋子第一步时,人类落子后周围八个位置的分值皆相同,防止出现机器人每次在人类落子之后落子位置总是相同,因此进行如下改进:若是有多个棋子位置分数相同,则相应位置储存再数组中,随机抽取一个位置进行落子
五元组评分算法(通过对每一个位置进行评分,落子在分数最高的位置)
//既有人类落子,又有机器落子,判分为0
if(humanChessmanNum > 0 && machineChessmanNum > 0){
return 0;
}
//2.全部为空,没有落子,判分为7
if(humanChessmanNum == 0 && machineChessmanNum == 0){
return 7;
}
//3.机器落1子,判分为35
if(machineChessmanNum == 1){
return 35;
}
//4.机器落2子,判分为800
if(machineChessmanNum == 2){
return 800;
}
//5.机器落3子,判分为15000
if(machineChessmanNum == 3){
return 15000;
}
//6.机器落4子,判分为800000
if(machineChessmanNum == 4){
return 800000;
}
//7.人类落1子,判分为15
if(humanChessmanNum == 1){
return 15;
}
//8.人类落2子,判分为400
if(humanChessmanNum == 2){
return 400;
}
//9.人类落3子,判分为1800
if(humanChessmanNum == 3){
return 1800;
}
//10.人类落4子,判分为100000
if(humanChessmanNum == 4){
return 100000;
}
双人对战
方法``一
(基本操作同上)
判断胜利的条件(八个方向)
方法二(说明:由于一开始用swing写的棋子以及界面视觉效果不佳,因此考虑尝试采用javafx编写双人对战的代码,因为javafx落子时,可以直接将棋子设置为一个按钮,点击后不设置操作,相比于swing直接画棋子来说,视觉效果要好一点,但后期操作后可以将网上扣取的图片作为棋子利用swing贴在棋盘上,统一操作后采用了方法一)
判断胜利条件基本相同,稍有不同的地方在于界面的建立