Dacke
|
|
« Reply #20 on: November 27, 2009, 09:26:55 AM » |
|
Neat! Could you be bothered to explain the code in a bit more detail? I do understand how it works basically, but a small comment for each row would be a real treat On a different topic: Would it be hard to set up a TIGS-hill?
|
|
|
Logged
|
programming • free software animal liberation • veganism anarcho-communism • intersectionality • feminism
|
|
|
Poor Lazlo
Guest
|
|
« Reply #21 on: November 27, 2009, 11:22:58 AM » |
|
Neat! Could you be bothered to explain the code in a bit more detail? I do understand how it works basically, but a small comment for each row would be a real treat.
Absolutely! ;corewar-94 <-- Using the '94 standard, not the '88 ;name Toothy <-- name (obv)
launch MOV bait, @bait <-- Move the instruction "bait" to the location specified in its B-Field.(Indirect addressing with the @)
ADD.AB clear, launch <-- Add the A-Field of clear to the B-field of bait. This means the bait will be sent 10 addresses ahead of last time.
SUB clear, bait <-- subtract the same step from the bait, so bait is still pointing at the trap
JMP launch <-- Loop back to launch
bait JMP trap, 0 <-- The JMP instruction to be dropped across the core. The SUB instruction above keeps it pointing at the trap. Any process that comes upon the bait will therefore jump straight into the trap! The B-Field for JMPs are unused, so we can use it here to keep the address where each bomb should be dropped. 10 is added to this each time, so the JMPs are placed 10 spaces apart. Toothy is only 9 addresses long, so it never hits itself.
clear DAT #10, #0 <-- The bomb used for the core-clear below. I used it to keep the step size of the attack as well. I should have just used a constant really, and kept this a DAT #0, #0, because then any scanners falling upon this instruction would see empty core, and move on.
trap SPL 1, -60 <-- The trap! This SPL creates a new (enemy) process, which slows down the enemy as each process takes up one turn. A program with many processes becomes very slow. I also use the unused B-Field of the SPL to store the location for the core-clear to begin at. MOV clear, <-1 <-- This drops the DAT bomb "clear" at the location specified in "trap"'s B-field, decrementing it every time. This means the core-clear will put a dat in every address in the core, hopefully destroying everything that is not me. Eventually this will loop round and wipe itself, and the enemy processes trapped here will be killed.
JMP trap, <-11 <-- This makes the enemy processes jump back to the SPL command, keeping them alive, and the enemy sluggish. The B-Field also decrements the address 11 spaces before it. This is called an imp-gate, and helps to kill imps (MOV 0, 1).
END launch <-- This signifies to the MARS that the program should begin at "launch" (Somewhat unintuitive, but whatever).
I hope that helps. On a different topic: Would it be hard to set up a TIGS-hill?
I have absolutely no idea. I shall have a look.
|
|
|
Logged
|
|
|
|
lokijki
|
|
« Reply #22 on: November 27, 2009, 11:37:37 AM » |
|
This looks fun, I'm just having trouble grasping the concept. I was reading through that tutorial and the code didn't make sense because I just don't know what its trying to accomplish or how you actually "win"; its very abstract as the guide said. I'm gonna keep reading and go re-read things and hopefully it'll start to make more sense.
|
|
|
Logged
|
|
|
|
PGGB
|
|
« Reply #23 on: November 27, 2009, 11:42:16 AM » |
|
I feel like this article gives a good introduction to the concept. The programs do not manipulate vehicles in a physical system in an attempt to vanquish opposing vehicles, as with some other types of programming games. Instead, the programs try to directly destroy the opposing program by overwriting their code. A program thread dies only when it executes an illegal instruction or tries to divide by zero. A program wins when all opposing threads crash in this manner, and it loses if it, itself, is entirely crashed.
|
|
|
Logged
|
|
|
|
Poor Lazlo
Guest
|
|
« Reply #24 on: November 27, 2009, 12:42:06 PM » |
|
I feel like this article gives a good introduction to the concept. The programs do not manipulate vehicles in a physical system in an attempt to vanquish opposing vehicles, as with some other types of programming games. Instead, the programs try to directly destroy the opposing program by overwriting their code. A program thread dies only when it executes an illegal instruction or tries to divide by zero. A program wins when all opposing threads crash in this manner, and it loses if it, itself, is entirely crashed. That's a great explanation. I think I'll add a list of resources to the first post.
|
|
|
Logged
|
|
|
|
Brother Android
|
|
« Reply #25 on: November 27, 2009, 03:28:36 PM » |
|
This looks pretty awesome. I don't know if I can comprehend it, though... whatever you say, it looks difficult. How can the modulus be used as a weapon?
|
|
|
Logged
|
|
|
|
LemonScented
|
|
« Reply #26 on: November 27, 2009, 05:18:36 PM » |
|
I want to start playing this, I really do. Without wanting to blow my own trumpet, I have a hunch I'd be able to write some pretty evil beasties. I'm just worried that if i start, I'll wake up one day and realise I've lost a year of my life... I get sucked into stuff like this far too easily, and I've gots me a game to write.
|
|
|
Logged
|
|
|
|
Dacke
|
|
« Reply #27 on: November 27, 2009, 05:35:30 PM » |
|
Thank you for you explanation, Lazlo! This looks pretty awesome. I don't know if I can comprehend it, though... whatever you say, it looks difficult. How can the modulus be used as a weapon?
You don't use modulus as a weapon. You just need to use modulus to figure things out. For example the program "Dwarf" bombs every fourth row by overwriting it with "DAT 0, 0". ADD #4, 3 ;program start MOV 2, @2 JMP -2 DAT #0, #0 ;program end ... ... ... DAT #0, #0 ;first bomb
It starts by bombing four rows under itself, then eight rows, then twelve rows and so on. The bombings will eventually reach 8000 rows. But as the core wraps around after 8000 rows, 8000 == 0. So the Dwarf then bombs 0 rows under itself (it bombs it's own DAT-row). The process then starts over. The neat thing is that it just misses bombing itself. Understanding how this works and using modulus to make such timings (and other modulus stuff) is probably a key skill when creating a warrior. A detailed explanation of how the Dwarf works can be found in this guide: http://vyznev.net/corewar/guide.html
|
|
|
Logged
|
programming • free software animal liberation • veganism anarcho-communism • intersectionality • feminism
|
|
|
Core Xii
|
|
« Reply #28 on: November 28, 2009, 01:27:44 AM » |
|
launch MOV bait, @bait ADD.AB clear, launch SUB clear, bait JMP launch
That's a pretty inefficient loop, .25 light speed. You should make it .34c by combining the ADD and SUB into a single instruction. Remember, ADD. F adds both fields of the source into the destination. For starters, I need to choose a better step size than 10 (finding constants that are good is the most boring part of core war, in my opinion)
Here's the list of optimal step sizes: 1 3039 3359 2 3094 2234 4 3044 3364 5 2365 3315 8 2376 2936 10 2430 2930 I'm sure there are lots of ways to make it smaller and more efficient.
I combined the ADD and SUB into a single ADD, and changed SPL 1 into SPL #0. The immediate mode makes the SPL always split into $0, regardless of the value in the A-field - Freeing it up as an extra data storage you can use for something else. The smallest possible step size is 4 for it to not bomb itself (it'll hit the last JMP in the trap, but that shouldn't matter. If it does, increment to 5) and the above table thus indicates the optimal step size is either 3044 or 3364, I chose the latter for aesthetics. You might want to add a bootstrap with a quickscan (too advanced for me) and to decoy scanners. Since this warrior relies on a core size of 8000 and splitting processes, you should add the assert directive to make sure those settings apply. ;corewar-94 ;name Toothy ;edited by Core Xii ;assert CORESIZE == 8000 && MAXPROCESSES > 1
INTV equ 3364
ORG launch
launch MOV bait, @bait ADD.F clear, bait JMP launch
bait JMP -INTV+trap, INTV
clear DAT #-INTV, #INTV
trap SPL #0, <-60 MOV clear, <-1 JMP trap, <-11
END
|
|
|
Logged
|
|
|
|
Core Xii
|
|
« Reply #29 on: November 28, 2009, 03:52:07 AM » |
|
Here's my response to Toothy: Indie; Wins 47%, loses 7%, ties 46% (my edited version of Toothy ties considerably more at 61%) ;redcode-94 ;name Indie ;author Core Xii ;strategy redirect stun bomber + DJN-stream ;assert CORESIZE == 8000 && MAXPROCESSES > 1
INTV equ 2234
org Bomb
Bomb spl #2484, }0 Aim add.ab #INTV, Fire Fire mov Bomb, }INTV-INTV Strm djn.a Aim, }Bomb
end
|
|
|
Logged
|
|
|
|
Poor Lazlo
Guest
|
|
« Reply #30 on: November 28, 2009, 05:44:36 AM » |
|
launch MOV bait, @bait ADD.AB clear, launch SUB clear, bait JMP launch
That's a pretty inefficient loop, .25 light speed. Ouch! Very true. I think I'll change it to something like this: launch SPL #const, #-const loop MOV bait, @bait ADD.I launch, -1 JMP loop, <-50 END launch Similar to what you suggested, but the SPL 0 adds protection. I also used it to store the constant, so I don't have a coloured dat in the middle of my warrior (which will get picked up by scanners). It obviously doesn't guard against core-clears, but it's better than nothing. I changed SPL 1 into SPL #0. The immediate mode makes the SPL always split into $0, regardless of the value in the A-field - Freeing it up as an extra data storage you can use for something else.
Hmm. I'm not sure that's better. Surely a SPL 0 will make the enemy processes survive the core clear they are running? The intention for the SPL 1 was that when the coreclear hit the MOV command, the enemy processes would split onto a DAT, and die. Maybe I need to step through this. For now, though, I'll leave it in. Looking at this, it should work with a step size of 5, so I'll use a constant of 2365. All in all, the new Toothy looks like this: ;corewar-94 ;name Toothy 1.1 ;strategy Vamp ;author Daniel Rivas ;assert CORESIZE == 8000 && MAXPROCESSES > 1
const EQU 2365
launch SPL #const, #-const loop MOV bait, @bait ADD.I launch, -1 JMP loop, <-50
bait JMP trap, 0
clear DAT #0, #0
trap SPL 1, <-120 MOV clear, <-1 JMP trap, <-11
END launch Hmm. Out of 8000 rounds, Toothy and Indie seem to be pretty evenly matched: Tournament Results ================== Conditions ========== Melee with 2 warriors, 8000 rounds Score formula: (W*W-1)/S Core size Max processes Max cycles Max length Min distance --------- ------------- ---------- ---------- ------------ 8000 8000 80000 100 100 Summary ======= Warrior Author Length Score Given W% L% T% ------- ------ ------ ----- ----- ------ ------ ------ Toothy Daniel Rivas 0.87873 111.5 110.9 11.3 11.1 77.6 Indie Anonymous 0.87873 110.9 111.5 11.1 11.3 77.6
|
|
|
Logged
|
|
|
|
Core Xii
|
|
« Reply #31 on: November 28, 2009, 11:20:17 PM » |
|
Hmm. I'm not sure that's better. Surely a SPL 0 will make the enemy processes survive the core clear they are running? The intention for the SPL 1 was that when the coreclear hit the MOV command, the enemy processes would split onto a DAT, and die. Maybe I need to step through this. For now, though, I'll leave it in.
Ah, I didn't realize that was your intention. It's just that SPL 0 is more effective at stunning. Very good. Here's my new response, something quite different: Upstream. It's basically a single-instruction warrior. Introducing bootstrapping, binary launch and the for-macro. ;redcode-94 ;name Upstream ;author Core Xii ;strategy interlaced DJN-stream ;assert CORESIZE == 8000 && MAXPROCESSES > 1
CORE equ (CORESIZE-(MINDISTANCE*2)) NUM equ 91
org Boot
Boot for NUM mov Strm, (Boot+MAXLENGTH)+((CORE/(NUM+1))*(1-Boot)) rof
spl 1, 0 ;1 mov -1, 0 ;0 spl 1, 0 ;1 spl 1, 0 ;1 mov -1, 0 ;0 spl 1, 0 ;1 mov -1, 0 ;0
jmp @Boot, }0
Strm djn.f #1, }0
end
Tournament Results ==================
Conditions ========== Melee with 3 warriors, 800 rounds Score formula: (W*W-1)/S Core size Max processes Max cycles Max length Min distance --------- ------------- ---------- ---------- ------------ 8000 8000 80000 100 100
Summary ======= Warrior Author Length Score Given W% L% T% ------- ------ ------ ----- ----- ------ ------ ------ Upstream Core Xii 0,92729 329,0 265,0 12,6 4,6 31,3 Toothy 1.1 Daniel Rivas 0,92729 207,0 387,0 0,4 22,9 25,3 Indie Core Xii 0,92729 161,0 433,0 0,6 34,6 13,3
|
|
« Last Edit: November 28, 2009, 11:24:03 PM by Core Xii »
|
Logged
|
|
|
|
Dacke
|
|
« Reply #32 on: November 29, 2009, 03:20:22 PM » |
|
Nice stuff! I'll try to put something together soon (even if I'll end up at the bottom of your list)
|
|
|
Logged
|
programming • free software animal liberation • veganism anarcho-communism • intersectionality • feminism
|
|
|
Poor Lazlo
Guest
|
|
« Reply #33 on: November 30, 2009, 07:33:02 AM » |
|
Very good. Here's my new response, something quite different: Upstream. It's basically a single-instruction warrior. Introducing bootstrapping, binary launch and the for-macro. Toothy is back again! I'm pretty unhappy with it, to be honest, but whatever. ;corewar-94 ;name Toothy 1.5 ;strategy Vamp ;author Daniel Rivas
const EQU 2430
start SPL copy, 0 launch SPL #const, #-const loop MOV bait, @bait ADD.I launch, -1 JMP loop, <-50
bait JMP trap, 0
trap SPL 2, <-120 MOV clear, <-1 last JMP trap, <-11 copy JMZ.F 0, -300 MOV last, -350 SUB.F #1, -1 SUB.A #1, count JMZ.A -353, count JMP -4
DAT #0, #0 count DAT #9, #0 clear DAT #0, #0
END start Changing the SPL 1 in the trap to SPL 2 helps to make sure the enemy processes still die. The big change, though, is the copy code. This basically scans an area 300 addresses above toothy, and copies toothy there 50 if it detects a change. This hopefully moves toothy out of danger... Anyway, it's a pretty crap implementation. Oh well. I think that really just going for a straight replicator would be a better way to go. Possibly I should just sit down and make this thing better. Anyways, Upstream and Toothy now tie against each other almost every time: Results ================== Conditions ========== Melee with 2 warriors, 8000 rounds Score formula: (W*W-1)/S Core size Max processes Max cycles Max length Min distance --------- ------------- ---------- ---------- ------------ 8000 8000 80000 100 100 Summary ======= Warrior Author Length Score Given W% L% T% ------- ------ ------ ----- ----- ------ ------ ------ Toothy 1.5 Daniel Rivas 0.96754 104.9 98.7 2.8 0.8 96.4 Upstream Core Xii 0.96754 98.7 104.9 0.8 2.8 96.4
|
|
|
Logged
|
|
|
|
Core Xii
|
|
« Reply #34 on: November 30, 2009, 09:44:25 AM » |
|
Oops, I've been running the tournaments in Melee rather than Round Robin. Explains the discrepancy between our numbers. A scanner enters the hill: Twoosh. Inspired by yours, this warrior has two parallel loops, one that adds numbers and another that clears the core. Both loops' jump instructions work together as the scanner. ;redcode-94 ;name Twoosh ;author Core Xii ;strategy .5c stun scanner + .25c core-clear ;assert CORESIZE == 8000 && MAXPROCESSES > 1
INTV equ 2430 DIST equ 5
org Boot
Boot spl Fire, Data+MINDISTANCE
Aim add.f Data, Ptr jmz.a Aim, @Ptr mov Ptr, @Ptr Hit djn.f Aim, >Boot
Fire mov Data, >Boot jmz.a Fire, *Ptr mov Ptr, *Ptr djn.f Fire, >Boot Ptr spl #Hit, }Hit+DIST Data dat {INTV, <INTV
end
Hint, use the tag to make your tournament table monospace. Tournament Results ==================
Conditions ========== Round robin with 4 warriors, 200 rounds per matchup Score formula: (W*W-1)/S Core size Max processes Max cycles Max length Min distance --------- ------------- ---------- ---------- ------------ 8000 8000 80000 100 100
Summary ======= Warrior Author Length Score Given W% L% T% ------- ------ ------ ----- ----- ------ ------ ------ Upstream Core Xii 0,84322 144,0 80,0 22,7 1,3 76,0 Twoosh Core Xii 0,68676 142,3 100,8 28,5 14,7 56,8 Toothy 1.5 Daniel Rivas 0,79269 88,2 139,2 5,2 22,2 72,7 Indie Core Xii 0,82416 85,2 139,7 3,3 21,5 75,2
I'd say we should roll with a hill format where all the existing warriors are fought also, for increased challenge. Upstream is still king of the hill. Do you think I should run more than 200 rounds per matchup? Would 800 suffice? I wouldn't care waiting for 8000.
|
|
|
Logged
|
|
|
|
Dacke
|
|
« Reply #35 on: November 30, 2009, 10:06:00 AM » |
|
I call for science! How big is the difference between 200 and 800 rounds, is the difference relevant?
|
|
|
Logged
|
programming • free software animal liberation • veganism anarcho-communism • intersectionality • feminism
|
|
|
Poor Lazlo
Guest
|
|
« Reply #36 on: November 30, 2009, 11:37:50 AM » |
|
I call for science! How big is the difference between 200 and 800 rounds, is the difference relevant?
Hmm. Well, after some experimentation, it seems like the results stop changing much after about 800 rounds, so is that okay?
|
|
|
Logged
|
|
|
|
Dacke
|
|
« Reply #37 on: November 30, 2009, 01:06:06 PM » |
|
Sounds good to me, I used 800 for the tournament below So, here is my first attempt ever at this. I give you The 7-10 Split. It's written from scratch and ignores most conventions. Against bench-mark tests, it gets the lowest score together with Toothy. But it stands as the proud champion of the TIGShill ;redcode-94 ;name The 7-10 Split ;author Dacke ;strategy Quick bombing run, followed by dual DJN streams ;assert CORESIZE == 8000 && MAXPROCESSES > 1 ;assert MAXLENGTH == 100 && MINDISTANCE == 100 space EQU 75 ORG Bombrun
Upstream DJN #-100, {0 Bombrun FOR 97 mov {(100+space/2+space*(-1*Bombrun)), {(100+space+space*(-1*Bombrun)) ROF SPL Upstream, <4000 DJN #102, }0 END
Conditions ========== Round robin with 4 warriors, 800 rounds per matchup Score formula: (W*W-1)/S Core size Max processes Max cycles Max length Min distance --------- ------------- ---------- ---------- ------------ 8000 8000 80000 100 100
Summary ======= Warrior Author Length Score Given W% L% T% ------- ------ ------ ----- ----- ------ ------ ------ The 7-10 Split Dacke 0,76662 130,0 99,2 19,7 9,5 70,8 Toothy 1.5 Daniel Rivas 0,92339 117,7 94,5 10,0 2,3 87,8 Upstream Core Xii 0,79560 112,5 111,7 12,3 12,0 75,8 Indie Core Xii 0,80474 86,5 141,2 4,7 23,0 72,3
|
|
|
Logged
|
programming • free software animal liberation • veganism anarcho-communism • intersectionality • feminism
|
|
|
Dacke
|
|
« Reply #38 on: November 30, 2009, 01:22:03 PM » |
|
Whoops, I missed Twoosh! Twoosh is the new champion of the hill Tournament Results ==================
Warrior Author Length Score Given W% L% T% ------- ------ ------ ----- ----- ------ ------ ------ Twoosh Core Xii 0,68493 135,2 109,4 26,6 18,0 55,5 The 7-10 Split Dacke 0,73739 129,0 105,3 21,1 13,2 65,7 Upstream Core Xii 0,77945 124,8 103,8 17,8 10,8 71,4 Toothy 1.5 Daniel Rivas 0,81001 100,9 126,0 9,3 17,7 73,1 Indie Core Xii 0,80113 91,2 136,7 6,3 21,5 72,2
|
|
|
Logged
|
programming • free software animal liberation • veganism anarcho-communism • intersectionality • feminism
|
|
|
Core Xii
|
|
« Reply #39 on: November 30, 2009, 01:53:44 PM » |
|
Huh.
Warrior Author Length Score Given W% L% T% ------- ------ ------ ----- ----- ------ ------ ------ The 7-10 Split Dacke 0,74133 133,3 100,2 22,3 11,2 66,5 Twoosh Core Xii 0,69324 131,7 111,6 25,0 18,3 56,7 Upstream Core Xii 0,77629 125,5 103,4 18,1 10,8 71,1 Toothy 1.5 Daniel Rivas 0,81477 97,7 128,4 7,9 18,2 73,9 Indie Core Xii 0,81561 91,2 135,7 6,0 20,8 73,1
So apparently 800 rounds isn't enough after all. It takes forever to run 8000 rounds. Oh well.
Edit: I'll try 3200.
|
|
« Last Edit: November 30, 2009, 02:11:27 PM by Core Xii »
|
Logged
|
|
|
|
|