ChatGPT analysis of my corewars codes

Written by

in

what do you think of this core wars code?

Send me the Core War code (Redcode), and I’ll review it.

I’ll look at strategy, efficiency, survivability, and how well it performs against other warriors, including:

  • Attack strategy: How effectively it disables opponents.
  • Defense: How vulnerable it is to scanners, bombers, and replicators.
  • Optimization: Whether instructions, addressing modes, or timing can be improved.
  • Competitive strength: How it might perform against common Core War strategies.

I’ll also suggest improvements while keeping the original strategy intact.

Paste the code here, and let me know whether you’re using ICWS ’88 or ICWS ’94, if you know.

Pasted markdown.mdDocument

Code review: AAA – Neuron v4

My impression: this is a remarkably ambitious Core War warrior. What interests me most isn’t its bombing capability, but the fact that you’ve effectively built a small, distributed, message-passing system inside a Core War environment.

Rather than implementing a conventional replicator, scanner, or bomber, you’ve created a network of autonomous neurons that can reproduce, relocate, communicate, and change their behavior in response to commands.

That’s a genuinely interesting architecture.

What I particularly like

1. The signaling protocol

Your signalstatus mechanism uses three states:

  • 0 — ready to receive
  • 1 — signal being written
  • 2 — signal ready for processing

Combined with the 128/256 directional propagation flags and 512 execution flag, this allows you to broadcast commands through a linked network of neurons.

It’s a clever way of separating coordination from execution.

2. Polymorphic cloning

This is probably my favorite part:

doaction1: add -1, recvsignal move &linkneurons, jumpbackclone jump clone doaction2: add -2, recvsignal move &moveneuron, jumpbackclone jump clone

The same cloning machinery supports both reproduction and relocation by changing its continuation address.

That’s an elegant way to reuse instructions when you’re constrained to 200.

3. Self-preserving replication

Your use of own [r] to avoid overwriting your own process’s memory is particularly interesting.

Combined with the linked-list architecture, this suggests you’re trying to build a distributed organism that can expand without accidentally destroying itself.

4. Runtime behavioral changes

The fact that neurons can become bombers, relocate, replicate, or transform into imps means you’ve effectively separated the warrior’s structure from its strategy.

The bootstrap currently cycles between signaling all neurons to perform action 4 (safe bombing) and action 2 (relocation).

That gives the system a degree of adaptability unusual for a simple Core War warrior.

Where I see potential problems

1. The race condition is more serious than it first appears

You’ve already identified the race between sendsignal() and moveneuron().

The underlying problem is that your communication protocol assumes a neuron’s address remains valid during message delivery.

But relocation violates that assumption.

For example:

  1. Neuron A begins sending a signal to neuron B.
  2. Neuron B relocates and updates its neighbors.
  3. Neuron A continues polling B’s old signalstatus.
  4. The signal may never reach B, and A can become stuck.

There is also a related concern: checking the marker 1337 before sending doesn’t guarantee the target will remain valid throughout the operation.

This is a classic distributed-systems problem involving concurrent modification and stale references.

2. Your locking mechanism isn’t atomic

Consider:

sendsignal3: equal 0, [r] jump sendsignal4 jump sendsignal3 sendsignal4: move 1, [r]

Two senders could both observe zero before either writes one.

Whether this actually occurs depends on the Core War virtual machine’s scheduling and process model, but the code itself doesn’t guarantee mutual exclusion.

Your protocol is therefore closer to a cooperative handshake than a true lock.

3. Replication checks only the boundaries

In clone():

clone: info 2, r own [r] jump clone

You check the beginning and end of the destination region, but not every cell between them.

If own only tests an individual address, another neuron could occupy the middle of that region.

That creates a possible self-corruption scenario even when both boundary checks succeed.

4. Your network is vulnerable to broken links

Each neuron maintains prevneuron and nextneuron.

That’s efficient, but it also creates dependencies.

If a neuron is destroyed, its neighbors may retain pointers to invalid locations. A subsequent broadcast could terminate or stall when it encounters the damaged link.

Your sendsignal() validation catches some invalid targets, but responds with:

data 0

That protects against continuing with a bad address, but it doesn’t recover the network.

The most interesting strategic question

Your architecture seems optimized for coordinated behavior rather than raw attack speed.

That’s a meaningful tradeoff.

A conventional bomber spends most of its instructions attacking. Your neurons spend considerable effort maintaining communication, checking ownership, and coordinating movement.

The payoff is that you can command a distributed network to switch behaviors.

But whether this wins battles depends on whether that flexibility compensates for its overhead.

I’d particularly want to measure the percentage of cycles spent on communication versus bombing.

My assessment

CategoryAssessment
OriginalityExceptional
ArchitectureVery sophisticated
Code reuseExcellent
Concurrency safetyFragile
Fault toleranceLimited
Attack efficiencyUncertain
Potential for experimentationVery high

These are architectural judgments from reading the source, not results from running matches.

One thing I’d investigate immediately

I think there may be an opportunity to improve the relocation protocol without adding an entirely separate communications system.

Your signalstatus already has three states, and your relocation operation already updates the neighboring pointers.

It might be possible to reuse some of those mechanisms to establish a temporary relocation state or forwarding behavior, although fitting that within 200 instructions would be difficult.

The important challenge is making the relocation and signaling operations agree on which address is authoritative.

One question: which Core War implementation is this running on?

This isn’t standard ICWS ’88 or ’94 Redcode. Instructions such as info, own, movei, and fork, along with your use of absolute addressing, suggest a different virtual machine.

