首页
留言
关于
统计
友情链接
Search
1
java面试题05
271 阅读
2
java魔方矩阵
109 阅读
3
Java中的包
101 阅读
4
java中接口的作用
97 阅读
5
java中this关键字
69 阅读
随笔
笔记
计算机基础
JAVA
web前端
分享
经验
软件
其他
登录
/
注册
Search
标签搜索
JAVA
笔记
面试
五子棋
游戏
阿涛
累计撰写
23
篇文章
累计收到
9
条评论
首页
栏目
随笔
笔记
计算机基础
JAVA
web前端
分享
经验
软件
其他
页面
留言
关于
统计
友情链接
搜索到
1
篇与
游戏
的结果
2022-04-04
javafx实现五子棋游戏
设计一个五子棋游戏,实现悔棋、保存棋谱、棋谱复盘等功能。窗口程序依赖于javafx,编译运行请使用jdk1.8。完成结果如下图:完整代码:棋子类 import javafx.scene.paint.Color; /** * 棋子描述类 */ public class Chess { /** * 棋子横坐标 */ private final int x; /** * 棋子纵坐标 */ private final int y; /** * 棋子颜色 */ private final Color color; public Chess(int x, int y, Color color) { this.x = x; this.y = y; this.color = color; } public int getX() { return x; } public int getY() { return y; } public Color getColor() { return color; } @Override public String toString() { return "Chess [x=" + x + ", y=" + y + ", color=" + color + "]"; } }主框架类import javafx.application.Application; 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.layout.Background; import javafx.scene.layout.BackgroundFill; import javafx.scene.layout.Pane; import javafx.scene.paint.Color; import javafx.scene.shape.Circle; import javafx.scene.shape.Line; import javafx.stage.FileChooser; import javafx.stage.FileChooser.ExtensionFilter; import javafx.stage.Stage; import java.io.*; import java.util.ArrayList; import java.util.Optional; import java.util.function.Predicate; /** * 主框架类 */ public class MyChessApp extends Application { /** * 棋盘宽度 */ private static final int WIDTH = 600; /** * 棋盘高度 */ private static final int HEIGHT = 600; /** * 棋盘中线与线之间的距离 */ private static final int PADDING = 40; /** * 棋盘与边框之间的距离 */ private static final int MARGIN = 20; /** * 棋盘中水平线与垂直线的个数 */ private static final int LINE_COUNT = 14; /** * 棋盘对象 */ private Pane pane; /** * 当前落子是否为黑子 */ private boolean isBlack = true; /** * 记录棋盘 */ private Chess[][] chesses = new Chess[LINE_COUNT][LINE_COUNT]; /** * 记录棋子顺序 */ private Chess[] cs = new Chess[LINE_COUNT * LINE_COUNT]; /** * 棋盘上棋子个数 */ private int count = 0; /** * 是否胜利 */ private boolean isWin = false; /** * 舞台对象 */ private Stage stage; @Override public void start(Stage stage) { this.stage = stage; // 获取画板对象 this.pane = getPane(); // 落子 moveInChess(); // 创建场景对象 Scene scene = new Scene(pane, WIDTH, HEIGHT); stage.setScene(scene); stage.setTitle("五子棋"); stage.setOnCloseRequest(event -> { Alert alert = new Alert(AlertType.CONFIRMATION); alert.setTitle("退出"); alert.setHeaderText("确认提出吗?"); Optional<ButtonType> optional = alert.showAndWait(); if (optional.isPresent() && optional.get() == ButtonType.CANCEL) { event.consume(); } }); stage.show(); } /** * 落子功能 */ private void moveInChess() { // 给画板对象绑定鼠标点击事件 pane.setOnMouseClicked(event -> { if (isWin) { return; } // 获取鼠标点击的坐标 double x = event.getX(); double y = event.getY(); // System.out.println(x + " " + y); if (!(x >= MARGIN && x <= MARGIN + (LINE_COUNT - 1) * PADDING && y >= MARGIN && y <= MARGIN + (LINE_COUNT - 1) * PADDING)) { return; } // 根据鼠标点击位置计算棋子坐标 int chessX = ((int) x - MARGIN + PADDING / 2) / PADDING; int chessY = ((int) y - MARGIN + PADDING / 2) / PADDING; // System.out.println(_x + " " + _y); if (chesses[chessX][chessY] != null) { // System.out.println("已经有棋子了"); return; } // 绘制棋子 Chess chess = drawChess(chessX, chessY); if (isWin(chess)) { Alert alert = new Alert(AlertType.INFORMATION); alert.setTitle("游戏结束"); String name; if (chess.getColor() == Color.BLACK) { name = "黑子"; } else { name = "白子"; } alert.setHeaderText(name + "胜利了"); alert.showAndWait(); isWin = true; } }); } /** * 绘制棋子 */ private Chess drawChess(int chessX, int chessY) { Circle circle; Chess chess; if (isBlack) { circle = new Circle(chessX * PADDING + MARGIN, chessY * PADDING + MARGIN, 15, Color.BLACK); chess = new Chess(chessX, chessY, Color.BLACK); isBlack = false; } else { circle = new Circle(chessX * PADDING + MARGIN, chessY * PADDING + MARGIN, 15, Color.WHITE); chess = new Chess(chessX, chessY, Color.WHITE); isBlack = true; } chesses[chessX][chessY] = chess; cs[count++] = chess; pane.getChildren().add(circle); return chess; } /** * 创建画板对象 */ private Pane getPane() { // 创建画板对象 Pane pane = new Pane(); // 设置画板背景颜色 pane.setBackground(new Background(new BackgroundFill(Color.BEIGE, null, null))); // 绘制棋盘 int increment = 0; for (int i = 0; i < LINE_COUNT; i++) { Line rowLine = new Line(MARGIN, MARGIN + increment, MARGIN + (LINE_COUNT - 1) * PADDING, MARGIN + increment); Line colLine = new Line(MARGIN + increment, MARGIN, MARGIN + increment, MARGIN + (LINE_COUNT - 1) * PADDING); pane.getChildren().add(rowLine); pane.getChildren().add(colLine); increment += PADDING; } // 再来一局按钮 Button startButton = getStartButton(); // 悔棋按钮 Button retractButton = getRetractButton(); // 退出按钮 Button quitButton = getQuitButton(); // 保存棋谱按钮 Button saveButton = getSaveButton(); // 保存打谱按钮 Button scoreButton = getScoreButton(); pane.getChildren().add(startButton); pane.getChildren().add(retractButton); pane.getChildren().add(quitButton); pane.getChildren().add(saveButton); pane.getChildren().add(scoreButton); return pane; } /** * 获取打谱按钮 */ private Button getScoreButton() { Button scoreButton = new Button("棋谱复盘"); scoreButton.setPrefSize(80, 30); scoreButton.setLayoutX(WIDTH / 15.0 + 100 * 3); scoreButton.setLayoutY(HEIGHT - 40); scoreButton.setOnAction(event -> { FileChooser fileChooser = new FileChooser(); fileChooser.getExtensionFilters().addAll(new ExtensionFilter("棋谱文件", "*.qipu"), new ExtensionFilter("所有文件", "*.*")); File file = fileChooser.showOpenDialog(stage); if (file == null) { return; } try { BufferedReader br = new BufferedReader(new FileReader(file)); String line; ArrayList<String> cheesiness = new ArrayList<>(); while ((line = br.readLine()) != null) { cheesiness.add(line); } br.close(); resetChessBoard(); Button next = new Button(">"); next.setPrefSize(40, 40); next.setLayoutX(WIDTH - 40); next.setLayoutY(100); next.setOnAction(event13 -> { if (count >= cheesiness.size()) { Alert alert = new Alert(AlertType.INFORMATION); alert.setTitle("提示"); alert.setHeaderText("没有下一步了"); alert.showAndWait(); return; } String[] info = cheesiness.get(count).split(","); drawChess(Integer.parseInt(info[0]), Integer.parseInt(info[1])); }); pane.getChildren().add(next); Button pre = new Button("<"); pre.setPrefSize(40, 40); pre.setLayoutX(WIDTH - 40); pre.setLayoutY(150); pre.setOnAction(event12 -> retract()); pane.getChildren().add(pre); Button exit = new Button("x"); exit.setPrefSize(40, 40); exit.setLayoutX(WIDTH - 40); exit.setLayoutY(200); exit.setOnAction(event1 -> { Alert alert = new Alert(AlertType.CONFIRMATION); alert.setTitle("提示"); alert.setHeaderText("确定退出打谱?"); Optional<ButtonType> optional = alert.showAndWait(); if (optional.isPresent() && optional.get() == ButtonType.OK) { resetChessBoard(); pane.getChildren().remove(pane.getChildren().size() - 3, pane.getChildren().size()); } }); pane.getChildren().add(exit); } catch (IOException e) { e.printStackTrace(); } }); return scoreButton; } /** * 获取保存棋谱按钮 */ private Button getSaveButton() { Button saveButton = new Button("保存棋谱"); saveButton.setPrefSize(80, 30); saveButton.setLayoutX(WIDTH / 15.0 + 100 * 2); saveButton.setLayoutY(HEIGHT - 40); saveButton.setOnAction(event -> { FileChooser fileChooser = new FileChooser(); fileChooser.getExtensionFilters().addAll(new ExtensionFilter("棋谱文件", "*.qipu"), new ExtensionFilter("所有文件", "*.*")); File file = fileChooser.showSaveDialog(stage); if (file == null) { return; } try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) { for (int i = 0; i < count; i++) { bw.write(cs[i].getX() + "," + cs[i].getY() + "," + cs[i].getColor()); bw.newLine(); } } catch (IOException e) { e.printStackTrace(); } }); return saveButton; } /** * 获取退出按钮 */ private Button getQuitButton() { Button quitButton = new Button("退出"); quitButton.setPrefSize(80, 30); quitButton.setLayoutX(WIDTH / 15.0 + 100 * 4); quitButton.setLayoutY(HEIGHT - 40); quitButton.setOnAction(event -> { Alert alert = new Alert(AlertType.CONFIRMATION); alert.setTitle("退出"); alert.setHeaderText("确认提出吗?"); Optional<ButtonType> optional = alert.showAndWait(); if (optional.isPresent() && optional.get() == ButtonType.OK) { System.exit(0); } }); return quitButton; } /** * 获取悔棋按钮 */ private Button getRetractButton() { Button retractButton = new Button("悔棋"); retractButton.setPrefSize(80, 30); retractButton.setLayoutX(WIDTH / 15.0 + 100); retractButton.setLayoutY(HEIGHT - 40); retractButton.setOnAction(event -> retract()); return retractButton; } /** * 获取再来一局按钮 */ private Button getStartButton() { // 添加按钮对象 Button startButton = new Button("再来一局"); startButton.setPrefSize(80, 30); startButton.setLayoutX(WIDTH / 15.0); startButton.setLayoutY(HEIGHT - 40); // 给按钮对象绑定鼠标点击事件 startButton.setOnAction(event -> resetChessBoard()); return startButton; } /** * 悔棋 */ private void retract() { if (isWin) { return; } if (count > 0) { pane.getChildren().remove(pane.getChildren().size() - 1); isBlack = !isBlack; Chess chess = cs[--count]; chesses[chess.getX()][chess.getY()] = null; cs[count] = null; } } /** * 重置棋盘 */ private void resetChessBoard() { pane.getChildren().removeIf((Predicate<Object>) t -> t instanceof Circle); count = 0; chesses = new Chess[LINE_COUNT][LINE_COUNT]; cs = new Chess[LINE_COUNT * LINE_COUNT]; isBlack = true; isWin = false; } /** * 判断胜负 */ private boolean isWin(Chess chess) { int x = chess.getX(); int y = chess.getY(); Color color = chess.getColor(); // 向右横向判断 for (int i = x + 1; i <= x + 4 && i < LINE_COUNT; i++) { Chess c = chesses[i][y]; if (c == null || !color.equals(c.getColor())) { break; } if (i == x + 4) { return true; } } // 向左横向判断 for (int i = x - 1; i >= x - 4 && i >= 0; i--) { Chess c = chesses[i][y]; if (c == null || !color.equals(c.getColor())) { break; } if (i == x - 4) { return true; } } // 向上纵向判断 for (int i = y - 1; i >= y - 4 && i >= 0; i--) { Chess c = chesses[x][i]; if (c == null || !color.equals(c.getColor())) { break; } if (i == y - 4) { return true; } } // 向下纵向判断 for (int i = y + 1; i <= y + 4 && i < LINE_COUNT; i++) { Chess c = chesses[x][i]; if (c == null || !color.equals(c.getColor())) { break; } if (i == y + 4) { return true; } } // 向右上斜向判断 for (int i = x + 1, j = y - 1; i <= x + 4 && j >= y - 4 && i < LINE_COUNT && j >= 0; i++, j--) { Chess c = chesses[i][j]; if (c == null || !color.equals(c.getColor())) { break; } if (i == x + 4 && j == y - 4) { return true; } } // 向左上斜向判断 for (int i = x - 1, j = y - 1; i >= x - 4 && j >= y - 4 && i >= 0 && j >= 0; i--, j--) { Chess c = chesses[i][j]; if (c == null || !color.equals(c.getColor())) { break; } if (i == x - 4 && j == y - 4) { return true; } } // 向左下斜向判断 for (int i = x - 1, j = y + 1; i >= x - 4 && j <= y + 4 && i >= 0 && j < LINE_COUNT; i--, j++) { Chess c = chesses[i][j]; if (c == null || !color.equals(c.getColor())) { break; } if (i == x - 4 && j == y + 4) { return true; } } // 向右下斜向判断 for (int i = x + 1, j = y + 1; i <= x + 4 && j <= y + 4 && i < LINE_COUNT && j < LINE_COUNT; i++, j++) { Chess c = chesses[i][j]; if (c == null || !color.equals(c.getColor())) { break; } if (i == x + 4 && j == y + 4) { return true; } } return false; } public static void main(String[] args) { launch(args); } }
2022年04月04日
58 阅读
0 评论
2 点赞