javafx逻辑实现五子棋基本功能(悔棋,重新开始,保存棋谱,复盘,人人对战,单机模式)
做这个项目,本身目的仅仅是想应用学过的知识做个小项目,想知道它们在实际开发中应该如何应用,顺便帮我对几个月来的学习的知识更深入的了解。等我学完了数据库,再做个更大的项目,应该不成问题。所以,这篇文章适合学完Java基础的人学习,这也是我对自己Java学习第一阶段做的总结。
这是关于棋子文件上传代码
saveButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public 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>() {
@Override
public void handle(ActionEvent event) {
//首先应该在点击复盘的时候清空所有棋子
//怎么删除呢,怎么添加怎么删除,pane.getChildren()是一个单列集合
pane.getChildren().removeIf(new Predicate<Object>() {
@Override
public 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>() {
@Override
public void handle(MouseEvent event) {
return;
}
});
Button up = up();
pane.getChildren().add(up);
Button down = down();
pane.getChildren().add(down);
movingdown(down);
movingup(up);
}
else
return;
}
});
单机模式完整代码
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>(){
//当鼠标点击画板,就会执行该方法
@Override
public 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>() {
@Override
public void handle(ActionEvent event) {
if (!isWin)
return;
//怎么删除呢,怎么添加怎么删除,pane.getChildren()是一个单列集合
pane.getChildren().removeIf(new Predicate<Object>() {
@Override
public 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>() {
@Override
public 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;
else
isBLACK=false;
chesses =new Chess[100];
count=0;
isWin=false;
}
});
pane.getChildren().add(backButton);
//获取保存棋谱的按钮对象
Button saveButton=getsaveButton();
saveButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public 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>() {
@Override
public void handle(ActionEvent event) {
//首先应该在点击复盘的时候清空所有棋子
//怎么删除呢,怎么添加怎么删除,pane.getChildren()是一个单列集合
pane.getChildren().removeIf(new Predicate<Object>() {
@Override
public 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>() {
@Override
public void handle(MouseEvent event) {
return;
}
});
Button up = up();
pane.getChildren().add(up);
Button down = down();
pane.getChildren().add(down);
movingdown(down);
movingup(up);
}
else
return;
}
});
pane.getChildren().add(replay);
//获取时间对象
/* 例:如果想在javafx程序中加一个计时器,那么必须用Platform.runLater(new Runnable() {
@Override
public void run() {
********此处将要执行在javafx上执行的代码写进来
}
});*/
Label label=new Label();
label.setLayoutX(250);
label.setLayoutY(0);
Timer timer=new Timer();
timer.schedule(new TimerTask() {
@Override
public 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() {
@Override
public void run() {
label.setText(time);
}
});
}
},0,1000);
pane.getChildren().add(label);
return pane;
}
public void movingup(Button up){
up.setOnAction(new EventHandler<ActionEvent>() {
@Override
public 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;
else
isBLACK = 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>() {
@Override
public 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);
else
circle = 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;
}
@Override
public 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);
}
@Override
public 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;
}
@Override
public String toString() {
return "com.Chess{" +
"x=" + x +
", y=" + y +
", color=" + color +
'}';
}
}
套接字编程