『第 35 楼』:
使用 LLM 解释/回答一下
原来已经发重了,算了,把一些错别字改改。。。
批处理推箱子源码解释:
1、数据定义的紧凑格式的使用
先把变量定义集放到变量:(要注意分隔符是唯一的,这里用“;”号)
set a=a=i75;b=i79;str=abc
这样变量a的值为:a=i75;b=i79;str=abc
利用预处理时变量值替换:
set %a:;=&set %
相当于以下语句被执行:
set a=i75&set b=i79&set str=abc
或者:
set a=i75
set b=i79
set str=abc
如果要定义的变量很多,综合从占用空间和可读性上看,此法有明显的优势。
2、推箱子程序实现算法
1). 读取关级数据放到数组:lev(n)
改变n的值,即为改变关级,这里 n即%lev%
2). 把当前关地图数据还原并存到二维数组:r(n).(m),
(一) 把值为坑“☆”的变量名r(n).(m),集放到变量ke,并把“☆”的个数存到变量ji,同时转为“★”;注意:ke保存的是变量名,不是变量值。
%ke%扩展后就是源值为坑“☆”的所有二维变量的实时的值了;只要%ke% 等于 !ji! 表明过关了
(二) 按行把二维变量名存为数组:r(n),注意:是变量名
%r(n)%扩展后即为第n行的所有二维数组的实时值
3). 变量ebuf作为显示缓存,所有要显示的内容全部存到ebuf,一次性用echo !ebuf!全部显示完成。实现快速刷屏。
因为for 变量 %%a 在扩展后,会再次扩展值中的!号变量,所以:
for /l %%a in (1,1,!r!) do for %%b in ("!r%%a!") do set ebuf=!ebuf! %%~b!cr!
上面依次把:1到!r!行的变量名数组r(n)扩展后的值,全部存到显示缓存ebuf内,并且加上了换行符!cr!
4).首先定义好按上下左右所进行的操作:
"c1=n-;c2=m-;c3=n+;c4=m+"
这样就可以通过下面代码:
set/a sm=m,sn=n,!c%in%!=1,bm=m,bn=n,!c%in%!=1
分别取得按了 上/下/左/右 后,源点:sm.sn,步进一:bm.bn,步进二:m.n,三个坐标的值
for /f "tokens=1,2" %%a in ("!r%bn%.%bm%! !r%bn%.%bm%!!r%n%.%m%!") do (
取出三个坐标的值并摆开为:(步进一 => %%a) (步进一+步进二 =>%%b) 例如:%%a=▓ %%b=▓∷
***各种可移动的组合类型在前面已经为变量***
***未定义的测视为不能移动的组合***
for %%c in ("!%%a!!%%b!") do (
%%a %%b 经再扩展后,组后到%%c, 接上例:!▓! =>空, !▓∷! =>▓-∷
则: ▓-∷ => %%c
for /f "tokens=1,2 delims=-" %%1 in (%%c) do (
摆开为:%%1=▓,%%2=∷
接下来就 if 判断了,根据各种情况把三个点和一个“大”站的!源!点的值重新调整
注意:有一点,如果%%c的值为空,如 %%b=▓■ 为时,则这个for将是空转,即连里面的if语句也不会被执行,
使得后面的 set/a m=sm,n=sn 被执行了,还原了m,n,即不能动
3、关级数据压缩与还原
1).压缩,因全角为双字节,用单字转换后可以少一半,如果 ▓=a,zf=▓,则:set zf=!%af%! 就可转过来了
如果不只一个,有连续的则在字母后跟个数字表示个数,如:a4,超过9个则另起一组,如:a11,则拆为a9a2
2).还原,引用:囧开头的好处,
for /f "tokens=2* delims=囧" %%a in (%~nx0) do (set lev!n!=%%a&set/a n+=1)
这样在读取时可以减去了对其它非数据行的读取,加快了速度
同样的方法把字符转换回来,再把数字作为for /l 计数重复即可全部转换
if "!tn:%%2=!" neq "!tn!" (set k=%%2) else (set k=1)
for /l %%k in (1,1,!k!) do (
上面的!k!即为连续字符的个数
4、摆脱choice.exe 和 刷屏不闪
就是用debug.exe 来替了,但这个是通常系统都会自带的,所以。。三方。。。
debug <%~nx0>nul
调用自身作为管道输入,第一行是出错的,真正有用的只有两行
e 100 cd 16 86 c4 b4 02 cd 10 b4 4C CD 21 写入代码
g 执行
这里面进行了键读取,把当前光标位置设为第一行,第一列,并把按键数据作为返回码到:%errorlevel%
定义:"a=i83=10;i1=7;i72=1;i80=3;i75=2;i77=4;i73=8;i81=9;i57=5;i79=6"
执行:set in=!i%errorlevel%!
就可以根据定义得到相应按键,如果未定义的则为空
平时写批处理要回到第一行显示时,只有用cls,然后再显示,显然速度也很快,还是觉得有点闪。
直接把光标重置到第一行,第一列,并没有清屏,再次显示时是在原来的基础上的,所以少了闪的感觉
如果要看汇编源码,很简单,把debug <%~nx0>nul后面的>nul去掉,再在e 行和g 行间加入一行u 就可以了
5、玩家记录保存,与读取
这里是把记录存在批处理的第一行,
1).读取
set/p yg=< %~nx0 >nul
取第一行到变量 yg
set yg=!yg:~13,52!
set lev=%yg:@=&rem %
因为当前关记录和已过关的记录是以@为分隔的,这样可以只把@前面部分给lev,@后面的被rem 注释掉了
set yg= !yg:* =!
取已过关的数据,并且保持前后必须有空格
这样就已经把当前关,及已经过了的关的数据全部读取到变量了
2).保存
set a=a 10d`db "!lev!@!yg! "``w`q
(echo %a:`=&echo;%)|debug %~nx0 >nul
经扩展为:
(echo a 10d&echo;db "!lev!@!yg! "&echo;&echo;w&echo;q)|debug %~nx0 >nul
实际上是把以下命令行递给debug 去执行:
a 10d
db "!lev!@!yg! "
w
q
利用了debug 的a命令输入汇编指令时,可以用db 定义字符串,然后直接用W命令可以写打开的文件
并且批处理程序在执行过程中,是可以修改自身的
Last edited by netbenton on 2009-10-5 at 15:46 ]
The original has been duplicated, forget it, just correct some typos...
Explanation of Batch Push-Square Source Code:
1. Use of Compact Format for Data Definition
First, put the variable definition set into a variable: (Note that the delimiter is unique, here using the ";" sign)
set a=a=i75;b=i79;str=abc
So the value of variable a is: a=i75;b=i79;str=abc
Use variable value replacement during preprocessing:
set %a:;=&set %
Equivalent to the following statements being executed:
set a=i75&set b=i79&set str=abc
Or:
set a=i75
set b=i79
set str=abc
If there are many variables to define, comprehensively considering from the perspective of occupied space and readability, this method has obvious advantages.
2. Implementation Algorithm of Push-Square Program
1). Read the level data into the array: lev(n)
Change the value of n, which is to change the level, here n is %lev%
2). Restore the current level map data and store it in the two-dimensional array: r(n).(m)
(1) Collect the variable names r(n).(m) with the value "☆" into variable ke, and store the number of "☆" into variable ji, and convert them to "★" at the same time; Note: ke saves the variable name, not the variable value.
%ke% expansion later is the real-time value of all two-dimensional variables with the source value "☆"; as long as %ke% is equal to !ji! indicates that the level is passed
(2) Store the two-dimensional variable names as an array: r(n) by row, Note: it is the variable name
%r(n)% expansion later is the real-time value of all two-dimensional arrays in row n
3). Variable ebuf is used as a display buffer, all content to be displayed is stored in ebuf, and all is displayed at once with echo !ebuf! to achieve fast screen refresh.
Because after expansion of for variable %%a, the! number variables in the value will be expanded again, so:
for /l %%a in (1,1,!r!) do for %%b in ("!r%%a!") do set ebuf=!ebuf! %%~b!cr!
The above sequentially stores the expanded values of the variable name array r(n) from row 1 to!r! into the display buffer ebuf, and adds the newline character!cr!
4). First define the operations for up, down, left and right:
"c1=n-;c2=m-;c3=n+;c4=m+"
In this way, the following code can be used:
set/a sm=m,sn=n,!c%in%!=1,bm=m,bn=n,!c%in%!=1
Respectively obtain the source point: sm.sn, step one: bm.bn, step two: m.n, the values of the three coordinates after pressing up/down/left/right
for /f "tokens=1,2" %%a in ("!r%bn%.%bm%! !r%bn%.%bm%!!r%n%.%m%!") do (
Take out the values of the three coordinates and spread them out as: (step one => %%a) (step one + step two =>%%b) For example: %%a=▓ %%b=▓∷
***Various movable combination types have been variables before***
***The undefined ones are considered as non-movable combinations***
for %%c in ("!%%a!!%%b!") do (
%%a %%b is re-expanded and grouped to %%c, connected with the previous example:!▓! => empty,!▓∷! =>▓-∷
Then: ▓-∷ => %%c
for /f "tokens=1,2 delims=-" %%1 in (%%c) do (
Spread out as: %%1=▓, %%2=∷
Next is the if judgment, and according to various situations, the values of the three points and a "big" standing! source! point are readjusted
Note: There is one point, if the value of %%c is empty, such as %%b=▓■, then this for will be idle, that is, even the following if statement will not be executed, making the following set/a m=sm,n=sn be executed, restoring m,n, that is, cannot move
3. Compression and Restoration of Level Data
1). Compression, because full-width is double-byte, using single character conversion can be reduced by half, if ▓=a, zf=▓, then: set zf=!%af%! can be converted back
If there is not only one, and there are consecutive ones, then a number is added after the letter to indicate the number of times, such as: a4, if it exceeds 9 times, then another group is started, such as: a11, then split into a9a2
2). Restoration, reference: the advantage of starting with 囧,
for /f "tokens=2* delims=囧" %%a in (%~nx0) do (set lev!n!=%%a&set/a n+=1)
In this way, when reading, the reading of other non-data lines can be subtracted, and the speed is accelerated
Similarly, convert the characters back, and then use for /l counting to repeat to convert all
if "!tn:%%2=!" neq "!tn!" (set k=%%2) else (set k=1)
for /l %%k in (1,1,!k!) do (
The above!k! is the number of consecutive characters
4. Get rid of choice.exe and no flickering when refreshing the screen
That is to use debug.exe instead, but this is usually built into the system, so third-party...
debug <%~nx0>nul
Call itself as pipeline input, the first line is wrong, only two lines are really useful
e 100 cd 16 86 c4 b4 02 cd 10 b4 4C CD 21 Write code
g Execute
Here, key reading is performed, the current cursor position is set to the first line, first column, and the key data is used as the return code to: %errorlevel%
Definition: "a=i83=10;i1=7;i72=1;i80=3;i75=2;i77=4;i73=8;i81=9;i57=5;i79=6"
Execute: set in=!i%errorlevel%!
You can get the corresponding key according to the definition, if it is not defined, it is empty
Usually when writing a batch processing to return to the first line to display, only cls is used, and then display, obviously the speed is also very fast, but still feel a little flickering.
Directly reset the cursor to the first line, first column, without clearing the screen, and when displaying again, it is on the original basis, so the feeling of flickering is less
If you want to see the assembly source code, it is very simple, remove >nul after debug <%~nx0>nul, and then add a line u between the e line and the g line
5. Player record saving and reading
Here, the record is stored in the first line of the batch processing,
1). Reading
set/p yg=< %~nx0 >nul
Take the first line to variable yg
set yg=!yg:~13,52!
set lev=%yg:@=&rem %
Because the current level record and the passed level record are separated by @, in this way, only the part before @ is given to lev, and the part after @ is commented out by rem
set yg= !yg:* =!
Take the passed data, and keep that there must be spaces before and after
In this way, the data of the current level and the passed levels has been read into the variable
Last edited by netbenton on 2009-10-5 at 15:46 ]
|