{"id":26,"date":"2026-10-17T10:24:20","date_gmt":"2026-10-16T23:24:20","guid":{"rendered":"https:\/\/davidshoon.com\/?p=26"},"modified":"2026-10-17T10:24:20","modified_gmt":"2026-10-16T23:24:20","slug":"neuron-core-wars-code","status":"publish","type":"post","link":"https:\/\/davidshoon.com\/?p=26","title":{"rendered":"Neuron Core Wars code&#8230;"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">So you want to see some crazy shit&#8230;?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is a neuron-like corewars set of code I wrote back in 2006&#8230;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">From the readme.txt:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>This is a collection of \"neuron-like\" corewars code.\nWhilst the signals being passed (at least up to v4) are basically pre-programmed actions,\none could alter this and instead use the neurons to process some input,  \nlike a neural network.\n\n\nAlthough there is no real advantage in corewars to do so.\n\nPerhaps there is a better way to create \"artificial intelligence\" in corewars.\n\n--\n\nAnother way, is using an \"evolver\" (see simple-evolver) where it takes code from \na random location and tries to store and execute it. If it fails, the code is discarded.\n\n--\n\nAnother way, is the typical parasite method, which is by forking into random code. But\nthis can be easily defeated by the forkbomb.cw code. \n\n--\n\nThe only other way i can think of is, some piece of code like this, with lots of jumps...\n\naddr:\t\tdata 0\t\t# this gets randomised (within the boundaries of the code)\nr:\t\tdata 0\t\t# just a var\n\nline1: \t\tsome instruction here, e.g. move 0, &#91;r]\n\t\tsome instruction here to alter addr, e.g. add 1, addr\n\t\tjump &#91;addr]\n\nline2: \t\tsome instruction here\n\t\tsome instruction here to alter addr\n\t\tjump &#91;addr]\n\nline3: \t\tsome instruction here\n\t\t...\n\t\t...\n...\n\nand so on. \n\nIt then boils down to the \"altering addr\" method, which can be stored into a table or \nbased on \"learning\" or \"statistics\" -- thus improving its code over time, without\nactually changing anything (except the order it's run). \n\nE.g. you could use an sbox to hold all the addrs of code. Each \"jump instruction\"\njumps into a function which then permutates the sbox and returns a new addr accordingly.\n\nThe permutation function can then be optimised for a particular scenario.\n\nThis is similar to \"neuron\" with the signal handling\/actions. \n\n--\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s version 4 of the code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># NB: This is complete and working, but there is a race condition with \"sendsignal()\"\n# and \"clone()\" which can prevent signals being sent to newly moved neurons (moveneuron)\n# because sendsignal() may be polling on the old location and doesn't know that it has moved.\n# \n# The only way to fix this is to implement a communications protocol similar to\n# process_protect and process_module.\n#\n# But this code has already reached the limit of 200 instructions, so there is no way\n# to fix this problem.\n# \n# \n\ntitle \"AAA - Neuron v4\"\nauthor \"---------- DS -----------\"\n\nbootthreads: \tdata 1\t\t\t\t# initial case: minimum 1 more threads\n\t\t\t\t\t\t# after \"first neuron\" and its clone...\n\t\t\t\t\t\t# i.e. total = 3 threads\n\n\t\t\t\t\t\t# self-signal to create initial neuron\n\nboot:\t\tmove 2, signalstatus\n\t\tmove 1, signal\n\t\tadd 256, signal\n# \t\tmove &amp;bootstrap, jumpback\n \t\tmove &amp;bootstrap2, jumpback\n\t\tjump checksignal\n\n\n#bootstrap:\tmove 1, sendsignaldata\t\t\t# issue \"create neuron\" command to last neuron\n#\t\tadd 256, sendsignaldata\n#\t\tmove nextneuron, sendsignalneuron\t# &amp;neuronmarker can be used instead of nextneuron\n#\t\tmove &amp;bootstrap1, jumpback\t\t# in non-bootstrap \"first neuron\" type code.. i.e. with a poll loop\n#\t\tjump sendsignal\t\t\t\t# otherwise, in bootstrap code, you need to checksignal()\n\t\t\t\t\t\t\t# to get it to work. \n\t\t\t\t\t\t\t# Since we have a cloned neuron already, due to this bootstrap,\n\t\t\t\t\t\t\t# we just use it instead.\n\n#bootstrap1:\tloop bootthreads, bootstrap\n\nbootstrap2:\tmove 4, sendsignaldata\t\t\t# issue new command action, for all neurons\n\t\tadd 256, sendsignaldata\n\t\tadd 512, sendsignaldata\t\t\n\t\tmove nextneuron, sendsignalneuron\n\t\tmove &amp;bootstrap3, jumpback\n\t\tjump sendsignal\n\nbootstrap3:\tmove &amp;bootstrap5, jumpback\n\t\tjump delay\n\nbootstrap5:\tmove 2, sendsignaldata\t\t\t# move neurons\n\t\tadd 256, sendsignaldata\n\t\tadd 512, sendsignaldata\n\t\tmove nextneuron, sendsignalneuron\n\t\tmove &amp;bootstrap6, jumpback\t\t\n\t\tjump sendsignal\n\nbootstrap6: \tmove &amp;bootstrap2, jumpback\n\t\tjump delay\n\ndelay:\t\tmove 1000, i\ndelay2:\t\tloop i, delay2\n\t\tjump &#91;jumpback]\n\t\t\n# ----------- begin neuron here --------------------------------------\n\n\t# signals (sent as bit flags):\n\t#\n\t# (action signals) - you'd want one of these (you can combine these):\n\t# 0 = do nothing. \n\t# 1 = create more neurons\n\t#\n\t# (action signals with special conditions) - or these (don't combine these):\n\t# 2 = move this neuron into a new cell\n\t\t# since this moves the current neuron into a new place, you can't combine this.\n\t# 4 = move 0, &#91;random] (safe version, does not kill other neurons of same process) \n\t\t# aborts on receiving another signal\n\t# 8 = move 0, &#91;random] (unsafe version)\n\t\t# aborts on receiving another signal\n\t# 32 = convert into an imp\n\t\t# neuron transforms into an imp\n\t# 64 = terminates\n\t\t# neuron terminates\n\t#\n\t# (signal handling signals) - and you'd want one of these (at least one of these):\n\t# 128 = signal prev neuron with this same signal\n\t# 256 = signal next neuron with this same signal\n\t# 512 = do action (even if you're not the last neuron to get this signal)\n\t#\n\t# NB: When you combine the flags, they will be handled in numerical order. \n\t# Special conditions may prevent further flags from being \"actioned\".\n\t# Also, signal propagation occurs FIRST before actions, so you cannot\n\t# expect \"newly created\" neurons to receive a signal until the next signal is sent.\n\t# (e.g. This is the only way to prevent signal 1 creating an infinite number of\n\t# neurons. Similar problems occur with signal 2.)\n\n# ------------- global variables: the values will not be copied on clone()->linkneuron() -----------------------------------\n\nneuronmarker:\t\tdata 1337\n\n# --- public vars ---\n\nsignalstatus:\t\tdata 0\nsignal:\t\t\tdata 0\n\nnextneuron:\t\tdata 0\nprevneuron:\t\tdata 0\n\n# --- private vars ---\n\njumpback:\t\tdata 0\t\t\t# jumpback address for various code\njumpbackclone:\t\tdata 0\t\t\t# jumpback address for clone code (only)\nrecvsignal:\t\tdata 0\t\t\t# received signal's value\nsendsignaldata:\t\tdata 0\t\t\t# signal value to be sent\nsendsignalneuron:\tdata 0\t\t\t# target address of neuron for sendsignal\n\ns:\t\t\tdata 0\t\t\t# generic vars -- may be clobbered when entering a new function call.\nr:\t\t\tdata 0\ni:\t\t\tdata 0\n\n# --- constants ---\n\nsizeofvars:\t\tdata 12\t\t\t# size of all variables\nentrypointoffset:\tdata 15\t\t\t# entry point offset from &amp;neuronmarker\n\n# ------------ main polling loop --------------------------------\n# Clobbered: jumpback\n\nmain:\t\tjump main2\n#\t\tdata 0\t\t\t\t# if your entrypointoffset is incorrect, it will terminate\n#\t\tdata 0\t\t\t\t# as soon as it forks into the wrong offset. \n#\t\tdata 0\t\t\t\t# (this is only useful for debugging)\n#\t\tdata 0\t\t\t\t# but this exceeds the \"max limit\" of 200 instructions.\n#\t\tdata 0\t\t\t\t# Uncomment as many as you want.\n\nmain2: \t\tmove 0, signalstatus\t\t# clear signalstatus\n\npoll:\t\tmove &amp;poll, jumpback\npoll1:\t\tequal 2, signalstatus\t# poll signalstatus\n\t\tjump checksignal\n\t\tjump poll1\n\n# ------------- Function: checksignal() ---------------------------------\n# Clobbered but restored: jumpback\n# Clobbered: signalstatus\n\nchecksignalret:\tdata 0\t\t\t\t\t# caller's return address\n\nchecksignal:\tmove jumpback, checksignalret\t\t# save caller's return address\n\t\tmove signal, recvsignal\t\t\t# save it into recv signal, and reset signalstatus\n\nchecksignal0:\tequal 0, recvsignal\t\t\t# do nothing?\n\t\tjump checksignalend\n\n\t# similar to doaction()'s switch-case, but optimised for speed (not code size).\n\t# i.e. does not do multiple evaluations but requires more opcodes for control.\n\nchecksignal128:\tmove 128, i\t\t\t\t# check 'signal prev' flag\n\t\tand recvsignal, i\n\t\tequal 128, i\n\t\tjump sendsignal128\n\t\tjump checksignal256\t\t\t# ->--+\n\t\t\t\t\t\t\t#     |\n\t\t\t\t\t\t\t#     |\nsendsignal128: \tequal prevneuron, 0\t\t\t# &lt;= if we're the last neuron in this signal chain\n\t\tjump checksignaldo\t\t\t# &lt;= do the action.\n\t\tmove recvsignal, sendsignaldata\t\t#     |\n\t\tmove prevneuron, sendsignalneuron\t#     |\n\t\tmove &amp;checksignal256, jumpback\t\t# ->--|--+\n\t\tjump sendsignal\t\t\t\t#     |  |\n\t\t\t\t\t\t\t#     |  |\n\t\t\t\t\t\t\t#     |  |\nchecksignal256:\tmove 256, i\t\t\t\t# &lt;---+--+\n\t\tand recvsignal, i\n\t\tequal 256, i\n\t\tjump sendsignal256\n\t\tjump checksignal512\t\t\t# ->--+\n\t\t\t\t\t\t\t#     |\nsendsignal256: \tequal nextneuron, 0\t\t\t# &lt;= if we're the last neuron in this signal chain\n\t\tjump checksignaldo\t\t\t# &lt;= do the action.\n\t\tmove recvsignal, sendsignaldata\t\t#     |\n\t\tmove nextneuron, sendsignalneuron\t#     |\n\t\tmove &amp;checksignal512, jumpback\t\t# ->--|--+\n\t\tjump sendsignal\t\t\t\t#     |  |\n\t\t\t\t\t\t\t#     |  |\n\t\t\t\t\t\t\t#     |  |\nchecksignal512:\tmove 512, i\t\t\t\t# &lt;---+--+\n\t\tand recvsignal, i\n\t\tequal 512, i\n\t\tjump checksignaldo\t\t\t# 512 -- do the action anyway.\n\t\tjump checksignalend\n\nchecksignaldo:\tmove &amp;checksignalend2, jumpback\n\t\tjump doaction\t\t\t\t# on return, doaction is expected to clear (or set) signalstatus\n\nchecksignalend: move 0, signalstatus\t\t\t# reset signalstatus -- we only passed a signal\nchecksignalend2:\tmove checksignalret, jumpback\t\t# return to caller. \n\t\tjump &#91;jumpback]\n\n\n# ----------- Function: doaction() --------------------\n# Clobbered but restored: jumpback\n# Clobbered: recvsignal, signalstatus (by action 4 and 8)\n\ndoactionret:\tdata 0\t\t\t\t\t# caller's return address\n\n\t# think of the following code like a switch-case statement that operates on a bitflag\n\t# it is optimised for code size, not speed. (it saves 1 or 2 jump instructions on each case in the switch-case)\n\t# at the expense of re-evaluating the entire switch-case from the beginning.\n\ndoaction:\tmove jumpback, doactionret\n\t\tand 127, recvsignal\t\t\t# mask only the bits we want...\n\ndoactionstart:\tmove &amp;doactionstart, jumpback\t\t# set this as the jumpback value\n\t\t\t\t\t\t\t# because \"doaction\" will change \"recvsignal\"\n\t\t\t\t\t\t\t# by substracting from recvsignal the action being done.\n\t\t\t\t\t\t\t# (this saves some code -- but you cannot do this for \"signal handling actions\"\n\n\t\tequal 0, recvsignal\t\t\t# are we done yet?\n\t\tjump doactiondone\n\n\t\tmove 1, i\t\t\t\n\t\tand recvsignal, i\n\t\tequal 1, i\n\t\tjump doaction1\n\n\t\tmove 2, i\n\t\tand recvsignal, i\n\t\tequal 2, i\n\t\tjump doaction2\n\n\t\tmove 4, i\n\t\tand recvsignal, i\n\t\tequal 4, i\n\t\tjump doaction4\n\n\t\tmove 8, i\n\t\tand recvsignal, i\n\t\tequal 8, i\n\t\tjump doaction8\n\n\t\tmove 32, i\n\t\tand recvsignal, i\n\t\tequal 32, i\n\t\tjump doaction32\n\n\t\tmove 64, i\n\t\tand recvsignal, i\n\t\tequal 64, i\n\t\tjump doaction64\n\n\t\tdata 0\t\t\t\t\t# buggy code? undefined action signal\n\n\t# -- NB these subroutines of doaction() will return to doaction()'s switch-case statement \n\t# via \"jump &#91;jumpback]\" and not \"return to caller\" since that only occurs once (see above).\n\n# --- Action 1: Create more neurons\n\ndoaction1:\tadd -1, recvsignal\t\t\t# substract from recvsignal, so this action isn't repeated again.\n\t\tmove &amp;linkneurons, jumpbackclone\t# make clone() fork and link the neurons\n\t\tjump clone\t\t\t\t# jumpback is already set by doaction()\n\n# --- Action 2: Move neuron.\n\ndoaction2:\tadd -2, recvsignal\n\t\tmove &amp;moveneuron, jumpbackclone\t\t# no need to set jumpback\n\t\tjump clone\n\n# --- Action 4: move 0, &#91;random] (safe version)\n\ndoaction4:\tmove 0, signalstatus\t\t\t# reset signalstatus here.\ndoaction4p1: \tequal 2, signalstatus\t\t\t# check signalstatus -- if this changes, we stop action4\n\t\tjump stopaction4\ndoaction4p2:\tinfo 2, r\n\t\town &#91;r]\n\t\tjump doaction4p2\n\t\tmove 0, &#91;r]\n\t\tjump doaction4p1\nstopaction4:\tjump doactiondone2\t\t\t# return, but don't reset signalstatus\n\n# --- Action 8: move 0, &#91;random] (unsafe, faster)\n\ndoaction8:\tmove 0, signalstatus\t\t\t# reset signalstatus here.\ndoaction8p1: \tequal 2, signalstatus\t\t\t# check signalstatus -- if this changes, we stop action8\n\t\tjump stopaction8\n\t\tinfo 2, r\n\t\tmove 0, &#91;r]\n\t\tjump doaction8p1\nstopaction8:\tjump doactiondone2\t\t\t# return, but don't reset signalstatus\n\n# --- Action 32: Convert into an imp\n\ndoaction32:\tmove doaction32, imp\t\t\t# no need for jump &#91;jumpback]\nimp:\t\tdata 0\n\n# --- Action 64: Terminate neuron\n \ndoaction64:\tdata 0\t\t\t\t\t# no need for jump &#91;jumpback]\n\n# --- Done?\n\ndoactiondone:\tmove 0, signalstatus\t\t\t# reset signalstatus.\ndoactiondone2:\tmove doactionret, jumpback\n\t\tjump &#91;jumpback]\t\t\t\t# return to caller\n\n# ----------- Function: sendsignal() -------------------------------------------\n# Clobbered: None.\n\nsendsignal:\tequal 1337, &#91;sendsignalneuron]\t\t# check target is a valid neuron by testing beginmarker\n\t\tjump sendsignal2\n\n\t\tdata 0\t\t\t\t\t# buggy code? terminate\n\nsendsignal2:\tmove sendsignalneuron, r\n\t\tadd 1, r\t\t\t\t# set r to point to \"signalstatus\"\n\nsendsignal3:\tequal 0, &#91;r]\t\t\t\t# simplified version.\n\t\tjump sendsignal4\n\t\tjump sendsignal3\t\n\nsendsignal4:\tmove 1, &#91;r]\t\t\t\t# lock signalstatus\n\t\tmove r, i\n\t\tadd 1, i\t\t\t\t# set i to point to \"signal\"\n\t\tmove sendsignaldata, &#91;i]\t\t# send signal\n\t\tmove 2, &#91;r]\t\t\t\t# update signalstatus to completed\n\nsendsignalend:\tjump &#91;jumpback]\t\t\t\t# return to caller.\n\n# ----------- Function: clone() ------------------------------------------\n# Clobbered: None. (Also see polymorphic functions.)\n\n# NB: \"jumpbackclone\" is a polymorphic function descriptor (i.e. function pointer or subclass method)\n# which changes the behaviour of the clone code\n\nclone:\t\tinfo 2, r\n\t\town &#91;r]\t\t\t\t\t# check if 'r' overwrites into another neuron.\n\t\tjump clone\n\n\t\tmove &amp;neuronmarker, s\t\t\t# grab length of neuron (i could hardcode this, but i dont want to)\n\t\tneg s, i\n\t\tadd &amp;endvar, i\n\t\tadd 1, i\n\t\tmove r, endvar\t\t\t\t# save 'r'\n\n\t\tadd i, r\t\t\t\t# check if 'r + len' overwrites into another neuron.\n\t\town &#91;r]\n\t\tjump clone\n\n\t\tmove endvar, r\t\t\t\t# restore 'r'\n\ncopy:\t\tmovei s, r\n\t\tloop i, copy\n\n\t\tmove 1337, &#91;endvar]\t\t\t# set neuron marker\n\n\t\tjump &#91;jumpbackclone]\t\t\t# jump to the polymorphic function -- either moveneuron() or linkneurons()\n\n# --- Polymorphic jumpbackclone function: linkneurons() ---\n# Clobbered: nextneuron\n\nlinkneurons:\tequal 0, nextneuron\n\t\tjump linkneurons1\n\n\t\tdata 0\t\t\t\t\t# buggy code? terminate\n\nlinkneurons1:\tmove endvar, r\t\t\t\t# zero the bss\n\t\tadd 1, r\t\t\t\t# (1st var location)\n\t\tmove sizeofvars, i\t\t\t# (number of vars)\nzerobss:\tmove 0, &#91;r]\t\t\t\t\n\t\tadd 1, r\n\t\tloop i, zerobss\n\n\t\tmove endvar, nextneuron\t\t\t# set our \"nextneuron\" to point to the clone\n\n\t\tmove endvar, r\n\t\tadd 4, r\n\t\tmove &amp;neuronmarker, &#91;r]\t\t\t# set \"prevneuron\" in the cloned neuron to us.\n\n\t\tadd entrypointoffset, endvar\t\t# readjust endvar to entry point of cloned neuron\n\t\tfork &#91;endvar]\t\t\t\t# fork\n\n\t\tjump &#91;jumpback]\t\t\t\t# return to caller\n\n# --- Polymorphic jumpbackclone function: moveneuron() ---\n\nmoveneuron:\tmove prevneuron, r\n\t\tadd 3, r\n\t\tmove endvar, &#91;r]\t\t\t# set previous neuron's \"next neuron\" to new address\n\n\t\tmove nextneuron, r\n\t\tadd 4, r\n\t\tmove endvar, &#91;r]\t\t\t# set next neuron's \"prev neuron\" to new address\n\n\t\tadd entrypointoffset, endvar\t\t# this is just a clone_move() operation, so re-adjust entrypoint\n\t\tjump &#91;endvar]\t\t\t\t# and only jump (don't fork)\n\n# ------------------------------------------------------------------------------------\n\nendvar:\t\t\tdata 0\t\t\t# end variable -- used to mark end of neuron -- only to be used by clone().\n\n\t# data\/code below is NOT used -- just to look nice in the gui -- only first neuron has this.\n\nneuronendmarker:\tmove &amp;neuronendmarker, neuronendmarker1\t\t\nneuronendmarker1:\tdata 0\t\t\t\t\t\t\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>So you want to see some crazy shit&#8230;? This is a neuron-like corewars set of code I wrote back in 2006&#8230; From the readme.txt: Here&#8217;s version 4 of the code:<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-26","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/davidshoon.com\/index.php?rest_route=\/wp\/v2\/posts\/26","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/davidshoon.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/davidshoon.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/davidshoon.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/davidshoon.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=26"}],"version-history":[{"count":1,"href":"https:\/\/davidshoon.com\/index.php?rest_route=\/wp\/v2\/posts\/26\/revisions"}],"predecessor-version":[{"id":27,"href":"https:\/\/davidshoon.com\/index.php?rest_route=\/wp\/v2\/posts\/26\/revisions\/27"}],"wp:attachment":[{"href":"https:\/\/davidshoon.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=26"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/davidshoon.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=26"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/davidshoon.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=26"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}