题目描述

Tromino 是指一个由棋盘上的三个方块组成的 L 型骨牌。如何用 Tromino 覆盖一个缺
少了一个方块(可以在棋盘上任何位置)的棋盘(下图展示了情况)。除了这个缺失的方
块,Tromino 应该覆盖棋盘上的所有方块,Tromino 可以任意转向但不能有重叠。

实现思想

使用变量标记区域坐标信息,随机生成L区域颜色。使用L区域的3个格子和随机生成的一个格子把每一个象限里都实现涂鸦一个格子。然后递归调用函数把每一个区域涂鸦,直到剩下的区域尺寸为2x2时结束调用。
数据结构:变量储存坐标信息
实现步骤:L区域的3个格子和随机生成的一个格子把每一个象限里都实现涂鸦一个格子。然后递归调用函数把每一个区域涂鸦,知道剩下的区域尺寸为2x2时结束调用。
实现技巧:递归的去实现涂鸦每一个象限的方格,我认为时很方便的处理方法。这样可以避免处理循环以及各种问题。
时间复杂度为:O(n^2)
空间复杂度:O(n^2)

结果

代码

package CourseDesign;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.shape.Line;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

import java.util.Random;

public class A1 extends Application {
   
    Group group = new Group();
    Scene scene = new Scene(group, 800, 800);
    Rectangle rectangle = null;

    @Override
    public void start(Stage primaryStage) throws Exception {
   
        // ***************
        int pow = 16;//界面
        int size = 50;//小格子的大小
        //****************
        Random random = new Random();
        // 画线
        for (int i = 0; i < pow + 1; i++) {
   
            // 横线
            Line line = new Line(0, i * size, 50 * pow, i * size);
            line.setStroke(Color.RED);
            group.getChildren().add(line);
            // 竖线
            line = new Line(i * size, 0, i * size, 50 * pow);
            line.setStroke(Color.RED);
            group.getChildren().add(line);
        }
        // 最开始的黑点
        int x = random.nextInt(pow) * size;
        int y = random.nextInt(pow) * size;
        rectangle = new Rectangle(x, y, size, size);
        group.getChildren().add(rectangle);
        // 建立一个线程开始涂棋盘
        Thread thread = new Thread(() -> {
   
            try {
   
                Thread.sleep(600);
            } catch (InterruptedException e) {
   
                e.printStackTrace();
            }
            Runnable runnable = () -> tromino(primaryStage, x, y, pow, 0, 0, size);
            // 使用Platform启动线程
            Platform.runLater(runnable);
        });
        // 设置线程属性
        thread.setDaemon(true);
        thread.start();

        primaryStage.setScene(scene);
        primaryStage.setTitle("primaryStage");
        primaryStage.show();
    }

