zoukankan      html  css  js  c++  java
  • 迷宫塔生成工具

    迷宫塔生成工具

    迷宫塔生成工具

    1 简介

    使用Clojure生成迷宫,然后把许多个迷宫的每一层解密路径作为zip密码,生成一个迷宫套娃。 迷宫生成的代码来自github

    主要是练习gui开发,使用cljfx库(包装了JavaFX)进行界面开发,使用起来还不是很顺手,与seesaw相比,没有seesaw与swing的配合方式用起来爽。不过响应式界面是现在的流行,有一些界面刷新的问题,使用了才知道,cljfx的事件处理方式不是很好用,也不能做到事件嵌套。用text-area实现一个日志输出窗口,折腾了很久也没弄好,滚动条逻辑不好实现。

    https://img2018.cnblogs.com/blog/1545892/202002/1545892-20200207000202889-1626391481.jpg

    图1  程序主界面

    首先设置好一系列参数,点生成,就可以生成相应数量的迷宫图片。

    再设置迷宫塔的生成参数,选择最顶层包含的文件,然后生成迷宫塔,注意迷宫塔文件的保存格式必须是图片:.png或.jpg后缀的文件,保存后会有一个同名的.pass.txt为解密密码文件,按照顺序每一层的zip密码与之对应。

    整个项目的代码文件

    2 范围值的使用

    因为要随机生成行数,列数,和路径长度等,需要提供范围值。范围值可以是一个数值(固定值),也可以是指定[min max]最小最大范围的区间值(取范围内一个随机整数),也可以是数值集合(随机从集合中取一个数值)。

    (defn range?
      "range-v是否为一个范围值"
      [range-v]
      (or (number? range-v)
          (set? range-v)
          (and (seqable? range-v)
               (= 2 (count range-v))
               (>= (second range-v)
                   (first range-v)))))
    
    (defn range-value
      "获取一个范围数字
      如果是数字n,则为固定的n
      如果是[x y] 则为x-y之间的随机数,包含x和y
      如果是#{a b ...} 集合,则为任意一个集合中的数字"
      [range-v]
      {:pre [(range? range-v)]}
      (cond
        (set? range-v)
        (rand-nth (vec range-v))
    
        (seqable? range-v)
        (let [[x y] range-v]
          (+ x
             (rand-int (inc (- y x)))))
    
        :else range-v))
    
    (defn in-range?
      "数字i是否在范围值range-v中 "
      [i range-v]
      {:pre [(int? i)
             (range? range-v)]}
      (cond
        (set? range-v)
        (range-v i)
    
        (seqable? range-v)
        (let [[x y] range-v]
          (<= x i y))
    
        :else (= i range-v)))
    
    (defn parse-range
      "解析范围数字,可以是单个数字,或者是x-y之间的范围,或者是a,b,c数字集合"
      [s]
      (let [s (str/trim s)]
        (if-let [grps (re-matches #"s*(d+)s*-s*(d+)s*" s)]
          [(Integer/parseInt (second grps))
           (Integer/parseInt (last grps))]
          (let [grps (str/split s #"s*,s*")]
            (if (> (count grps) 1)
              (-> (map #(Integer/parseInt %) grps)
                  set)
              (-> (first grps)
                  (Integer/parseInt)))))))
    
    (defn range->str
      "范围值转换为字符串表示"
      [range-v]
      {:pre [(range? range-v)]}
      (cond
        (set? range-v)
        (str/join "," range-v)
    
        (seqable? range-v)
        (str/join "-" range-v)
    
        :else (str range-v)))
    

    通过界面设置范围值需要提供value-converter,在views中实现。

    (def range-value-converter
      (proxy [StringConverter] []
        (fromString [s]
          (util/parse-range s))
        (toString [v]
          (util/range->str v))))
    

    3 combo-box的value-converer

    对于需要转换值和界面显示字符串的部分,JavaFX提供了StringValueConverter。 但是对于combo-box, converter处理的时候没有包含异常处理,如果输入值不合法就抛出异常。 需要自己进行包装。

    (defn non-exception-long-converter
      "不抛出异常的转换器,可提供默认值,出现异常则使用默认值"
      ([] (non-exception-long-converter 0))
      ([default]
       (proxy [StringConverter] []
         (fromString [s]
           (try
             (Long/parseLong s)
             (catch Exception e default)))
         (toString [v]
           (str v)))))
    

    4 项目打包

    直接用lein uberjar打包后,发现在windows下执行会报错:

    Graphics Device initialization failed for :  d3d, sw
    Error initializing QuantumRenderer: no suitable pipeline found
    

    原因是JavaFX的windows依赖没有添加,在project.clj中添加依赖即可提供对windows的支持,mac系统也类似:

    ;; 添加JavaFX的windows和mac系统支持
    [org.openjfx/javafx-graphics "13" :classifier "win"]
    [org.openjfx/javafx-graphics "13" :classifier "mac"]
    

    打包之后的jar文件有50M,已经包含了openjfx库,但是不包含jdk,加上jdk打包成独立可执行文件的话,也有80M左右了,Java写桌面GUI还是太巨大了,最后的可执行程序大小与Electron程序差不多。

    通过去掉没有使用的openjfx依赖,主要是webkit,使打包后的文件体积从50M降到20M,主要是webkit太大了,就是内嵌一个浏览器。

    提供一个打包好的release:微云下载,最低需要jdk 11才能正常运行,已添加windows、mac下的依赖包,可直接运行。

    作者: ntestoc

    Created: 2020-02-07 五 00:01

  • 相关阅读:
    mui 点击输入框软键盘弹起解决
    Vue中form表单常用rules校验规则
    ios new Date('yyyy-MM-dd HH-mm-ss').getTime() 方法获取不到时间戳
    uni-app运行到手机报错 Component constructors should be called while initialization. A constructor call has been ignored.
    vue-element-admin后台 点击侧边栏 刷新当前路由
    vue 防抖和节流
    vue data数据变化 页面数据不更新问题
    uni-app中页面部分内容使用索引列表(uni-indexed-list),动态数据
    css 文本单行显示溢出时出现省略号 多行显示溢出时出现省略号 首行缩进
    css实现两个div并排等高(一个div高度随另一个高度变化而变化)
  • 原文地址:https://www.cnblogs.com/ntestoc/p/12271251.html
Copyright © 2011-2022 走看看