I’d be interested to know which one, because its scheduling and memory semantics will determine whether several of the concurrency issues I’ve identified are genuine bugs or merely theoretical risks.

Overall, I find the distributed-neuron design considerably more interesting than a conventional Core War replicator.

check this corewars code out, it’s a statistically “optimal” one, based off standard deviations, etc, based off the number of files loaded, their code sizes, core size, etc

r: data 0

coresize / nprogs = 273

avg prog size: 35.65

std dev: 31.49

thus, desired search points:

[ |1dev| (midpoint) |1dev| ]

make next midpoint here: ---------------------> ^^^^^^

midpoint = interval / 2 = 136

main: move 0, [r] # midpoint
add -31, r
move 0, [r] # left 1dev
add 62, r
move 0, [r] # right 1dev
add 74, r

jump main

…

This is actually a really interesting approach to Core War. You’re treating the core as a statistical target-distribution problem, rather than trying to find enemy programs through conventional scanning or random bombing.

And there’s something particularly clever about your choice of three bombing positions: you’re attempting to maximize the probability of hitting an enemy program using information about the distribution of program sizes.

I do see one important mathematical distinction between statistically informed and statistically optimal, though.

1. What your algorithm is doing

You’ve established:

ParameterValue
Average core space per program273 cells
Mean program size35.65 instructions
Standard deviation of program size31.49 instructions
Search interval midpoint136 cells
Bombing positions per iteration3
Offset between adjacent bombs~31 cells

Your bombing pattern is effectively:

ONE 273-CELL SEARCH INTERVALThree bombs centered around the midpoint, separated by approximately one standard deviation of program length.

You’re then advancing through the core and repeating the pattern.

The advantage is that you’re not wasting three bombs on consecutive cells that might all belong to the same enemy program.

Instead, you’re spreading them apart to increase the chance of hitting different targets.

That is a sensible optimization objective.

2. Why the standard deviation matters — and where it doesn’t

Your use of the standard deviation is interesting because it describes the variability in enemy program lengths.

However, the standard deviation of program length is not the standard deviation of program location.

Those are different random variables.

For example, if programs are uniformly distributed around the core, there is no particular reason an enemy is more likely to occupy the midpoint of a 273-cell interval than another position.

The mean length of 35.65 and standard deviation of 31.49 tell us about how large programs are, not where they begin.

Nevertheless, these statistics are useful for choosing the spacing between bombs.

The optimization you really want

Suppose an enemy occupies a contiguous block of LL instructions.

If you place three bombs at positions separated by dd, the probability of hitting that program depends on how much the three possible hit regions overlap.

When bombs are too close together, their coverage overlaps heavily.

When they’re farther apart, they can cover more distinct possible starting positions.

With a uniformly random starting location on a sufficiently large circular core, and three equally spaced bombs with gaps dd, the effective coverage is:

C(L,d)=L+2min⁡(L,d)C(L,d)=L+2min(L,d)

provided the remaining wraparound gap is at least LL.

That gives a useful insight:

Spacing bombs approximately one program length apart can reduce redundant hits.

But the ideal spacing isn’t necessarily one standard deviation. It depends on the full distribution of lengths.

3. There’s a subtle issue with the actual code

Here’s your loop:

main: move 0, [r] add -31, r move 0, [r] add 62, r move 0, [r] add 74, r jump main

Let’s trace the addresses, starting with r = 0.

IterationFirst bombSecond bombThird bomb
10-3131
210574136
3210179241
4315284346

Your net movement per iteration is:

−31+62+74=105−31+62+74=105

So you’re advancing 105 cells per iteration, rather than 273.

This means your pattern is not actually visiting the midpoint and ±31 of successive 273-cell intervals.

Instead, it creates a repeating pattern with gaps of:

SORTED BOMB LOCATIONSAfter sorting the addresses, the gaps follow a 31, 43, 31 pattern, rather than independent 273-cell intervals.

And this might actually be a better pattern than your stated interval approach!

You’ve accidentally—or perhaps deliberately—created a relatively dense, nonuniform bombing sequence with alternating gaps.

That could be effective against programs of around 35 instructions, because the spacing is close to their average length.

4. What I’d optimize next

I’d compare your current pattern against other spacings using the actual distribution of program sizes.

For a simple model with uniformly random program starting positions, we can calculate the expected probability of hitting at least one cell of an enemy program:

P(hit)=∑LP(L)C(L)NP(hit)=L∑​P(L)NC(L)​

where P(L)P(L) is the probability that an enemy program has length LL, C(L)C(L) is the number of distinct starting positions covered by the bombs, and NN is the core size.

This would allow us to test whether spacing by 31, 35, 40, or some other value produces the highest expected hit rate.

One caveat: your mean and standard deviation alone don’t determine the full program-length distribution. We’d need either the actual program sizes or an assumed distribution.

And the best bombing sequence also depends on how quickly the enemy acts, whether processes move or clone, and how much damage a single zero-write actually causes.

My verdict

I like the underlying idea a lot. You’re applying statistical information about the population of enemy programs to a tactical problem that is often approached with fixed heuristics.

The strongest part of the design is that you’re trying to minimize redundant bombing by matching bomb spacing to the characteristic size of enemy programs.

The weakest part of the mathematical argument is treating one standard deviation as inherently optimal. It may be a good heuristic, but it isn’t established as the optimum by the numbers you’ve supplied.

One thing I’m particularly curious about: was the add 74, r intentional?

Because that produces a 105-cell stride and the 31/43/31 gap pattern. If that was deliberate, I’d be interested in your reasoning—it makes the code more interesting than simply bombing three positions every 273 cells.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *