Board logo

标题: [游戏娱乐] 批处理生成UBB彩虹代码 [打印本页]

作者: CrLf    时间: 2015-12-26 05:03     标题: 批处理生成UBB彩虹代码

本帖最后由 CrLf 于 2015-12-26 05:16 编辑

改进自:http://www.bathome.net/redirect. ... id=38720&pid=179971
优化算法,提升效率,平衡取值,并加上了详细注释

....................................................................................................................................................................................................
....................................................................................................................................................................................................
....................................................................................................................................................................................................
....................................................................................................................................................................................................
....................................................................................................................................................................................................
....................................................................................................................................................................................................
....................................................................................................................................................................................................
....................................................................................................................................................................................................
....................................................................................................................................................................................................
....................................................................................................................................................................................................
....................................................................................................................................................................................................
....................................................................................................................................................................................................
....................................................................................................................................................................................................
....................................................................................................................................................................................................
....................................................................................................................................................................................................
....................................................................................................................................................................................................
....................................................................................................................................................................................................
....................................................................................................................................................................................................
....................................................................................................................................................................................................
....................................................................................................................................................................................................
....................................................................................................................................................................................................


代码和详解:
  1. @echo off & setlocal enabledelayedexpansion
  2. rem 此处变量用于设置彩虹的各项参数
  3. set /a n1=400,n2=250
  4. rem n1 = 大圆半径
  5. rem n2 = 小圆半径
  6. set /a Lines=350
  7. rem Lines = 彩虹行数
  8. set /a stepCol=4,stepRow=17
  9. rem stepCol = 列的间隔比例,用于定义一个字符的宽度对应半径中多少点
  10. rem stepRow = 行的间隔比例,用于定义一个字符的高度对应半径中多少点
  11. rem 关键代码从这里开始
  12. if !stepCol! lss !stepRow! (
  13.         set /a stepTest=stepCol
  14. ) else (
  15.         set /a stepTest=stepRow
  16. )
  17. rem 若列的间隔小于行,则将在 x 轴上计算 RGB,否则在 y 轴上计算
  18. rem 选用最小的间隔可以保证在计算 RGB 时取得较大的精度
  19. set "Count=0"
  20. rem Count 变量用于统计取样计算的 r2 和 RGB 总数
  21. for /l %%b in (0 %stepTest% %n1%) do (
  22.         rem 从原点出发在 x 轴或 y 轴上的半径范围内取样
  23.         set /a r1=%%b*%%b-n1*n1
  24.         rem r1 是该点上勾股算法的结果,用于判断是否在大圆内
  25.         if !r1! leq 0 (
  26.                 rem 若在大圆内,则再进行小圆判断
  27.                 set /a r2=%%b*%%b-n2*n2
  28.                 rem r2 是该点上勾股算法的结果,用于判断是否在小圆内
  29.                 if !Count!==0 set /a rMin=r[0]=!r2!
  30.                 rem 若没有触碰过小圆,则记录 r2 为最小值,并顺便设置 r[0]
  31.                 if !r2! geq 0 (
  32.                         rem 若在小圆内,则进行记录
  33.                         set /a Count+=1,rMax=r2
  34.                         rem Count 加一,并记录 r2 为最大值
  35.                         for %%z in (!Count!) do set "r[%%z]=!r2!"
  36.                         rem 记录 r2 到 r[*] 变量组
  37.                 )
  38.         )
  39. )
  40. for /l %%a in (1 1 7) do set /a "p%%a=Count-(7-%%a)*Count/7"
  41. rem 计算将 Count 切分为 7 段时每段的边界,并保存在 p* 变量组
  42. for /l %%z in (0 1 !Count!) do (
  43.         rem 对 r[*] 中的每一个 r2 计算对应 RGB 值
  44.         set /a R=G=B=0
  45.         rem 初始化 R G B 变量,默认为 0
  46.         if %%z lss !p2! set /a "R=255-255*(%%z)/(p2)"
  47.         if %%z geq !p3! if %%z lss !p4! set /a "R=(255*(%%z-p3)/(p4-p3))"
  48.         if %%z geq !p4! set /a "R=255"
  49.         rem 计算 R 值:
  50.         rem 0~1 段 : 0xff -> 0x00
  51.         rem 3~4 段 : 0x00 -> 0xff
  52.         rem 4~7 段 :         0xff
  53.         if %%z lss !p2! set /a "G=255*(%%z)/(p2)"
  54.         if %%z geq !p2! if %%z lss !p4! set /a "G=255"
  55.         if %%z geq !p4! if %%z lss !p7! set /a "G=255-255*(%%z-p4)/(p7-p4)"
  56.         rem 计算 G 值:
  57.         rem 1~2 段 : 0x00 -> 0xff
  58.         rem 2~4 段 :         0xff
  59.         rem 4~7 段 : 0xff -> 0x00
  60.         if %%z lss !p2! set /a "B=255"
  61.         if %%z geq !p2! if %%z lss !p3! set /a "B=255-255*(%%z-p2)/(p3-p2)"
  62.         rem 计算 B 值:
  63.         rem 0~2 段 :         0xff
  64.         rem 2~3 段 : 0xff -> 0x00
  65.         set /a RGB=R*256*256+G*256+B
  66.         rem 组合 RGB 值
  67.         cmd /c "exit /b %%RGB%%"
  68.         set "RGB[%%z]=#!=ExitCode:~-6!"
  69.         rem 转 16 进制并截取后 6 位,保存到 RGB[*] 数组中
  70. )
  71. set /a StartRow=stepCol/2-n1
  72. set /a StartCol=stepRow/2
  73. rem 计算起始点
  74. rem 为了尽量避免出现单点的行,从小圆半径向外偏移半步处开始计数
  75. set /a EndRow=Lines-n1
  76. set /a EndCol=n1-stepCol/2
  77. rem 计算终止点
  78. rem 在大圆半径向内偏移半步处终止
  79. (for /l %%a in (%StartRow% %stepRow% %EndRow%) do (
  80.         rem 从顶部遍历到 Lines 指定的位置
  81.         set "ubb="
  82.         rem 在行首将 ubb 变量设置为空
  83.         for /l %%b in (%StartCol% %stepCol% %EndCol%) do (
  84.                 rem 从原点偏半步处向右计算,将计算的结果左右对称,以减半计算量
  85.                 set "fontcolor=white"
  86.                 rem 字体颜色默认为白
  87.                 set /a r2=%%a*%%a+%%b*%%b-n2*n2
  88.                 rem 计算 r2,用于和前面生成的索引进行比对
  89.                 if !r2! geq !rMin! if !r2! leq !rMax! (
  90.                         rem 如果 r2 在最大值和最小值之间,则判断该点离圆心的距离最接近 r[*] 中的哪个点
  91.                         for /l %%z in (0 1 !Count!) do (
  92.                                 if !r[%%z]! leq !r2! set "fontcolor=!RGB[%%z]!"
  93.                                 rem 根据比对结果的索引号到 RGB[*] 数组中取得相应 RGB 值
  94.                         )
  95.                 )
  96.                 set "ubb=[color=!fontcolor!].[/font]!ubb![color=!fontcolor!].[/font]"
  97.                 rem 将结果对称附加到该行 ubb 左右
  98.         )
  99.         echo;!ubb!
  100.         rem 输出该行 ubb
  101. )) >ubb.txt
  102. start ubb.txt
  103. rem ......