    // 涂颜色函数
    private void tromino(Stage primaryStage, int x, int y, int pow, int x0, int y0, int size) {
   
        // 初始化随机颜色
        Random random = new Random();
        int c1 = random.nextInt(256);
        int c2 = random.nextInt(256);
        int c3 = random.nextInt(256);
        // 的到中点
        int xCenter = x0 + pow / 2 * size;
        int yCenter = y0 + pow / 2 * size;
        // 其他三个象限的左上角坐标
        int x1, x2, x3, y1, y2, y3;
        // 判断象限再进行递归每一个象限涂色
        if (pow > 2) {
   
            if (xCenter > x) {
   
                x1 = xCenter;
                y1 = yCenter;
                rectangle = new Rectangle(xCenter, yCenter, size, size);
                rectangle.setFill(Color.rgb(c1, c2, c3));
                group.getChildren().add(rectangle);

                x2 = xCenter;
                y2 = yCenter - size;
                rectangle = new Rectangle(xCenter, yCenter - size, size, size);
                rectangle.setFill(Color.rgb(c1, c2, c3));
                group.getChildren().add(rectangle);

                if (yCenter > y) {
   
                    x3 = xCenter - size;
                    y3 = yCenter;
                    rectangle = new Rectangle(xCenter - size, yCenter, size, size);
                    rectangle.setFill(Color.rgb(c1, c2, c3));
                    group.getChildren().add(rectangle);
                } else {
   
                    x3 = xCenter - size;
                    y3 = yCenter - size;
                    rectangle = new Rectangle(xCenter - size, yCenter - size, size, size);
                    rectangle.setFill(Color.rgb(c1, c2, c3));
                    group.getChildren().add(rectangle);
                }
            } else {
   
                x1 = xCenter - size;
                y1 = yCenter;
                rectangle = new Rectangle(xCenter - size, yCenter, size, size);
                rectangle.setFill(Color.rgb(c1, c2, c3));
                group.getChildren().add(rectangle);

                x2 = xCenter - size;
                y2 = yCenter - size;
                rectangle = new Rectangle(xCenter - size, yCenter - size, size, size);
                rectangle.setFill(Color.rgb(c1, c2, c3));
                group.getChildren().add(rectangle);
                if (yCenter - y > 0) {
   
                    x3 = xCenter;
                    y3 = yCenter;
                    rectangle = new Rectangle(xCenter, yCenter, size, size);
                    rectangle.setFill(Color.rgb(c1, c2, c3));
                    group.getChildren().add(rectangle);
                } else {
   
                    x3 = xCenter;
                    y3 = yCenter - size;
                    rectangle = new Rectangle(xCenter, yCenter - size, size, size);
                    rectangle.setFill(Color.rgb(c1, c2, c3));
                    group.getChildren().add(rectangle);
                }
            }
            // 建立线程开始继续画棋盘
            Thread thread = new Thread(() -> {
   
                try {
   
                    Thread.sleep(600);
                } catch (InterruptedException e) {
   
                    e.printStackTrace();
                }
                Runnable runnable = () -> {
   
                    int[] xy = at(xCenter, yCenter, x1, y1, pow / 2, size);
                    tromino(primaryStage,  x1, y1, pow / 2, xy[0], xy[1], size);

                    xy = at(xCenter, yCenter, x2, y2, pow / 2, size);
                    tromino(primaryStage,  x2, y2, pow / 2, xy[0], xy[1], size);

                    xy = at(xCenter, yCenter, x3, y3, pow / 2, size);
                    tromino(primaryStage,  x3, y3, pow / 2, xy[0], xy[1], size);

                    xy = at(xCenter, yCenter, x, y, pow / 2, size);
                    tromino(primaryStage,  x, y, pow / 2, xy[0], xy[1], size);
                };
                Platform.runLater(runnable);
            });
            thread.setDaemon(true);
            thread.start();
        } else {
   
            if (x0 != x || y0 != y) {
   
                rectangle = new Rectangle(x0, y0, size, size);
                rectangle.setFill(Color.rgb(c1, c2, c3));
                group.getChildren().add(rectangle);
            }
            if (x0 + size != x || y0 != y) {
   
                rectangle = new Rectangle(x0 + size, y0, size, size);
                rectangle.setFill(Color.rgb(c1, c2, c3));
                group.getChildren().add(rectangle);
            }
            if (x0 != x || y0 + size != y) {
   
                rectangle = new Rectangle(x0, y0 + size, size, size);
                rectangle.setFill(Color.rgb(c1, c2, c3));
                group.getChildren().add(rectangle);
            }
            if (x0 + size != x || y0 + size != y) {
   
                rectangle = new Rectangle(x0 + size, y0 + size, size, size);
                rectangle.setFill(Color.rgb(c1, c2, c3));
                group.getChildren().add(rectangle);
            }
        }
    }

    /**
     * 返回点所在象限的左上角坐标
     *
     * @param xCenter 中心坐标
     * @param yCenter 中心坐标
     * @param x       点坐标
     * @param y       点坐标
     * @param len     长度,pow的一半
     * @return n0 x,n1 y
     */
    private int[] at(int xCenter, int yCenter, int x, int y, int len, int size) {
   
        int[] n = new int[2];
        n[0] = x >= xCenter ? xCenter : xCenter - len * size;
        n[1] = y >= yCenter ? yCenter : yCenter - len  * size;
        return n;
    }

    public static void main(String[] args) {
   
        launch(args);
    }
}