rewrite swinemeeper autoreveal in assembly
This commit is contained in:
parent
f45d523bdd
commit
8afdda713d
3
asm.jrt
3
asm.jrt
|
@ -301,6 +301,7 @@ var ignoreimm
|
|||
arg2 oparg-reg? oparg-val @ 0x00 = and arg1 oparg-wreg? and
|
||||
if 0x90 >wreg+op* then
|
||||
0x86 >bar-war* ;
|
||||
|
||||
2 :op MOV
|
||||
0x88 >bmr-wmr-brm-wrm*
|
||||
arg2 oparg-imm? arg1 if
|
||||
|
@ -325,6 +326,8 @@ var ignoreimm
|
|||
2 :op RCR 3 >grp2* ; 2 :op SHL 4 >grp2* ; 2 :op SHR 5 >grp2* ;
|
||||
2 :op SAR 7 >grp2* ;
|
||||
|
||||
2 :op TEST 0x84 >bar-war* 0 >grp3* ;
|
||||
|
||||
1 :op NOT 2 >grp3* ; 1 :op NEG 3 >grp3* ; 1 :op MUL 4 >grp3* ;
|
||||
1 :op IMUL 5 >grp3* ; 1 :op DIV 6 >grp3* ; 1 :op IDIV 7 >grp3* ;
|
||||
|
||||
|
|
BIN
assemble.com
BIN
assemble.com
Binary file not shown.
99
swine.jrt
99
swine.jrt
|
@ -92,18 +92,91 @@ array board maxw maxh * allot
|
|||
dup mine? if lose then FREVEALED swap b!|
|
||||
else drop then ;
|
||||
|
||||
: visibly-empty? dup revealed? swap squarecount not and ;
|
||||
: backtrack-square ( p -- p ) boardw @ - 1- dup board < if drop board then ;
|
||||
: backtrack? ( p -- f )
|
||||
dup revealed? over 1+ revealed? and swap 2 + revealed? and not ;
|
||||
: autoreveal-backtrack ( -- )
|
||||
i visibly-empty? i backtrack-square backtrack? and
|
||||
if i backtrack-square 1- idrop >i then ;
|
||||
: autoreveal ( -- )
|
||||
iterboard each i revealed? not if
|
||||
i ' visibly-empty? count-neighbours
|
||||
if i reveal autoreveal-backtrack then
|
||||
then next ;
|
||||
var autoreveal-count
|
||||
( autoreveal: Happens row-at-a-time in optimized machine code.
|
||||
ar-check-dir: a strip of squares is checked for visibly empty neighbours
|
||||
against its corresponding square in a given direction, specified with BX.
|
||||
autoreveal-count is incremented whenever a new square is revealed.
|
||||
The strips are carefully constructed so as to not step over the edge of
|
||||
the board.
|
||||
This is _not_ a Forth word, it's called with CALL by the words below.
|
||||
autoreveal-row-above: check the nw, n, and ne squares with ar-check-dir.
|
||||
autoreveal-row-horiz: check the w and e squares with ar-check-dir.
|
||||
autoreveal-row-below: check the sw, s, and se squares with ar-check-dir.
|
||||
autoreveal-fast: iterates over the rows of the board and checks each row
|
||||
against itself and the strips above and below. If anything new is
|
||||
autorevealed in the current row, we check the previous row again. )
|
||||
|
||||
L: ar-check-dir
|
||||
( in: DI - row to reveal
|
||||
BX - offset of row to check
|
||||
CH - 0, CL - count of squares to check
|
||||
out: DI, BX, CX - preserved
|
||||
trampled: AX, DX )
|
||||
MOV AX DS
|
||||
MOV ES AX
|
||||
MOV AL FREVEALED # ( AL - byte value of visibly empty square )
|
||||
( DI is now row to check, BX+DI is row to reveal )
|
||||
MOV DH CL
|
||||
ADD DI BX
|
||||
NEG BX
|
||||
DEC BX ( DI will be one past the square that was checked when SCASB returns )
|
||||
0 :>
|
||||
JCXZ 2 @> ( end of row, exit )
|
||||
REPNZ SCASB ( search for visibly empty square )
|
||||
JNZ 1 @> ( none found, exit )
|
||||
MOV DL @[ BX+DI]
|
||||
TEST DL AL
|
||||
JNZ 0 <@ ( already revealed, keep searching )
|
||||
OR DL AL
|
||||
AND DL FFLAG ~ #
|
||||
MOV @[ BX+DI] DL
|
||||
INC @[ autoreveal-count @]
|
||||
JMP 0 <@
|
||||
1 <: 2 <:
|
||||
( revert DI, BX and CX to previous value )
|
||||
MOV CL DH
|
||||
SUB DI CX
|
||||
INC BX
|
||||
ADD DI BX
|
||||
NEG BX
|
||||
RET
|
||||
|
||||
:asm autoreveal-row-above ( p -- )
|
||||
POP DI
|
||||
MOV CX @[ boardw @]
|
||||
MOV BX CX NEG BX ( directly above )
|
||||
CALL ar-check-dir
|
||||
L: autoreveal-left-right
|
||||
DEC CX INC BX ( to the right )
|
||||
CALL ar-check-dir
|
||||
DEC BX DEC BX INC DI ( to the left )
|
||||
CALL ar-check-dir
|
||||
NEXT
|
||||
|
||||
:asm autoreveal-row-horiz ( p -- )
|
||||
POP DI
|
||||
MOV CX @[ boardw @]
|
||||
XOR BX BX ( on the current square )
|
||||
JMP autoreveal-left-right
|
||||
|
||||
:asm autoreveal-row-below ( p -- )
|
||||
POP DI
|
||||
MOV CX @[ boardw @]
|
||||
MOV BX CX ( directly below )
|
||||
CALL ar-check-dir
|
||||
JMP autoreveal-left-right
|
||||
|
||||
: autoreveal-fast
|
||||
iterrows each
|
||||
0 autoreveal-count !
|
||||
i autoreveal-row-horiz
|
||||
i board > if i autoreveal-row-above then
|
||||
i lastrow? not if i autoreveal-row-below then
|
||||
i board > autoreveal-count @ and if
|
||||
( backtrack ) <i boardw @ 2* - >i
|
||||
then
|
||||
next ;
|
||||
|
||||
: won? ( -- f )
|
||||
1 iterboard each i b@ FMINE FREVEALED | & not if not break then next ;
|
||||
|
@ -114,7 +187,7 @@ array board maxw maxh * allot
|
|||
if click neighbours each i reveal next else drop then ;
|
||||
: reveal-at square-at dup revealed?
|
||||
if reveal-unflagged-neighbours? else reveal click then
|
||||
autoreveal check-win ;
|
||||
autoreveal-fast check-win ;
|
||||
: flag-noise ( p -- ) b@ FFLAG & if moop else meep then ;
|
||||
: flag-at square-at dup revealed? not
|
||||
if FFLAG swap dup flag-noise b!^ else drop then ;
|
||||
|
|
BIN
zipoff.com
BIN
zipoff.com
Binary file not shown.
BIN
zipstub.seg
BIN
zipstub.seg
Binary file not shown.
Loading…
Reference in a new issue