复制代码

作者: aa77dd@163.com    时间: 2015-12-26 18:04

本帖最后由 aa77dd@163.com 于 2015-12-26 18:09 编辑

我用了一个位运算选择器:
令 t 的可选值为 0 或者 -1,
~t & a | t & b
上式的值: 当 t = 0, 得 a; 否则, 得 b

这个选择器可以多层嵌套
~t & a | t & (~t1 & b | t1 & c) 以此类推

这样多层嵌套后, 就可以实现在小范围内索引区间搜索, 最开始我也想用 for + if 的方式实现, 然后又觉得效率不高, 特别是批处理的 for 代码在退出前 都不能 break

但 set /a 构造 的这种多层嵌套选择器 是否 比 for + if 效率要高, 也只是我想当然, 实际上我并没有测试比较过

以下示例 在 5 个数中找出 不大于 x 的最大的一个数
  1. @echo off
  2. setlocal enableDelayedExpansion
  3. set "@1=18225"
  4. set "@2=17956"
  5. set "@3=17689"
  6. set "@4=17424"
  7. set "@5=17161"
  8. set "exp=0"
  9. for /L %%i in (5 -1 1) do (
  10.     set "exp=t=x-@%%i>>31,~t&@%%i|t&(!exp!)"
  11. )
  12. set exp
  13. set /a "x=17688,result=(%exp%)"
  14. set result
  15. pause
  16. exit
复制代码

作者: CrLf    时间: 2015-12-26 20:30

本帖最后由 CrLf 于 2015-12-26 21:28 编辑

回复 2# aa77dd@163.com


    位运算是不错,应该比 if 快
    再优化一下,!(@%%i/t) 仔细想一想还是减法配合 >> 更快




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2