From news-rocq.inria.fr!jussieu.fr!oleane!tank.news.pipex.net!pipex!usenet.eel.ufl.edu!brutus.bright.net!chi-news.cic.net!newsfeed.internetmci.com!in2.uu.net!news.new-york.net!news.stormking.com!ff95@dial.pipex.com Thu Dec 21 11:52:20 1995 Article: 3381 of rec.games.corewar Path: news-rocq.inria.fr!jussieu.fr!oleane!tank.news.pipex.net!pipex!usenet.eel.ufl.edu!brutus.bright.net!chi-news.cic.net!newsfeed.internetmci.com!in2.uu.net!news.new-york.net!news.stormking.com!ff95@dial.pipex.com From: Robert Macrae Newsgroups: rec.games.corewar Subject: One Fat Lady Date: 20 Dec 1995 17:59:04 -0500 Organization: Storm King Ind. Inc. Lines: 294 Sender: server@news.stormking.com Distribution: world Message-ID: Reply-To: ff95@dial.pipex.com NNTP-Posting-Host: valhalla.stormking.com Mime-Version: 1.0 Originator: corewar-l@stormking.com Round 9 was very hard work, partly to decide what was needed, but mainly to make all the parts work as intended. Below I've described the design process, which (I hope) will show why the code came out as it did. STRATEGY What '94 stalwarts do we lose when coding for the reduced instruction set? -- Silks (no >) -- Imp-gates (no < or >) -- The fastest scanner/bombers (no * for Tornado etc) In addition, a some classes are hampered: -- Small stones (no MOV or DJN.f) Everything else gains in relative strength. Imps are the likely big winners, but so do Quick-Scanners (still 2.0c) and Vamps. So we want a QS / Vamp / Imp combo :) This decision was the easy to make. What _was_ hard was to believe in the logic as Imp, Vamp and QS stubbornly refused to hurt (or even upset:) the simplest stone/imp combinations... IMPS Imps will be a real pain. We have to assume everyone will have one, so we must be capable of killing them to beat 0/0/100 scorelines. The defences are (1) catch them at launch (2) use ADD instructions as a kind of gate (3) build a gating pit. (1) Is handled by the QS, but won't work well against short launch codes. (2) I never really sorted out. I have a partial solution, which looks like step DAT +1396,-1396 fang JMP pit, 0 ... vamp MOV fang, @fang ADD step, fang JMP vamp This will damage an imp which hits it; when the imp over-writes step, I start biting randomly but as soon as it overwrites fang as well, I start bombing it! The code now looks like step MOV 0, 2731 ; For example -- any size works fang MOV 0, 2731 ... vamp MOV fang, @fang ADD step, fang JMP vamp and every time I execute a MOV and ADD I overwrite part of the imp with a MOV 0, 2731*N instruction where N=3D1,2,3... This usually seems to end up generating a MOV 0,1 imp just after the gate. I'm not sure how worthwhile this is (especially since I then proceed to bomb myself), but I hope that a ready-damaged imp might be obliging enough to die... (3) A pit-gate is perhaps the most hopeful line of attack. If we can capture enough enemy processes, they can implement a perfect gate, or a coreclear. I chose the latter, because I can keep my vamp smaller if it needn't do the clear. I'm not sure about this choice, but I was worried that my perpetual mod-4 biting would leave bombers' SPL 0 instructions in the gaps, so I gave up some likely imp kills to get extra dwarf kills. PROCESSES The 64 process limit offers a defence against stuns; split 64 times yourself! This suggests a vampire including a SPL, but I decided to slim the vamp and fatten the launch by splitting before launch. Not usually sensible -- you waste cycles JMPing multiple times -- but in this case I don't expect scanners and a QS shootout will already have been decided. Then we have to divide the processes between imp and vamp. Since the imp is essentially defensive, it needs just enough to survive, and all the rest should go to the vamp to maximise the bite-rate. Quick tests suggested that 6-process 3-point or 10-process 5-point imps were tough enough, and I decided on 5-point since I hoped most defenses would be tuned against 3 (after all mine is:) I haven't seen this form of launch before. Its far from optimised, but = I suspect it must have been used in some dwarf/imp combinations (Planar?)= . My version does not quite work smoothly; I execute MOV-ADD-JMP 18 times= , but then switch to ADD-JMP-MOV which misses one target. There _is_ a way to fix this with an extra process thrown in, but I couldn't code it in the time. It hurts to lose a few percent bombing efficiency, but I had far bigger problems ( like how to make the pit hit anything at all )-: VAMP/PIT With no SPL, a minimum vampire is 3 cells. Making the pit 3 active cells + JMP -3 means we can have a MOD-4 bombing pattern (larger pits get bombed too often anyway). So what to put in the pit code? We need a MOV and ADD for the coreclear; the remaining instruction is a SPL so that I slow any enemies with less than 64 processes. This configuration would work fine with lots of processes, but with 64 there is a major problem. If I bite something like my own vamp, I will suck in 3 "lumps" of 18 processes each; these will cycle messily around the pit and will occasionally perform 18 ADDs with _no_MOVs_ in between. This is bad news, as the coreclear will have gaps, so we have to make the pit as vulnerable as possible (SPL 2 rather than SPL -1 or SPL 0) so that it is likely to die if hit at anywhere. Otherwise, worst case, we kill our own imp, miss the pit and then flatten the vamp :-( I did toy with a MOV-ADD-MOV trap (no SPL), which works better in self-fi= ghts, but it is really too tuned to my own code. The stepsize is aimed to kill 3-point imps; with luck we will overwrite = the whole thing before is moves. I tried using an external step/pointer = arangement for the coreclear, but it didn't seem to help (perhaps because= it gave enemies more to bomb?). I'm sure there is more scope here... QS I use DAT bombs. This is not usually a good idea; you are better sucking processes into a pit, or stunning with SPLs. In this case, though, the coreclear is weak and I couldn't guarantee to pinch out the SPLs later. I tried several tricks -- bombing only locations I would later bite, (both SPL 0 and JMP 0 bombs), and using SPL -7 bombs -- but DAT beat them all in self-fights. Speeded up debugging, too :) In the absence of DJN, I loop until I reach the end of the enemy code. To avoid too short a run, I first check whether there is any enemy code 45 cells on, and if so I start up there. Finally, I try to get a bomb into the last 10 cells of the enemy (assuming he is 100 long) in case he has a (very slow) imp-launch there. If this sounds a rather forlorn hope (Michael:), spare a thought for the sheer pain that dozens of 10-0-90 scorelines had by this stage caused. Why look 45 cells on? Well you want to maximise the expected bombed length. I don't know the optimum distance, but I think its a bit less than 50, and 45=3D7x6+3 fits with my pre-bomb. Any offers? THE CODE And here it is. Not as aggressive as Paul Kline's warrior, and much more of an anti-imp specialist than Beppe's (which has an astounding 3rd place on the _unrestricted_ '88 hill). As far as I can see, none of the various anti-imp measures are very effective in their own right, but together they come good just often enough... ;redcode-94 ;name One Fat Lady ;author Robert Macrae ;strategy QS + 54 process Vamp + 10 process 5 pt Imp. ;assert CORESIZE =3D=3D 8192 ; Warrior based on half of the '88 instructions. It seems very ; hard to kill imps, so I expect a lot of draws. I'll need them... ; QS bombs with DATs because I can't guarantee that the trap will ; suicide. This will work best against other QSs ; Vampire is launched without a SPL, to make a smaller target. ; Imp is compact (Nimbus?) style. ; Pit is not likely to achieve much, but does occasionally manage ; a coreclear. ; ------------------------------------------------------------- ; QS based on my favourite "special tournament version of Sauron" core equ (look+102) look qscan for 6 cmp look+((qscan+2)*100)+3, look+4096+((qscan+2)*100)+3 mov #look+((qscan+2)*100)-point+3, @point rof cmp #0, point jmp found qscan for 7 cmp look+((qscan+10)*100)+3, look+4096+((qscan+10)*100)+3 mov #look+((qscan+10)*100)-point+3, @point rof cmp #0, point jmp found qscan for 8 cmp look+((qscan+18)*100)+3, look+4096+((qscan+18)*100)+3 mov #look+((qscan+18)*100)-point+3, @point rof cmp #0, point jmp found jmp boot ; Or move boot code here? spb DAT #0, #-7 found cmp core, @point add #4096, point add #4096, point ; point now points to hit mov spb, @point add #45, point cmp core, @point ; Scan at +45, and add #52, point ; Set to +45 add #-52, point ; or to -7 loop mov spb, @point ; 40% bomber, backwards through point mov spb, @0 ; his code add #-14, point cmp core, @point ; Loop over whole target jmp point add #98, point mov spb, @point ; and one for luck! ; --------------------------------------------------------------- STEP equ 1396 OFFS equ -100 FANGOFF equ -41 STEPOFF equ -42 boot spl bootimp boot1 mov vamp-boot1, OFFS boot2 mov vamp-boot1, OFFS boot3 mov vamp-boot1, OFFS mov fang, boot1+OFFS+FANGOFF mov step, boot1+OFFS+STEPOFF spl 1 mov -1, 0 mov -1, 0 mov -1, 0 ; Get 18 processes spl 1 spl j1 ; spread evenly around spl j3 ; the vamp j2 jmp @boot3 j3 jmp @boot1 j1 jmp @boot1 ; and jump to it. fang jmp pit-boot1-OFFS-FANGOFF, 0 vamp mov FANGOFF, @FANGOFF add vamp+STEPOFF, vamp+FANGOFF jmp vamp step dat #-STEP, #STEP pit SPL 2, boot1+OFFS+STEPOFF-5 MOV bomb, @pit ADD #-2731, pit JMP pit ; Overwritten. bomb DAT #0, #0 ; ------------------------------------------- ; Nimbus launch for 5 point, 10 process imp. Size is a ; better protection than speed here. Currently has tail ; on the end of my code; not elegant. imp MOV 0, 3277 ; 2731 or 3277 (3 or 5 point) bootimp SPL 1 ; 2 MOV -1, 0 ; 3 MOV -1, 0 ; 5 SPL 1 ; 10 SPL 2 JMP @0, imp ADD #3277, -1 Regards, Robert Macrae ff95@dial.pipex.com