题目
轮流放置红色和黄色棋子,如果一个玩家胜利,闪烁连好的棋子
说明
可以通过修改类中的私有变量来修改棋盘大小、连子胜利条件、棋子颜色等。
代码
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.scene.layout.GridPane;
import javafx.scene.input.MouseEvent;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.util.Duration;
public class Main extends Application {
private int lianqi = 4; //连续4个相同游戏结束
private int qipan_size = 6; //棋盘大小 6*6
private int bushu = 0; //步数
private int [][]qiziweizhi = new int[lianqi*2][2]; //保存胜利一方妻子的位置,用于闪烁棋子
private int lianzi_count = 0; //一方胜利后连子的个数,一般等于变量 lianqi
private double yuan_banjing = 30; //棋子半径
private double yuan_jiange = 10; //棋子间隔
private boolean sheixia = false; //标记该谁下
private boolean youxi_end = false; //标记游戏结束
private Circle [][]circle = new Circle[qipan_size][qipan_size]; //棋盘
private Label lblstatus = new Label("X's turn to play"); //棋盘下面显示的字段
private Timeline t; //定时器,用于胜利后闪烁棋子
public void start(Stage primaryStage) {
//GridPane 网状布局
GridPane pane = new GridPane();
//设置纵横间隔
pane.setHgap(yuan_jiange);
pane.setVgap(yuan_jiange);
//创造布局 一个qipan_size*qipan_size的棋盘
for(int i = 0;i<qipan_size;i++){
for(int j = 0;j<qipan_size;j++){
circle[i][j] = new Circle(yuan_banjing);
circle[i][j].setStroke(Color.BLACK);
circle[i][j].setFill(Color.WHITE);
circle[i][j].setOnMouseClicked(e -> xiaqi(e));
pane.add(circle[i][j], i, j);
}
}
//定时器,游戏结束闪烁时用的
EventHandler<ActionEvent> eventHandler = e -> {
for(int i=0;i<lianzi_count;i++){
Circle c = circle[qiziweizhi[i][0]][qiziweizhi[i][1]];
if(c.getFill() == Color.WHITE){
if(bushu%2 == 1)
c.setFill(Color.RED);
else
c.setFill(Color.YELLOW);
}
else
c.setFill(Color.WHITE);
}
};
t = new Timeline(new KeyFrame(Duration.millis(500), eventHandler));
t.setCycleCount(Timeline.INDEFINITE);
//场景
BorderPane borderPane = new BorderPane();
borderPane.setCenter(pane);
borderPane.setBottom(lblstatus);
//舞台
Scene scene = new Scene(borderPane);
primaryStage.setTitle("Exercise");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
//鼠标点击棋盘上的⚪后 触发事件
private void xiaqi(MouseEvent e){
if(youxi_end)
return;
if(bushu>=qipan_size*qipan_size){
lblstatus.setText("with!!"); //平局
return;
}
int x = (int)(e.getSceneX()/(yuan_banjing*2 + yuan_jiange));
int y = (int)(e.getSceneY()/(yuan_banjing*2 + yuan_jiange));
if(circle[x][y].getFill() != Color.WHITE){
return;
}
sheixia =! sheixia;
bushu++;
if(sheixia){
circle[x][y].setFill(Color.RED);
lblstatus.setText("Y's turn to play");
}
else{
circle[x][y].setFill(Color.YELLOW);
lblstatus.setText("X's turn to play");
}
youxi_end = panduanend(x,y); //判断该点放至棋子后游戏是否会结束
if(youxi_end){
if(sheixia)
lblstatus.setText("Y's turn victory");
else
lblstatus.setText("X's turn victory");
}
t.play();
}
//游戏结束条件判断,下面就是算法的问题了。这是我想的一个简单算法,虽然看着麻烦,但是好用啊
private boolean panduanend(int x,int y){
lianzi_count = 0;
//横向判断连子个数
for(int i=0;true;i++){
if(x+i<qipan_size && circle[x][y].getFill() == circle[x+i][y].getFill()){
qiziweizhi[lianzi_count][0] = x+i;
qiziweizhi[lianzi_count][1] = y;
lianzi_count ++;
}
else
break;
}
for(int i=1;true;i++){
if(x-i>=0 && circle[x][y].getFill() == circle[x-i][y].getFill()){
qiziweizhi[lianzi_count][0] = x-i;
qiziweizhi[lianzi_count][1] = y;
lianzi_count ++;
}
else
break;
}
if(lianzi_count>=lianqi)
return true;
lianzi_count = 0;
//列向判断连子个数
for(int i=0;true;i++){
if(y+i<qipan_size && circle[x][y].getFill() == circle[x][y+i].getFill())
{
qiziweizhi[lianzi_count][0] = x;
qiziweizhi[lianzi_count][1] = y+i;
lianzi_count ++;
}
else
break;
}
for(int i=1;true;i++){
if(y-i>=0 && circle[x][y].getFill() == circle[x][y-i].getFill())
{
qiziweizhi[lianzi_count][0] = x;
qiziweizhi[lianzi_count][1] = y-i;
lianzi_count ++;
}
else
break;
}
if(lianzi_count>=lianqi)
return true;
lianzi_count = 0;
//左上到右下连子数目
for(int i=0;true;i++){
if(y+i<qipan_size && x+i<qipan_size && circle[x][y].getFill() == circle[x+i][y+i].getFill())
{
qiziweizhi[lianzi_count][0] = x+i;
qiziweizhi[lianzi_count][1] = y+i;
lianzi_count ++;
}
else
break;
}
for(int i=1;true;i++){
if(y-i>=0 && x-i>=0 && circle[x][y].getFill() == circle[x-i][y-i].getFill())
{
qiziweizhi[lianzi_count][0] = x-i;
qiziweizhi[lianzi_count][1] = y-i;
lianzi_count ++;
}
else
break;
}
if(lianzi_count>=lianqi)
return true;
lianzi_count = 0;
//左下到右上
for(int i=0;true;i++){
if(y+i<qipan_size && x-i>=0 && circle[x][y].getFill() == circle[x-i][y+i].getFill())
{
qiziweizhi[lianzi_count][0] = x-i;
qiziweizhi[lianzi_count][1] = y+i;
lianzi_count ++;
}
else
break;
}
for(int i=1;true;i++){
if(y-i>=0 && x+i<qipan_size && circle[x][y].getFill() == circle[x+i][y-i].getFill())
{
qiziweizhi[lianzi_count][0] = x+i;
qiziweizhi[lianzi_count][1] = y-i;
lianzi_count ++;
}
else
break;
}
if(lianzi_count>=lianqi)
return true;
lianzi_count = 0;
return false;
}
}