javafx逻辑实现五子棋基本功能(悔棋,重新开始,保存棋谱,复盘,人人对战,单机模式)
做这个项目,本身目的仅仅是想应用学过的知识做个小项目,想知道它们在实际开发中应该如何应用,顺便帮我对几个月来的学习的知识更深入的了解。等我学完了数据库,再做个更大的项目,应该不成问题。所以,这篇文章适合学完Java基础的人学习,这也是我对自己Java学习第一阶段做的总结。
这是关于棋子文件上传代码
saveButton.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent event) {//创建保存框对象FileChooser fileChooser=new FileChooser();if(!isWin)return;//展示Window window = ;File file=fileChooser.showSaveDialog(stage);BufferedWriter bw=null;if (file!=null){try {bw=new BufferedWriter(new FileWriter(file) );//一次写一个字符串for (int i=0;i<count;i++){Chess chess=chesses[i];bw.write(chess.getX()+","+chess.getY()+","+chess.getColor());bw.newLine();bw.flush();}} catch (Exception e) {System.out.println("保存失败");}finally {try {bw.close();} catch (IOException e) {e.printStackTrace();}}}System.out.println(file);}});
复盘代码
replay.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent event) {//首先应该在点击复盘的时候清空所有棋子//怎么删除呢,怎么添加怎么删除,pane.getChildren()是一个单列集合pane.getChildren().removeIf(new Predicate<Object>() {@Overridepublic boolean test(Object obj) {return obj instanceof Circle;}});//清空了,为什么会是白子先走,而且有些地方仍旧显示有棋子isBLACK=true;chesses =new Chess[100];count=0;isWin=false;FileChooser fileChooser=new FileChooser();file=fileChooser.showOpenDialog(stage);if (file!=null) {//关闭画板鼠标点击事件pane.setOnMouseClicked(new EventHandler<MouseEvent>() {@Overridepublic void handle(MouseEvent event) {return;}});Button up = up();pane.getChildren().add(up);Button down = down();pane.getChildren().add(down);movingdown(down);movingup(up);}elsereturn;}});
单机模式完整代码
package com.zht.ui.single;import com.zht.domain.Chess;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
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.Stage;import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
import java.util.function.Predicate;public class SingleUI extends Application {private boolean isBLACK=true;private Chess[] chesses=new Chess[100];//装棋子的容器private int count=0;//棋盘上妻子个数private int iswincount=1;private boolean isWin=false;private Stage stage=null;private Pane pane=null;Scanner scanner=null;public static void main(String[] args) {launch(args);}public void start (Stage stage) {this.stage=stage;//获取画板this.pane=getPane();pane.setBackground(new Background(new BackgroundFill(Color.BISQUE,null,null)));//给画板对象,绑定鼠标点击事件,就可以执行某些动作moveInChess(pane);//创建场景对象,把画板对象放进去Scene scene=new Scene(pane,850,860);stage.setScene(scene);stage.show();}private void moveInChess(Pane pane) {pane.setOnMouseClicked(new EventHandler<MouseEvent>(){//当鼠标点击画板,就会执行该方法@Overridepublic void handle(MouseEvent event) {//注意这里if (isWin){return;}//获取鼠标点击位置x和y的坐标double x=event.getX();double y=event.getY();if(!(x>=50&&x<=750&&y>=50&&y<=750)){return;}else{int x1=(int)((x+25)/50)*50;int y1=(int)((y+25)/50)*50;//判断x和y上是否有棋子,使棋子无法同时在一点if(isHas(x1,y1)){System.out.println("该位置有棋子");return;}Circle circle=null;Chess chess=null;if(isBLACK){circle=new Circle(x1,y1,15, Color.BLACK);isBLACK=false;chess=new Chess(x1,y1,Color.BLACK);}else {circle=new Circle(x1,y1,15, Color.WHITE);isBLACK=true;chess=new Chess(x1,y1,Color.WHITE);}pane.getChildren().add(circle);//向容器里放一个棋子对象chesses[count]=chess;count++;if(isWin(chess)){//System.out.println("胜利了");//弹窗Alert alert=new Alert(Alert.AlertType.INFORMATION);alert.setContentText("五子棋大师!!!!!!");alert.showAndWait();isWin=true;}}}});}//当落完子后,连续超过5个同颜色棋子即为胜利private boolean isWin(Chess chess){int x=chess.getX();int y=chess.getY();//向右for (int i=x+50;i<=x+200&&i<750;i+=50){//判断这个位置,有没有棋子,颜色是什么Chess _chess=getChess(i,y);if(_chess!=null&&chess.getColor().equals(_chess.getColor())){iswincount++;}else {break;}}//向左for (int i=x-50;i>=x-200&&i>=0;i-=50){//判断这个位置,有没有棋子,颜色是什么Chess _chess=getChess(i,y);if(_chess!=null&&chess.getColor().equals(_chess.getColor())){iswincount++;}else {break;}}if(iswincount>=5){iswincount=1;return true;}iswincount=1;//判断垂直方向for (int i=y+50;i<=y+200&&i<800;i+=50){//判断这个位置,有没有棋子,颜色是什么Chess _chess=getChess(x,i);if(_chess!=null&&chess.getColor().equals(_chess.getColor())){iswincount++;}else {break;}}for (int i=y-50;i>=y-200&&i>=0;i-=50){//判断这个位置,有没有棋子,颜色是什么Chess _chess=getChess(x,i);if(_chess!=null&&chess.getColor().equals(_chess.getColor())){iswincount++;}else {break;}}if(iswincount>=5){iswincount=1;return true;}iswincount=1;//判断右斜for (int i=x+50, j=y+50;i<=x+200&&i<750&&j<=y+200&&j<750;i+=50,j+=50){//判断这个位置,有没有棋子,颜色是什么Chess _chess=getChess(i,j);if(_chess!=null&&chess.getColor().equals(_chess.getColor())){iswincount++;}else {break;}}for (int i=y-50,j=x-50;i>=y-200&&i>=0&&j>=x-200&&j>=0;i-=50,j-=50){//判断这个位置,有没有棋子,颜色是什么Chess _chess=getChess(j,i);if(_chess!=null&&chess.getColor().equals(_chess.getColor())){iswincount++;}else {break;}}if(iswincount>=5){iswincount=1;return true;}iswincount=1;//判断左斜for (int i=x+50, j=y-50;i<=x+200&&i<750&&j>=y-200&&j>=0;i+=50,j-=50){//判断这个位置,有没有棋子,颜色是什么Chess _chess=getChess(i,j);if(_chess!=null&&chess.getColor().equals(_chess.getColor())){iswincount++;}else {break;}}for (int i=x-50, j=y+50;i>=x-200&&i>=0&&j<=y+200&&j<=750;i-=50,j+=50){//判断这个位置,有没有棋子,颜色是什么Chess _chess=getChess(i,j);if(_chess!=null&&chess.getColor().equals(_chess.getColor())){iswincount++;}else {break;}}if(iswincount>=5){iswincount=1;return true;}iswincount=1;return false;}//封装的方法,如果找到返回chess,没有返回null//获取指定坐标的棋子对象private Chess getChess(int x,int y){//定义个容器for (int i=0;i<count;i++){Chess chess=chesses[i];if (chess.getX()==x&&chess.getY()==y){return chess;}}return null;}private boolean isHas(int x,int y){//定义个容器for (int i=0;i<count;i++){Chess chess=chesses[i];if (chess.getX()==x&&chess.getY()==y){return true;}}return false;}File file=null;private Pane getPane() {//创建画板对象Pane pane=new Pane();//创建线条对象for (int i=1;i<16;i++){Line colline=new Line(50*i,50,50*i,750);Line rowline=new Line(50,50*i,750,50*i);//将线条放进画板里pane.getChildren().add(colline);pane.getChildren().add(rowline);}//这里是重新开始按钮Button startButton = getButton();startButton.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent event) {if (!isWin)return;//怎么删除呢,怎么添加怎么删除,pane.getChildren()是一个单列集合pane.getChildren().removeIf(new Predicate<Object>() {@Overridepublic boolean test(Object obj) {return obj instanceof Circle;}});//清空了,为什么会是白子先走,而且有些地方仍旧显示有棋子isBLACK=true;chesses =new Chess[100];count=0;isWin=false;}});pane.getChildren().add(startButton);//获得悔棋的按钮对象//悔棋,这里要理解迭代器Button backButton=backButton();backButton.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent event) {if (isWin)return;Iterator it=pane.getChildren().iterator();Object obj=null;while (it.hasNext()){obj=it.next();}if (obj instanceof Circle){it.remove();}if (isBLACK==false)isBLACK=true;elseisBLACK=false;chesses =new Chess[100];count=0;isWin=false;}});pane.getChildren().add(backButton);//获取保存棋谱的按钮对象Button saveButton=getsaveButton();saveButton.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent event) {//创建保存框对象FileChooser fileChooser=new FileChooser();if(!isWin)return;//展示Window window = ;File file=fileChooser.showSaveDialog(stage);BufferedWriter bw=null;if (file!=null){try {bw=new BufferedWriter(new FileWriter(file) );//一次写一个字符串for (int i=0;i<count;i++){Chess chess=chesses[i];bw.write(chess.getX()+","+chess.getY()+","+chess.getColor());bw.newLine();bw.flush();}} catch (Exception e) {System.out.println("保存失败");}finally {try {bw.close();} catch (IOException e) {e.printStackTrace();}}}System.out.println(file);}});pane.getChildren().add(saveButton);//获取复盘按钮的对象Button replay=replayButton();replay.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent event) {//首先应该在点击复盘的时候清空所有棋子//怎么删除呢,怎么添加怎么删除,pane.getChildren()是一个单列集合pane.getChildren().removeIf(new Predicate<Object>() {@Overridepublic boolean test(Object obj) {return obj instanceof Circle;}});//清空了,为什么会是白子先走,而且有些地方仍旧显示有棋子isBLACK=true;chesses =new Chess[100];count=0;isWin=false;FileChooser fileChooser=new FileChooser();file=fileChooser.showOpenDialog(stage);if (file!=null) {//关闭画板鼠标点击事件pane.setOnMouseClicked(new EventHandler<MouseEvent>() {@Overridepublic void handle(MouseEvent event) {return;}});Button up = up();pane.getChildren().add(up);Button down = down();pane.getChildren().add(down);movingdown(down);movingup(up);}elsereturn;}});pane.getChildren().add(replay);//获取时间对象/* 例:如果想在javafx程序中加一个计时器,那么必须用Platform.runLater(new Runnable() {@Overridepublic void run() {********此处将要执行在javafx上执行的代码写进来}});*/Label label=new Label();label.setLayoutX(250);label.setLayoutY(0);Timer timer=new Timer();timer.schedule(new TimerTask() {@Overridepublic void run() {//获取当前时间LocalDateTime localDateTime=LocalDateTime.now();DateTimeFormatter pattern=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");String time=localDateTime.format(pattern);Platform.runLater(new Runnable() {@Overridepublic void run() {label.setText(time);}});}},0,1000);pane.getChildren().add(label);return pane;}public void movingup(Button up){up.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent event) {if (isWin)return;Iterator it = pane.getChildren().iterator();Object obj = null;while (it.hasNext()) {obj = it.next();}if (obj instanceof Circle) {it.remove();}if (!isBLACK)isBLACK = true;elseisBLACK = false;chesses = new Chess[100];count = 0;isWin = false;}});}public void movingdown(Button down) {try {scanner = new Scanner(new FileInputStream(file));down.setOnAction(new EventHandler<ActionEvent>() {@Overridepublic void handle(ActionEvent event) {Circle circle=null;String line=null;if ((line = scanner.nextLine()) != null) {String[] strs = line.split(",");if (strs[2].equals("0x000000ff"))circle = new Circle(Integer.parseInt(strs[0]), Integer.parseInt(strs[1]), 15, Color.BLACK);elsecircle = new Circle(Integer.parseInt(strs[0]), Integer.parseInt(strs[1]), 15, Color.WHITE);pane.getChildren().add(circle);}}});} catch (FileNotFoundException e) {System.out.println("已经到头啦!");}}private Button down(){Button up=new Button(">");up.setPrefSize(40,30);up.setLayoutX(780);up.setLayoutY(560);return up;}private Button up(){Button up=new Button("<");up.setPrefSize(40,30);up.setLayoutX(780);up.setLayoutY(500);return up;}private Button replayButton(){Button replay=new Button("复盘");replay.setPrefSize(100,50);replay.setLayoutX(500);replay.setLayoutY(780);return replay;}private Button getsaveButton(){Button saveButton=new Button("保存棋谱");saveButton.setPrefSize(100,50);saveButton.setLayoutX(350);saveButton.setLayoutY(780);return saveButton;}private Button backButton() {Button backButton=new Button("悔棋");backButton.setPrefSize(100,50);backButton.setLayoutX(200);backButton.setLayoutY(780);return backButton;}private Button getButton() {Button startButton=new Button("再来一局");startButton.setPrefSize(100,50);startButton.setLayoutX(50);startButton.setLayoutY(780);return startButton;}}
/*
class Pane{public final void setOnMouseClicked(EventHandler<? super MouseEvent> value){}
}*/
单机版实体类
package com.zht.domain;//真正的面向对象思想
import javafx.scene.paint.Color;public class Chess {private int x;private int y;private Color color;public Chess(){}public Chess(int x,int y,Color color){this.x=x;this.y=y;this.color=color;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Chess chess = (Chess) o;return x == chess.x && y == chess.y && color.equals(chess.color);}@Overridepublic int hashCode() {return 0;}public int getX() {return x;}public void setX(int x) {this.x = x;}public int getY() {return y;}public void setY(int y) {this.y = y;}public String getColor() {return color.toString();}public void setColor(Color color) {this.color = color;}@Overridepublic String toString() {return "com.Chess{" +"x=" + x +", y=" + y +", color=" + color +'}';}
}
套接字编程
想要看到更多的代码,请
完整代码请点击此处