'88 Quickscanner:'94 Quickscanner:Description The Q^1-Scan The Q^2-Scan (I) The Q^2-Scan (II) The Q^2-Scan (III) The Q^3 and Mini-Q^3 The Q^4 and Q^4.5 Qscanner for Tiny Hill Qscanner for Nano Hill Webmaster: fizmo_master@yahoo.com
Created by Christian Schmidt, 2002,2003,2004 |
The Q^3 and Mini-Q^3 The Q^3 Snippet... ;; ;; quickscanner ;; start EQU boot ; first instruction of this warrior qStep EQU 5400 ; distance between two scans qHop EQU 1300 ; scan distance within a scan for 25 dat.f 0, 0 rof ;; decoding table dat.f 15, 10 ; A, D qTab dat.f 7, 4 ; B, E dat.f 13, 11 ; C, F qGo ... ;; found nothing -> boot paper ... ;; decoder attack2 mul.b qTab, found attack1 mul.ab qTab, @ attack2 ;; choose between the two possible positions qSelect sne.i (start - 1), @ found ; use 1st position? add.ab # qHop, found ; no, use 2nd! ;; prepare bombing adjust add.ba found, found ;; bombing engine IV qTimes EQU 20 ; number of bombs to throw qStep2 EQU 4 ; distance between bombs throw mov.i qBomb, @ found mov.i qBomb, * found found mov.i -qStep2, @ qStart ; <-- CHANGED AGAIN add.f qIncr, found djn.b throw, # 20 jmp boot ; start paper qBomb dat.f # 0, # qStep2 qIncr dat.f # -qStep2, # 2*qStep2 ...I've taken the liberty to use the bombing engine IV, that we have used along with the last versions of YAP. Puddleglum uses a 0.5c negative bomber, which doesn't need the extra line at "adjust". This means, that the average number of cycles before an attack in Puddleglum starts is 1 cycle lower than in the version, that I present here. Let's look at the scans (without 1-cycle-attacks): ... qGo seq found+1*qStep, found+1*qStep+qHop ; 1 jmp qSelect ...This is the usual scan without decoding. During the following scans there are a lot gaps, which the decoder cannot handle. I will not mention this anymore, because you should be quite familar with the problem now. ... seq found+3*qStep, found+3*qStep+qHop ; E-1 jmp > attack1, < qTab seq found+4*qStep, found+4*qStep+qHop ; E jmp > attack1 seq found+5*qStep, found+5*qStep+qHop ; E+1 jmp > attack1, > qTab seq found+6*qStep, found+6*qStep+qHop ; B-1 jmp attack1, { qTab seq found+7*qStep, found+7*qStep+qHop ; B jmp attack1 seq found+8*qStep, found+8*qStep+qHop ; B+1 jmp attack1, } qTab seq found+9*qStep, found+9*qStep+qHop ; D-1 djn.b > attack1, { attack2 seq found+10*qStep, found+10*qStep+qHop ; D jmp > attack1, { attack2 seq found+11*qStep, found+11*qStep+qHop ; F jmp > attack1, } attack2 seq found+13*qStep, found+13*qStep+qHop ; C jmp attack1, } attack1 seq found+14*qStep, found+14*qStep+qHop ; A-1 djn.a attack1, { attack1 seq found+15*qStep, found+15*qStep+qHop ; A jmp attack1, { attack1 seq found+18*qStep, found+18*qStep+qHop ; B*E+1-B-E djn.f attack2, qTab seq found+21*qStep, found+21*qStep+qHop ; B*E-B jmp attack2, < qTab seq found+24*qStep, found+24*qStep+qHop ; B*E-E jmp attack2, { qTab seq found+32*qStep, found+32*qStep+qHop ; B*E+E jmp attack2, } qTab seq found+35*qStep, found+35*qStep+qHop ; B*E+B jmp attack2, > qTab seq found+39*qStep, found+39*qStep+qHop ; C*E-C djn.b attack2, } attack1 seq found+52*qStep, found+52*qStep+qHop ; C*E jmp attack2, } attack1 seq found+56*qStep, found+56*qStep+qHop ; A*E-E djn.a attack2, { attack1 seq found+60*qStep, found+60*qStep+qHop ; A*E jmp attack2, { attack1 seq found+63*qStep, found+63*qStep+qHop ; B*D-B djn.b attack2, { attack2 seq found+66*qStep, found+66*qStep+qHop ; B*F-F djn.a attack2, } attack2 seq found+70*qStep, found+70*qStep+qHop ; B*D jmp attack2, { attack2 seq found+77*qStep, found+77*qStep+qHop ; B*F jmp attack2, } attack2 ...In previous quickscanners the scanned locations were all relative to the beginning of the warrior. Because we can no longer add a value to the first scanned position, it is necessary to make the scanned position relative to the label "found". Now we find an interesting idea: ... sne found+28*qStep, found+28*qStep+qHop ; B*E jmz boot, found+28*qStep+qHop-10 ...Normally we would just add a "jmp boot" to the end of the scan, but if the scan is immediately followed by the decoder, we have a restricted free scan. It is restricted to a position near (found+28*qStep+qHop), but it is free. Before I start to benchmark this quickscan, I have to address a problem when creating quickscanners. As you have seen they become more and more complex and it is therefore quite probable, that they contain bugs. If your quickscanner bombs the found position and not only near it, there is a simple test for your quickscanner (CoreWarrior #84). Append your quickscanner to a "jmp 0" and let it fight against a simple "jmp 0, 1" with "pmars -b -P -c 500 qscan.red jmp0.red". If your quickscanner works correctly it should win exactly twice the number of scanned locations. Another problem of this quickscanner is, that it is no longer that easy to assure, that all scanned positions are inside [200,7900], but for example with (qStep EQU 5400) and (qHop EQU 1300) that is the case. Puddleglum's quickscan looks at 27*2+1 locations. This might be a bit much. It scores as follows against Wilkies and WilFiz (the free scan is always used and scans are removed from the end, i.e. beginning with 77, 70, ...): scaned pos.| Wilkies -----------+------------------------------------------------------ 2*27+1 | 131.955839 (W 28.590352%, T 46.184784%, L 25.224864%) 2*26+1 | 132.661945 (W 28.678481%, T 46.626501%, L 24.695018%) 2*25+1 | 132.218092 (W 28.442935%, T 46.889288%, L 24.667778%) 2*24+1 | 131.983613 (W 28.305132%, T 47.068218%, L 24.626650%) 2*23+1 | 131.836730 (W 28.228219%, T 47.152075%, L 24.619707%) scaned pos.| WilFiz -----------+------------------------------------------------------ 2*27+1 | 113.860937 (W 25.200295%, T 38.260052%, L 36.539653%) 2*26+1 | 115.350062 (W 25.310858%, T 39.417489%, L 35.271653%) 2*25+1 | 116.271418 (W 25.300709%, T 40.369290%, L 34.330000%) 2*24+1 | 116.930522 (W 25.277208%, T 41.098898%, L 33.623894%) 2*23+1 | 117.677221 (W 25.262253%, T 41.890463%, L 32.847285%) 2*22+1 | 118.061787 (W 25.071572%, T 42.847071%, L 32.081357%) 2*21+1 | 118.561723 (W 25.011751%, T 43.526471%, L 31.461778%) 2*20+1 | 118.797804 (W 24.870743%, T 44.185575%, L 30.943682%) 2*19+1 | 118.991155 (W 24.692347%, T 44.914114%, L 30.393539%) 2*18+1 | 119.000235 (W 24.447186%, T 45.658676%, L 29.894138%) 2*17+1 | 118.976734 (W 24.239414%, T 46.258493%, L 29.502094%)The full quickscan has 1 jump to qSelect, 6 jumps to attack1 and 20 jumps (19 jumps + 1 fall-through) to attack2. When we use the bombing engine IV, it takes an average of 4.20 instructions before the first bomb is thrown. The original quickscan needs only an average of 3.20 instructions, because it doesn't need to prepare the bombing (label "adjust"). This is the (more or less ;-) original bombing engine: ... ;; decoder attack2 mul.b qTab, found attack1 mul.ab qTab, @ attack2 ;; choose between the two possible positions qSelect sne.i (start - 1), @ found ; use 1st position? add.ab # qHop, found ; no, use 2nd! ;; bombing engine V qTimes EQU 20 ; number of bombs to throw qStep2 EQU 4 ; distance between bombs qDist EQU (qTimes*qStep2 - 10) qLoop mov qBomb, @ found found mov qBomb, * qStep sub # qStep2, found djn qLoop, # qTimes jmp boot ; start paper qBomb dat.f { qDist, { 1 ...It scores as follows: scaned pos.| Wilkies -----------+------------------------------------------------------ 2*27+1 | 131.728304 (W 28.069585%, T 47.519549%, L 24.410866%) 2*26+1 | 131.540828 (W 27.952079%, T 47.684592%, L 24.363330%) 2*25+1 | 131.337863 (W 27.827629%, T 47.854976%, L 24.317395%) scaned pos.| WilFiz -----------+------------------------------------------------------ 2*27+1 | 112.777208 (W 24.472824%, T 39.358736%, L 36.168440%) 2*26+1 | 113.414413 (W 24.459471%, T 40.036000%, L 35.504529%) 2*25+1 | 114.162714 (W 24.455732%, T 40.795518%, L 34.748750%) 2*24+1 | 114.982588 (W 24.463210%, T 41.592958%, L 33.943832%) 2*23+1 | (to be calculated ...) 2*22+1 | (to be calculated ...) 2*21+1 | (to be calculated ...)At the point some of you may have noticed, that the q^2-scanner of Innocuous scores against WilFiz better than this q^3-scanner. The Mini-Q^3... ;; quickscanner start EQU boot ; first instruction of this warrior qStep EQU 5400 ; distance between two scans qHop EQU 1300 ; scan distance within a scan for 52 dat.f 0, 0 rof qGo seq found+1*qStep, found+1*qStep+qHop ; 1 jmp qSelect seq found+2*qStep, found+2*qStep+qHop ; C-1 jmp > attack1, { attack2 seq found+3*qStep, found+3*qStep+qHop ; C jmp > attack1 seq found+4*qStep, found+4*qStep+qHop ; C+1 jmp > attack1, } attack2 seq found+5*qStep, found+5*qStep+qHop ; B-1 jmp attack1, < qBomb seq found+6*qStep, found+6*qStep+qHop ; B jmp attack1 seq found+7*qStep, found+7*qStep+qHop ; B+1 jmp attack1, > qBomb seq found+9*qStep, found+9*qStep+qHop ; A-1 djn.b attack1, { attack1 seq found+10*qStep, found+10*qStep+qHop ; B jmp attack1, { attack1 seq found+12*qStep, found+12*qStep+qHop ; B*C-B jmp attack2, { attack2 seq found+15*qStep, found+15*qStep+qHop ; B*C-C jmp attack2, < qBomb seq found+21*qStep, found+21*qStep+qHop ; B*C+C jmp attack2, > qBomb seq found+24*qStep, found+24*qStep+qHop ; B*C+B jmp attack2, } attack2 seq found+27*qStep, found+27*qStep+qHop ; A*C-C djn.b attack2, { attack1 seq found+30*qStep, found+30*qStep+qHop ; A*C jmp attack2, { attack1 ;; free scan + boot paper, if found nothing sne found+18*qStep, found+18*qStep+qHop ; B*C jmz.f boot, found+18*qStep+qHop-10 ;; decoder attack2 mul.ab # 3, found ; C=3 attack1 mul.b qBomb, @ attack2 ;; choose between the two possible positions qSelect sne.i (start-1), @ found add.ab # qHop, found ;; bombing engine V qTimes EQU 20 ; number of bombs to throw qStep2 EQU 4 ; distance between bombs qDist EQU (qTimes*qStep2 - 10) qLoop mov qBomb, @ found found mov qBomb, * qStep sub # qStep2, found djn qLoop, # qTimes jmp boot, > 10 ; A=10 qBomb dat.f { qDist, { 6 ; B=6 ...YAP with the original MiniQ^3 (and original bombing engine) scores as follows: Wilkies: 129.334380 (W 26.811199%, T 48.900782%, L 24.288019%) WilFiz : 118.624749 (W 23.864462%, T 47.031364%, L 29.104175%) Yet Another Paper IIIWilkies: 130.187369 (W 27.325022%, T 48.212302%, L 24.462676%) WilFiz : 119.077682 (W 24.473358%, T 45.657608%, L 29.869034%)The only difference to the version in chapter 5 is, that this version uses three 1-cycle-attacks. This little change results in an improvement of about 0.077 points against Wilfiz. ;redcode-94nop ;name Yet Another Paper III ;author Jens Gutzeit ;strategy q^3 -> paper ;assert CORESIZE == 8000 ORG qGo pStep1 EQU 3913 pStep2 EQU 3035 boot spl 1 spl 1 silk1 spl @ silk1, < pStep1 mov.i } silk1, > silk1 mov.i { silk1, < silk2 silk2 djn.f @ silk2, < pStep2 ;; ;; quickscanner ;; start EQU boot ; first instruction of this warrior qStep EQU 5400 ; distance between two scans qHop EQU 1300 ; scan distance within a scan for 42 dat.f 0, 0 rof ;; decoding table dat.f 15, 10 ; A, D qTab dat.f 7, 4 ; B, E dat.f 13, 11 ; C, F qGo seq found+1*qStep, found+1*qStep+qHop ; 1 jmp qSelect, < found+1*qStep+qHop/2 seq found+3*qStep, found+3*qStep+qHop ; E-1 jmp > attack1, < qTab seq found+4*qStep, found+4*qStep+qHop ; E jmp > attack1, < found+4*qStep+qHop/2 seq found+5*qStep, found+5*qStep+qHop ; E+1 jmp > attack1, > qTab seq found+6*qStep, found+6*qStep+qHop ; B-1 jmp attack1, { qTab seq found+7*qStep, found+7*qStep+qHop ; B jmp attack1, < found+7*qStep+qHop/2 seq found+8*qStep, found+8*qStep+qHop ; B+1 jmp attack1, } qTab seq found+9*qStep, found+9*qStep+qHop ; D-1 djn.b > attack1, { attack2 seq found+10*qStep, found+10*qStep+qHop ; D jmp > attack1, { attack2 seq found+11*qStep, found+11*qStep+qHop ; F jmp > attack1, } attack2 seq found+13*qStep, found+13*qStep+qHop ; C jmp attack1, } attack1 seq found+14*qStep, found+14*qStep+qHop ; A-1 djn.a attack1, { attack1 seq found+15*qStep, found+15*qStep+qHop ; A jmp attack1, { attack1 seq found+18*qStep, found+18*qStep+qHop ; B*E+1-B-E djn.f attack2, qTab seq found+21*qStep, found+21*qStep+qHop ; B*E-B jmp attack2, < qTab seq found+24*qStep, found+24*qStep+qHop ; B*E-E jmp attack2, { qTab seq found+32*qStep, found+32*qStep+qHop ; B*E+E jmp attack2, } qTab ;; free scan + boot paper, if found nothing sne found+28*qStep, found+28*qStep+qHop ; B*E jmz boot, found+28*qStep+qHop-12 ;; decoder attack2 mul.b qTab, found attack1 mul.ab qTab, @ attack2 ;; choose between the two possible positions qSelect sne.i (start - 1), @ found ; use 1st position? add.ab # qHop, found ; no, use 2nd! ;; prepare bombing adjust add.ba found, found ;; bombing engine IV qTimes EQU 20 ; number of bombs to throw qStep2 EQU 4 ; distance between bombs throw mov.i qBomb, @ found mov.i qBomb, * found found mov.i -qStep2, @ qStep add.f qIncr, found djn.b throw, # 20 jmp boot, < 4000 ; start paper qBomb dat.f # 0, # qStep2 qIncr dat.f # -qStep2, # 2*qStep2 END |