There are two distinct prototypes for scanners. They are B-scanner and CMP-scanner. Their names were derived from their functions that do scanning. B-scanners detect their opponent by searching for any non-zero B-field in their code. CMP-scanners provide more rigid detection by comparing (CMP) for any non-identical instructions between two different locations. In the extent of their functional differences, both kinds of scanners avoid self-attack in interestingly different manner. (For further detail, see Comparison between B-scanners and CMP-scanners).
One of B-scanners' duties might be as follow:
; ... B-scan ; ... throw self-splitting instructions ; ... redo before finish ; ... core-clear
scan ADD #const, ptr JMZ scan, ptrDuring scanning phase, the scanner shouldn't be mistaken with any of its own codes. An easy way to do it is to add SLT after JMZ, e.g:
scan ADD #const, ptr JMZ scan, ptr SLT #num, ptr ; num is number of codes... ; ...in-between ptr and last line
MOV jmp_i, @ptr MOV spl_i, <ptrspl_i refers to SPL 0 and jmp_i refers to JMP -1.
JMN scan, scan
SPL 0, 0 MOV dat_i, <-1 JMP -1, 0
; name B-scanner 1 const EQU 3094 init EQU scan scan ADD #const, ptr ptr JMZ scan, ptr+init SLT #dat_i, ptr throw MOV jmp_i, @ptr MOV spl_i, <ptr ; pointer is decremented by 1 ADD #1, ptr ; needed to readjust the pointer redo JMN scan, scan spl_i SPL 0, 0 MOV dat_i, <-1 jmp_i JMP -1, 0 dat_i END scanHere is a much more elegant solution to B-scanner, blatantly taken from a successful classical B-scanner: B-scanner live in vain.
; name B-scanner 2 const EQU 2234 init EQU scan scan ADD #const, @2 JMZ scan, @ptr ; hit here throw MOV jmp_i, @ptr ptr MOV spl_i, <init+ptr redo JMN scan, scan spl_i SPL 0, 0 MOV dat_i, <-1 jmp_i JMP -1, 0 dat_i END scanThe SLT instruction has been dropped off but this program performs much better. Note that the warrior scans in modulo 2 or one for every two instructions. Also note that the warrior structure is aligned such as the B-scanner will scan zero B-field in its own code. This is how it avoids winding up its own code. There is but one instruction: the second one that will be read as non-zero when it reads its own code. This instruction is the indicator for this warrior to begin its core-clear.
CMP-scanners might as well fall into two smaller divisions. Their difference is in the way they handle two non-identical instructions. Their choices are based on their scanning gap. The CMP-scanner with large/medium scanning gap assumes the following: "if it is not the first instruction, then the second one is part of opponent's". It then takes the next step (detailed below) to accomplish its duty. The other CMP-scanner (small scanning gap) assumes that they have touched the intersection of the opponent's code. It then throws in self-splitting instructions at all locations between the two locations it is comparing.
Most CMP-scanners have the following components:
; ... CMP-scan ; ... handle everything to do upon two non-identical instructions. ; ... redo before finish ; ... core-clear
update ADD loc_mod, scan scan CMP loc, loc + gap avoid SLT #num, scan rescan JMP update, 0The first instruction updates both A-field and B-field of scanning location. The second instruction does the scanning. The third instruction provides a mechanism to prevent damaging its own codes. The last instruction loops back to label update in the case of identical instructions. Most scanners use the form DJN update, <b-attack as their looping instruction.
MOV #gap, cnt ; the constant gap is known MOV spl_i, <scan cnt DJN -1, #cnt ADD #gap, scan ; re-adjust the B-field scan ptr
MOV jmp_i, @scan ; on B-field MOV spl_i, <scan SUB #gap-1, scan ; now B-field scan has the same value... ; ... as A-field scan MOV jmp_i, @scan ; on A-field MOV spl_i, <scan ADD #gap+1, scan ;resume to B-field scan
MOV jmp_i, @scan MOV spl_i, <scan ADD loc_mod2, scan
The last method is intriguing to know. In normal scanning (instruction 1 - 4), both location pointers are updated as from E-F to C-D to A-B ... (below).
* * * * * * A B C D E FWhen it detects different instructions, e.g between E and F, it changes its scanning pointers as from E-F to D-E. The purpose is to provide way to access the A-Field.
JMN update, update
; name CMP-scanner (small) ; name CMP-scanner (large) gap EQU 12 gap EQU 49 const EQU -28 const EQU -98 init EQU update+const init EQU update+const2 const2 EQU -49 update ADD loc_mod, scan update ADD loc_mod, scan scan CMP init-gap, init scan CMP init-gap, init SLT #last-update, scan SLT #last-update, scan rescan DJN update, <6000 rescan DJN update, <6000 MOV spl_i, <scan MOV jmp_i, @scan cnt DJN -1, #cnt MOV spl_i, <scan MOV #gap, cnt ADD mod_2, scan ADD #gap, scan redo JMN scan, scan redo JMN update, update spl_i SPL 0 spl_i SPL 0 mod_2 MOV const2, <const2+1 loc_mod MOV const, <const jmp_i JMP -1 last END scan loc_mod DAT #const, #const END scan
(back to Trilogy)