From news-rocq!jussieu.fr!oleane!newsfeed.berkeley.edu!logbridge.uoregon.edu!msunews!not-for-mail Mon Sep 6 18:01:33 1999 Article: 10618 of rec.games.corewar Path: news-rocq!jussieu.fr!oleane!newsfeed.berkeley.edu!logbridge.uoregon.edu!msunews!not-for-mail From: David Matthew Moore Newsgroups: rec.games.corewar Subject: Starving Hacker Date: 5 Sep 1999 08:25:00 GMT Organization: Michigan State University Lines: 221 Message-ID: <7qt9cs$4d1$1@msunews.cl.msu.edu> NNTP-Posting-Host: arctic.cse.msu.edu User-Agent: tin/pre-1.4-980618 (UNIX) (SunOS/5.6 (sun4u)) Xref: news-rocq rec.games.corewar:10618 jklewis wrote: : : Macrae and Moore both entered "dumber" programs that cleared core : with sequential clears, hoping to trade score for speed that might help : in the Knock Out portion of the tourney. Let me elaborate on the strategy a bit. Suppose that your PLAYER number is 1. To maximize your score, fill the registers like this: dat 7999, 0 ; register for player 1 dat 0, 0 ; register for player 2 So your score becomes 7999 - 0 = 7999. The trick is to find the exact location of the registers, so that you avoid ghastly errors like writing 7999 to your opponent's register. For example, an evil warrior could quickly scan for the oversized OS, then shift the signature instructions by one, then wait for the unsuspecting victim to finish the job. "Starving Hacker" avoids the problem of register location. Its core-clear creates a long SPL carpet like this: spl #7999, 12 spl #7998, 12 spl #7997, 12 ... spl #2, 12 spl #1, 12 spl #0, 12 The result is 1 point if the registers appear anywhere within the carpet, which is satisfactory for single-elimination play. Just be sure that the carpet's "seam" (the transition from 0 to 7999) occurs within your original MAXLENGTH lines of code. In the case of PLAYER 1, the Hacker's core-clear looks like this: clear mov bomb, >pointer ; move bomb to next location jmp clear, {bomb ; alter data value of bomb by 1 bomb spl #0, 12 If PLAYER==2, then some optimization is possible, since the data value of the bomb can be the same as its pointer: mov bomb, }bomb ; move bomb and alter data value For example, it's much easier to put the PLAYER==2 code inside of a blur-style scannner. This gives some advantages to the player with the lower seed. jklewis continues: : : Unfortunately for Ben, Moore's attack was too fast and he fell. Having : easily dominated the round robin, "Quick Thinking" was ironically beaten : by a quicker program. My program is a mirage-style scanner (33%c scan) which probably scans slower than Ben's HSA variant. It was a blatant copy of Fire and Ice, but the d-clear was replaced by the special clear mentioned above. Despite the strategy-line comments, it was not very "optimized" at all; I just wrote that to make it sound "intelligent" :-) However, I was certain that a scanner would be the most competitive entry, since it was the best strategy to take advantage of large code. jklewis continues: : : I'm glad that this competitions winner was a program of some size and : that it needed a bit of intelligence to win. And a bit of luck :-) Curiously, the two dumb programs (mine and Macrae's) were undefeated in round-robin play (except that I lost to Macrae); however, both were eliminated in the single-elimination rounds (losing 2 out of 3 matchups). Anyway, I was just happy to see that not everyone picked the same strategy! David. ;redcode-94 ;name Starving Hacker ;author David Moore ;strategy Score 1 point :-) Optimized for single-elimination combat. ;assert 1 PLAYER EQU 0 dest equ 2670 ;---------------------------------- ; bootstrap ;---------------------------------- boot mov scan1+0, >away mov scan2+0, >away mov scan2+1, >away mov scan3+0, >away mov scan3+1, >away mov scan3+2, >away mov scan4+0, >away mov scan4+1, >away mov scan4+2, >away away jmp boot+dest+3, boot+dest ;---------------------------------- ; scanner adapted from Fire and Ice ;---------------------------------- ; pre-bootstrap version scan1 MOV.B $ 2, # 2667 jmp #0, @0 ; scanned scan2 MOV.I $ 4, > -1 ADD.AB # -723, # -2170 jmp #0, 0 ; scanned scan3 JMZ.F $ -2, @ -1 JMN.B $ -4, * -4 SPL.B # 0, { 0 jmp #0, #0 ; scanned scan4 MOV.I $ 2, > -6 for PLAYER!=1 JMP.B $ -1, } 1 rof for PLAYER==1 JMP.B $ -1, { 1 rof SPL.B # 0, $ 12 ;---------------------------------- ; decoy ;---------------------------------- spl #0, #0 ; scanned spl #1, {1 spl #1, @1 spl #0, *0 ; scanned spl 1, *1 spl 1, {1 spl #1, 1 spl #0, @0 ; scanned spl #1, #1 spl #1, {1 spl #1, @1 spl #0, *0 ; scanned spl 1, *1 spl 1, {1 spl #0, 0 ; scanned spl #0, @0 spl #1, #1 spl #1, {1 spl #0, @0 ; scanned spl #0, *0 spl 1, *1 spl #0, 0 ; scanned spl #1, #1 spl #1, {1 spl #1, @1 spl #0, *0 ; scanned spl 1, *1 spl 1, {1 spl #1, 1 spl #0, @0 ; scanned spl #1, #1 spl #1, 1 spl #0, @0 ; scanned spl #1, *1 spl 1, *1 spl #1, *1 spl #0, *0 ; scanned spl 1, {1 spl #1, 1 spl #0, @0 ; scanned spl #1, #1 spl #1, {1 spl #1, @1 spl #0, *0 ; scanned spl 1, *1 spl #1, *1 spl #1, #1 spl #0, {0 ; scanned spl #1, @1 spl #1, *1 spl 0, *0 ; scanned spl 1, {1 spl #1, 1 spl #1, @1 spl #0, #0 ; scanned spl #1, {1 spl #1, @1 spl #1, *1 spl #0, #0 ; scanned spl #1, {1 spl #1, @1 spl #0, *0 ; scanned spl 1, *1 spl 1, {1 spl #1, 1 spl #0, @0 ; scanned spl #1, #1 spl #1, #1 spl #0, {0 ; scanned spl #1, @1 spl #1, *1 spl 1, *1 spl #0, {0 ; scanned spl #1, 1 spl #1, @1 spl #1, 1 spl #0, @0 ; scanned spl #1, #1 end boot