Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

All bots at the battle arena suddenly got brainfucked and no one can explain why. But who cares as long as they are still able to fight - although Brainfuck is the only language they understand anymore.


|       Owner        |          Bot            Score |
| LymiaAluysia       | NyurokiMagicalFantasy -  566  |
| weston             | MickeyV4              -  547  |
| Comintern          | CounterPunch          -  517  |
| Sp3000             | YandereBot            -  511  |
| Sylwester          | BurlyBalderV3         -  497  |
| LymiaAluysia       | NestDarwin            -  493  |
| Manu               | DecoyMaster           -  477  |
| DLosc              | LightfootPlodder      -  472  |
| IstvanChung        | Bigger                -  460  |
| Sylwester          | TerribleThorV2        -  455  |
| Timtech            | MetalDetector         -  433  |
| MikaLammi          | WallE2.0              -  428  |
| Mikescher          | MultiVAC              -  426  |
| csarchon           | TheWallmaster         -  403  |
| AndoDaan           | BeatYouMate           -  401  |
| ccarton            | AnybodyThere          -  401  |
| Sparr              | SeeSawRush            -  390  |
| PhiNotPi           | RandomOscillator      -  382  |
| Comintern          | 2BotsOneCup           -  379  |
| PhiNotPi           | EvoBot2               -  377  |
| Sylwester          | ReluctantRanV2        -  367  |
| PhiNotPi           | EvoBot1               -  367  |
| kaine              | SternBot              -  355  |
| Brilliand          | TimedAttack           -  354  |
| AndoDaan           | PrimesAndWonders      -  354  |
| DLosc              | Plodder               -  342  |
| Nax                | TruthBot              -  324  |
| Moop               | Alternator            -  312  |
| MikaLammi          | PolarBearMkII         -  309  |
| Sp3000             | ParanoidBot           -  308  |
| weston             | FastTrapClearBot      -  306  |
| icedvariables      | PyBot                 -  303  |
| TestBot            | DecoyBot              -  286  |
| TestBot            | FastClearBot          -  274  |
| Geobits            | Backtracker           -  267  |
| IngoBuerk          | Geronimo              -  243  |
| flawr              | CropCircleBot         -  242  |
| kaine              | BestOffense           -  240  |
| frederick          | ConBot                -  239  |
| AndoDaan           | EndTitled             -  232  |
| frederick          | 128Bot                -  232  |
| plannapus          | CleanUpOnAisleSix     -  223  |
| bornSwift          | ScribeBot             -  219  |
| DLosc              | ScaredyBot            -  205  |
| isaacg             | CleverAndDetermined   -  204  |
| PhiNotPi           | CloakingDeviceBot     -  199  |
| PhiNotPi           | CantTouchThis         -  195  |
| AndoDaan           | GetOffMate            -  187  |
| Cruncher           | StallBot              -  181  |
| Moop               | StubbornBot           -  166  |
| IngoBuerk          | Gambler               -  148  |
| SebastianLamerichs | Dumbot                -  134  |
| flawr              | DoNothingBot          -  127  |
| BetaDecay          | RussianRoulette       -  123  |
| mmphilips          | PacifistBot           -  109  |
| SeanD              | DontUnderstand        -  100  |
| proudHaskeller     | PatientBot            -  79   |
| Darkgamma          | TheRetard             -  70   |
| BetaDecay          | Roomba                -  70   |
| flawr              | MetaJSRandomBot       -  69   |
| frederick          | Dumberbot             -  61   |
| BetaDecay          | PrussianRoulette      -  28   |
| frederick          | Dumbestbot            -  0    |

Scores from 17.09.2014 - Could not include LethalLokeV2.1 due to runtime issues! Will run it on a faster computer next week

EDIT6: Discarded logs due to extreme size and runtime. You can generate them yourself by uncommenting the lines in RunThisTournament.py.

EDIT5: Implemented Abbreviation handling into the controller, no huge runtimes anymore. This has the side effect that numbers and parentheses are not treated as comments anymore. You can still use them if you want to provide an annotated version, but it would be very helpful if there would be also an uncommented version of your code, so I don't need to remove the comments manually. Thanks!

EDIT4: Changed the title, because the tournament got removed from the hot network questions. Thanks to @Geobits for pointing this out!

EDIT3: Removed comments in bf programs, due to an unexpected result, should be fixed now. If anyone has a problem with removing his comments, please report.

EDIT2: Since it caused an arcane runtime on my quite slow computer, I reduced the timeout limit from 100000 cycles to 10000 cycles. Not that anyone has turned the resultof a running game beyond this point anyway.

EDIT1: Fixed a bug in the convert script causing the interpreter to not ignore numbers in commented programs.


This is a Brainfuck tournament inspired by BF Joust. Two bots (Brainfuck programs) are fighting each other in an arena which is represented by a memory tape. Each cell can hold values from -127 up to 128 and wrap at their limits (so 128 + 1 = -127).

Valid instructions are similiar to regular Brainfuck, which means:

+ : Increment cell at your pointer's location by 1
- : Decrement cell at your pointer's location by 1
> : Move your memory pointer by 1 cell towards the enemy flag
< : Move your memory pointer by 1 cell away from the enemy flag
[ : Jump behind the matching ']'-bracket if the cell at your pointer's location equals 0
] : Jump behind the matching '['-bracket if the cell at your pointer's location is not 0
. : Do nothing

The arena has a size of 10 to 30 cells which is pseudorandomly chosen each battle. At both ends is a 'flag' located which has an initial value of 128, while all other cells are zeroed. Your bot's goal is to zero the enemy's flag for 2 consecutive cycles before he zeroes your own flag.

Each bot starts at his own flag, which is cell [0] from his own perspective. The opponent is located on the other side of the tape.

[ 128 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 128 ]
   ^                                             ^
my bot                                       other bot

Both bots execute their action simultaneously, this is considered one cycle. The game ends after 10000 cycles or as soon as one of the winning conditions is reached. If one of the programs reaches its end, it simply stops doing anthing until the end of the game, but can still win.

Winning conditions

Your bot wins under one of the following conditions:

  • Your enemy's flag is zeroed before yours
  • Your enemy moves his pointer out of the tape (executes > on your flag or < on his own)
  • Your flag's value is more far away from 0 than the value of your opponent's flag after 10000 cycles


Your post should contain a name for your bot and its code.

  • You can use the following abbreviation syntax to make your code more readable:
    • e.g. (+)*4 is the same as ++++, this is valid for any instruction except unmatched brackets in parentheses since the loop logic collides with the abbreviation logic. Please use [-[-[- instead of ([-)*3
  • Every other character than +-><[]. is a comment and therefore ignored, except ()* for abbreviations

Bots which do not follow the rules will excluded from the tournament.

  • Only basic Brainfuck is allowed, no other variants which supports procedures or arithmetic operations
  • Your bot's source code should not contain unmatched brackets

You may inform yourself about basic strategies but do not use another one's code for your own bot.


A bot's score is determined by the number of wins against all other bots. An encounter between 2 bots consists of 10 matches with different memory tape lengths, which results in a maximum score of 10 points per encounter. A draw results in no points for this match.

Control program

You can find the control program on github, along with the full logs from the battles. The leaderboard will be posted here once it is generated.

Feel free to clone the repository and try your bot against the others on your own. Use python Arena.py yourbot.bf otherbot.bf to run a match. You can modify the conditions with the command-line flags -m and -t. If your terminal does not support ANSI escape sequences, use the --no-color flag to disable colored output.

Example bots


(>)*9       Since the tape length is at least 10, the first 9 cells can be easily ignored
([          Find a non-zero cell
+++         Increment at first, since it could be a decoy
[-]         Set the cell to zero
]>          Move on to the next cell
)*21        Repeat this 21 times


>(+)*10     Set up a large defense in front of your flag
>(-)*10     Set up another one with different polarity
(>+>-)*3    Create some small decoys
(>[-]       Move on and set the next cell to zero
.           Wait one round, in case it is the enemy's flag
)*21        Repeat this 21 times

The DecoyBot will win every match with a tape length greater than ten, since the FastClearBot can avoid the small decoys, but not the larger ones. The only situation in which the FastClearBot can win against DecoyBot, is when it is fast enough to reach the enemy's flag before his opponent has built up large decoys.

share|improve this question
Original, I like it. I'm just afraid that this won't allow for enough strategical depth, but that might be just me. –  ɐɔıʇǝɥʇuʎs Aug 22 at 17:54
This would be even more fun with Befunge. –  IchBinKeinBaum Aug 22 at 18:09
I am not getting what the [91m] notation is in the output –  Moop Aug 22 at 20:07
I found a BF Jousting webpage which can run and visualize jousting matches. –  PhiNotPi Aug 23 at 11:33
Thanks for hosting this KOTH, Cipher. Must be a lot of work with so many submissions. –  AndoDaan Aug 25 at 17:05

58 Answers 58

Don't Understand

I don't know what's going on, so I've chose some good looking lines from other programs

(>)*9    nine noses
(        open bracket
>-->     a fish
(>+>-)   I'm watching you
>+       headless man
)        close that bracket

I'm confident of success

share|improve this answer
Had to lol at your 'explanation' :P –  Chris Cirefice Aug 23 at 0:05
I had to register to upvote this, and to thank you for the most pleasant laugh I've had in a long time :) –  user1853181 Aug 23 at 11:07
"I'm confident of success" — I think so too! –  tomsmeding Aug 23 at 11:58
Reminder: Upvote good posts, not ones that make you laugh. (I'm being way too serious right?) –  immibis Aug 24 at 7:13
This post is good because it made me laugh –  wim Aug 25 at 13:29

Cloaking Device Bot

This bot basically tries to hide its base, making it so that other bots will move right past it and off the tape.

share|improve this answer
Very clever, had to adjust my bot to account for this. –  Moop Aug 22 at 21:25
This is one of the most clever ones in here, in my opinion. –  Almo Aug 26 at 21:24
+f for first cloaker. I didn't notice this one before after I made Ràn but it's similar idea, different application. –  Sylwester Sep 1 at 17:01

Burly Balder v3

Burly Balder is a medium slow rush. It makes two large decoys before going into rush mode. In rush mode it has a loop that only uses 4 steps each zero cell and when a non zero cell it has a case analysis for [-18,18] before blindly reducing with 107 before clearing with [-.]. He clears an unchanged flag in 242 steps, 114 more than a uncertain -*128 and 14 less than a naive [-] clear. When a cell is cleared he continues leaving a trail of -2 decoys. He has a special case only for index 9 to save some steps for size 10 games and it leaves the cell with a 1 decoy.

>((-)*18>)*2                                  Make two minus seventeen decoys
(->)*6                                        Move to cell nine

[                                             special case for ten cell game 
   +[+[+[+[+[+[+[+[+[+[+[+[+[+[+[+[+[+[       if not minus one to minus eighteen 
   (-)*18                                     decrease by eighteen
   -[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[       if not plus one to plus eighteen
       (-)*107                                decrease by hundred and seven
       [-.]                                   slow clear
   ]]]]]]]]]]]]]]]]]]                         end plus conditionals
   ]]]]]]]]]]]]]]]]]]                         end minus conditionals
]                                             end special case
([>                                           while true go right
  [                                           start clear cell 
   +[+[+[+[+[+[+[+[+[+[+[+[+[+[+[+[+[+[       if not minus one to minus eighteen 
   (-)*18                                     decrease by eighteen
   -[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[       if not plus one to plus eighteen
       (-)*107                                decrease by hundred and seven
       [-.]                                   slow clear
   ]]]]]]]]]]]]]]]]]]                         end plus conditionals
   ]]]]]]]]]]]]]]]]]]                         end minus conditionals
  ]                                           end clear cell
  --                                          set to minus two 
 ]                                            while true end
 -                                           decrease and loop
)*5                                          In case of clash or initial column minus seven is zero

Trivia: Balder is a nordic god and son of Odin. He is known mostly for the story of his death: He was scared for his safety so the other gods tried to predict and shield against every threat. He was eventually killed by Loki since while they protected him against swords and arrows they forgot to protect him against Mistletoe.

share|improve this answer
Your decoys are killing me. Well done. –  AndoDaan Aug 25 at 16:08
@AndoDaan Thanks. Your BeatYouMate was clever. I fear the decoys on most bots are going to get even bigger next round until it gives a penalty. Then we'll perhaps have some more cool strategies emerging :) –  Sylwester Aug 25 at 16:51
Problem with increasing the decoy size is that it trades off with performance on shorter tapes against fast attack bots. With 10 random rounds there is more likely a sweet spot that changes depending on how fast the other entries attack. –  Comintern Aug 25 at 22:44
Yep, you're still the one to beat. –  AndoDaan Aug 27 at 14:17
@AndoDaan With so many nordic gods to support me the random arena sizes seem to be in my favor :-) –  Sylwester Aug 27 at 15:18


It assumes most people will zero a cell by either adding or subtracting to it, so on average every cell will take 128 turns to zero.


Annotated version

(>+>-)*4       Move eight squares alternating polarity    
>+             Move one more
    >          Move to the next square
    [-]        Zero it
    [.]        Wait while it is zero
)*21           Repeat
share|improve this answer
Damn, your latest changes improve the win rate for Alternator against Geronimo from ~60% to ~90%. Nice. –  Ingo Bürk Aug 22 at 20:32
yeah, i was moving 18 times when i did (>+>-)*9, so it would fall off the tape. Silly mistake. –  Moop Aug 22 at 20:33
Even protecting Geronimo by alternatingly adding/subtracting to zero the cell does not change my win rate at all. Alternator might come out as the winner here -- it uses few cylces to set a fairly hard to crack trap. –  Ingo Bürk Aug 22 at 20:37
Hey, correct me if I'm wrong but doesn't this bot automatically move off the board if the board is 10 long? It's moving 10 squares before attempting to set anything to zero. –  A Boschman Aug 31 at 18:51

EvoBot 1

This is a simple bot created via genetic algorithm. I started with a template, and my program slowly adjusted the numbers to create a better warrior-bot. The code below has been edited to increase readability.


I used the other entries in the competition to measure the fitness of the different candidates.

Since this was my first attempt at an evobot, I started with a simple template:

>(+)*n>(-)*n(>)*n(>[(+)*n[-]])*30  #template

I predict that this bot will receive a score in the 50s to 60s range.

I am currently working on a reverse decoy template.

EvoBot 2

This is a bot created by the same genetic algorithm, but with the following template:

>>>>(-)*n<(+)*n<(-)*n<(+)*n(>)*8(>[+++[-]])*30  #template

This bot uses the reverse decoy strategy to set 4 decoys of varying height. The resulting bot is:


I expect this new bot to fare better than the previous bots, possibly earning a score in the 70s (probably much higher than that since there are many new entries).

share|improve this answer
+1 for genetic algorithms. I have great faith in them. I hope your bots do well. –  AndoDaan Aug 24 at 21:49

So, someone else here using an genetic algorithm to try and make programs here. Well... a long time ago, I wrote an BF Joust evolver for an ongoing hill in an IRC channel. I decided to give it a spin for this contest as well~

And... unlike the other person with an evolver, my evolver can actually change more of the program more than repeat counts. :)

NestDarwin (Generation 309)

This is the best result my evolver has come up with so far. I'm not sure how much the nested structure helps in this case, but, structures like this was what the evolver is meant to be able to do. Expected performance on the 27.08.2014 hill is 474 points. (Calculated by running the battle on all 21 tape lengths, and multiplying by 10/21. Note that this isn't normalized for the fact that this hill has one extra program on it)


EDIT: Changed list of programs I wanna enter into this hill. Ran evolver overnight. :)

EDIT 2: I went and manually analyzed the evolver's output. Despite looking very different, NestDarwin is basically an optimized version of TinyDarwin... Manually minimized (with identical functionality) and analyzed:

(-)*5                     Break stuff that assumes flag size.
(>[(-)*8[.+]](-)*7)*3     Make a few larger decoys next to our flag. 
                          The clear loop is basically dead code here.
                          Few things are going to approach so fast, so.
(>[(-)*8[.+]](-)*2)*10000 And go on an rampage with an offset clear!
                          I presume the slow clear is to beat tripwires.

So, an almost identical program would be as follows... which is basically a super-optimized version of TinyDarwin.


TinyDarwin was as follows. Not very different, hun? I'm just going to withdraw it from the hill. I thought it was distinct, but... well, I was wrong.


It's become apparent that the current hill isn't strong enough to allow it to evolve much more complex things. :(

share|improve this answer
Congrats with first place. Is the genetic algo program able to use your current version as a template and continue with the new versions to improve it even further? –  Sylwester Aug 29 at 18:21
Great job with first place. I'm so happy a genetic algorithm (well, its spawn) made it up there! –  AndoDaan Aug 29 at 18:43
Now if we could take the results of all the games, evolve more, add some machine learning... then us pitiful humans will no longer have any chance :P –  Sp3000 Aug 30 at 8:32
@Sylwester Sort of? My internal representation uses a (poorly thought out) gene activation system that's supposed to let it evolve superstructure (and in practice, doesn't really). I can't put the final program back and recover the internal representation, but I can put the instructions into a single gene and let it continue evolving (however much that would help). –  Lymia Aluysia Aug 30 at 11:38
@Sp3000 Unfortunately my algorithm can barely make progress on the well developed #esoteric hill. It'd be nice if I could do such a thing, but, alas, my skill at genetic algorithms just isn't good enough. I'll probably release my evolver some day when I get all my ugly hacks cleaned up. –  Lymia Aluysia Aug 30 at 11:39

Polar bear Mk II

There are two kinds of polar bears: those who get trapped and those who trap other people.

Tries to guess polarity of the opponent and then uses that information to lock opponent into infinite loop. Works well against simple clearing strategies and somewhat randomly against other. Traps can be quite easily avoided so I might add some backup strategies later.

>++>- create polar bear traps
(+)*290 (>)*9  (+)*120 (.+)*16 (<)*9
(+)*112 (>)*10 (+)*120 (.+)*16 (<)*10
(+)*112 (>)*11 (+)*120 (.+)*16 (<)*11
(+)*112 (>)*12 (+)*120 (.+)*16 (<)*12
(+)*111 (>)*13 (+)*120 (.+)*16 (<)*13
(+)*111 (>)*14 (+)*120 (.+)*16 (<)*14
(+)*111 (>)*15 (+)*120 (.+)*16 (<)*15
(+)*110 (>)*16 (+)*120 (.+)*16 (<)*16
(+)*110 (>)*17 (+)*120 (.+)*16 (<)*17
(+)*110 (>)*18 (+)*120 (.+)*16 (<)*18
(+)*109 (>)*19 (+)*120 (.+)*16 (<)*19
(+)*109 (>)*20 (+)*120 (.+)*16 (<)*20
(+)*109 (>)*21 (+)*120 (.+)*16 (<)*21
(+)*108 (>)*22 (+)*120 (.+)*16 (<)*22
(+)*108 (>)*23 (+)*120 (.+)*16 (<)*23
(+)*108 (>)*24 (+)*120 (.+)*16 (<)*24
(+)*107 (>)*25 (+)*120 (.+)*16 (<)*25
(+)*107 (>)*26 (+)*120 (.+)*16 (<)*26
(+)*107 (>)*27 (+)*120 (.+)*16 (<)*27
(+)*106 (>)*28 (+)*120 (.+)*16 (<)*28
(+)*106 (>)*29 (+)*120 (.+)*16 (<)*29
(+)*106 (>)*29 [-]
(-)*290 (>)*9  (+)*120 (.+)*16 (<)*9
(-)*112 (>)*10 (+)*120 (.+)*16 (<)*10
(-)*112 (>)*11 (+)*120 (.+)*16 (<)*11
(-)*112 (>)*12 (+)*120 (.+)*16 (<)*12
(-)*111 (>)*13 (+)*120 (.+)*16 (<)*13
(-)*111 (>)*14 (+)*120 (.+)*16 (<)*14
(-)*111 (>)*15 (+)*120 (.+)*16 (<)*15
(-)*110 (>)*16 (+)*120 (.+)*16 (<)*16
(-)*110 (>)*17 (+)*120 (.+)*16 (<)*17
(-)*110 (>)*18 (+)*120 (.+)*16 (<)*18
(-)*109 (>)*19 (+)*120 (.+)*16 (<)*19
(-)*109 (>)*20 (+)*120 (.+)*16 (<)*20
(-)*109 (>)*21 (+)*120 (.+)*16 (<)*21
(-)*108 (>)*22 (+)*120 (.+)*16 (<)*22
(-)*108 (>)*23 (+)*120 (.+)*16 (<)*23
(-)*108 (>)*24 (+)*120 (.+)*16 (<)*24
(-)*107 (>)*25 (+)*120 (.+)*16 (<)*25
(-)*107 (>)*26 (+)*120 (.+)*16 (<)*26
(-)*107 (>)*27 (+)*120 (.+)*16 (<)*27
(-)*106 (>)*28 (+)*120 (.+)*16 (<)*28
(-)*106 (>)*29 (+)*120 (.+)*16 (<)*29
(-)*106 (>)*29 [-]
share|improve this answer
You can halve the code size with (]< (+)*290 (>)*9 ... [-])*2? –  Sylwester Aug 26 at 23:48
@Sylwester I can't because the other half uses + and the other one uses -. –  Mika Lammi Aug 27 at 5:31
Polar Bear doesn't do very well with offset clears... awesome idea though –  Sp3000 Aug 27 at 8:32
@Sp3000 Are you sure? I tried with several offsets and polarities (like [(+)*3[-]], [(-)*6[+]]) and it works great (at least for quite small offsets). –  Mika Lammi Aug 27 at 9:05
Oh, I know what's wrong :/ I was trying programs like >>>>>>>>>((-)*4[+][--.]>)*21 which double check the cell and your (+/-)*290 was causing the second off-sync loop to be triggered. Not the offset clear's fault. –  Sp3000 Aug 27 at 9:47

Pacifist Bot

My bot believes violence is never the answer and will try to avoid combat at all costs.

(.)*8       Since it takes at least 9 turns for a bot to come to mine, remain idle for 8.
>           Skedaddle over one spot
([(>)*8     If a bot has approached, RUN!
[(<)*8      If you accidentally ran into a bot, run the other way this time
]].         If it's safe here, chill out.
)*6249      keep running until the end of battle, or until tired.
share|improve this answer
I took the liberty of removing the '.'s in your comments since they would count as Brainfuck code and make your bot a little bit slower than necessary. If the dots are deliberate, feel free to correct me! –  Cipher Aug 23 at 10:51
Oh right the .'s were rather silly of me, thanks for removing them :p –  mmphilips Sep 2 at 13:06


Periodically looks behind to determine when the enemy has started clearing it's decoys, then rushes ahead.

Seems to do well, but I'm not sure if that's because of the strategy or just because I'm adding 10 to every cell before clearing.

Edit: Fixed a logic problem. First time writing a brainfuck program. It lives up to it's name.

>>>+<(+)*5<(-)*5>>             Initial defense
[                              While he hasn't passed us yet
  (>[([(+)*10[-]]>)*29])*4     Jump ahead four, checking for enemy
  +                            Front marker
  <<<<                         Check behind
  [                            If he hasn't passed us yet
    (+)*5<(-)*5                Set decoys in reverse
  >>>>                         Check ahead
([-[(+)*10[-]]]>)*29           Clear to the end
share|improve this answer
+1: This is the first bot I've seen that strings decoys (other than +/-1) out beyond the first 9 cells. On longer tapes, that's a killer. Retrofitting Lightfoot Plodder some more now... –  DLosc Aug 25 at 23:14

WALL-E 2.0

Rushes to location 9 and adds 128 to it, winning quickly in size 10 arena if opponent hasn't changed initial flag value. On larger arenas, this works as large decoy. After that it fills the space between location 9 and own flag with large decoys. When decoys are placed, it scans for non-empty locations and tries to clear them quickly.

Version 2.0 builds larger decoys and has some tolerance against changing initial flag value. It can also switch to backup strategy if things start to look hairy.

(+)*128 <
< [ (<)*7 ((-+-)*256)*15 ] > [ (<)*8 ((+-+)*256)*15 ]
(-)*47 < (+)*63 < (-)*72 < (+)*69 <
(-)*84 < (+)*66 < (-)*76 < (+)*66 <
++++ (>)*9 +.+.+.----.-.-. (>[-[++[(+)*124.+.+.+.+.+.+.+.+.>]]])*21

Effectiveness of this bot is based on two facts:

  1. Most bots do not change the initial value of their flag.
  2. Building large decoys is faster than clearing them.
share|improve this answer
These walls are killing me –  Sp3000 Aug 28 at 13:16


Is even more offensive than kaine's BestOffense bot as it does not build up any defense. The strategy here is: Others will try to be clever, but being clever takes cycles. So let's just skip to the part we know the enemy is in and clear everything we find.


Seems to win most matches against the OP's example bots and kaine's bot.

share|improve this answer

CounterPunch - Edited

Balanced combination of building a strong defense and then attacking.



(+)*6                             Switch polarity of the flag
>(-)*12                           Build a quick decoy in front of the flag
(>)*7(<(-)*12<(+)*12)*3           Hop out and start building decoys backward
(>)*7                             Tally ho!
(([-([(-)*6[+.]])*5])*4>)*21      Clear toward the opposite end

Defends similar to @Geobit's Backtracker, but defends against fast attackers by putting a quick decoy out in front of the flag first.

Attack is nested clearing with opposite polarity to quickly clear out decoys with smallish values. Worst case scenario should be a decoy of 64 (either polarity).

Edit 1: Improve attacking efficiency against decoys (had a logic error in the polarity switching).

Edit 2: Testing indicates that the pause performs slightly better in the inner-most loop.

share|improve this answer


An actual half serious bot now that things are started. Addressing the simular nature of some of these bots.

share|improve this answer
SternBot gives me parity issues :( –  Sp3000 Aug 26 at 12:49


A reverse decoy strategy. Start laying decoys down from the front back, so nobody skips over the rest as I'm building them.

If the board is less than size 20 or so, this doesn't work against fast-attack bots, since we'll just pass each other before I start decoying.


(>)*9                   Jump ahead 9
((-)*4<+<-<(+)*4<)*2    Lay down alternating polarity/size decoys for 8 spots behind
(>)*8                   Jump back forward
(>[-])*21               Clear until flag

Note: I don't BF, but this like it does what I want to me. If not, please let me now.

share|improve this answer


A simple-yet-efficient bot.
Create some traps, then destroy the other flag.

share|improve this answer

Can't Touch This

This is a defense-oriented program that attempts to determine how the opponent is clearing cells, and builds a decoy of the appropriate size.

>---    create 1st decoy
>+      decoy for timing
>+      decoy for waiting
[]<     tripwire activated!
[<-->]  increase size of 1st decoy while opponent clears 2nd decoy
(>)*8   attack!
[+(<)*9(+)*20(>)*9]    slowly clear, while going back to stop enemy progress

I am currently working on a version that can win against both polarities.

share|improve this answer

Lethal Loke V2.1 (with Mistletoe)

This is of course a deadly bot and he kills not only beautiful Burly Balder a with mistletoe, but wins almost every time against the other bots as well. It is a combined medium and fast rush. My test gives me a score of 567

Compiled BFJ file for battle, Racket BFJ generator source:

#lang racket
;; bare minimum bfj support
(define (bf . args)
  (apply string-append 
         (map (lambda (x) 
                (if (number? x)
                    (number->string x)

(define (dup x num)  
  (let loop ((n num) (lst '()))
    (cond ((< n 0) (error "Negative n"))
          ((zero? n) (apply bf lst))
          (else (loop (sub1 n) (cons x lst))))))

;; Useful procedures
(define (wiggle amount default-zero n)
  (let rec ((n n))
    (if (zero? n)
        (bf "["
            (dup "-[" amount)
            (bf "(+)*" amount)
            (dup "+[" amount)
            (rec (sub1 n))
            (dup "]" (* amount 2))

(define (goto from to)
  (let* ((dst (- to from))
         (op (if (> dst 0) ">" "<"))
         (abs (if (> dst 0) dst (- dst))))
    (if (= from to) 
        (bf "(" op ")*" abs))))

(define max-position 30)
(define initial-decoy  "(-)*17")
(define small-decoy "(+)*10")
(define large-decoy "(-)*32")
(define flag-position 7)
(define decoy-phase-end-position 14)
(define wiggle-amount 8)
(define plodd-clear "..(+)*120(+.)*27>")
(define plodd-inner-clear (bf "(+)*" 
                              (- 78 wiggle-amount) 
;; Main body of Loke V2
(define (generate-loke2)
  (bf ">" 
      (let gen-rec ((n flag-position) (p #t))
        (if (> n decoy-phase-end-position)
            (bf (medium-slow n))
            (bf "[" 
                (medium-slow n)
                (if p small-decoy large-decoy)
                (gen-rec (+ n 1) (not p)))))))

;; Retreat goes back to home
;; leaving a trail of flags
;; from flag position
(define (medium-slow last-index)
  (bf (goto last-index 2)
      (let medium-rec ((n 2) (p #f))
        (if (= n flag-position)
                (fast-rush n last-index)
            (bf (if p "-" "+")
                "[" (fast-rush n (max 9 last-index)) "]" 
                (if p small-decoy large-decoy)
                (medium-rec (+ n 1) (not p)))))))

(define (fast-rush cur-position last-known)
  (bf (goto cur-position last-known)      
      "([" plodd-clear 
      (wiggle wiggle-amount
              (- max-position last-known 1))
      ">)*" (- max-position last-known)
      "]>)*" (- max-position last-known)))

(display (generate-loke2))

Trivia: Loke (Loki) is a god in Nordic mythology that likes to play with everyone and trick them. He is a shape shifter (into animals and people) and usually goes his own ways. In the stories he often travel with and assist the other gods and does small tricks and stir things up. Besides killing Balder he fathered Hel (godess of Hell/Helvete), the beast Fenrir, and the Midgard Serpent that starts Ragnarok (norse armageddon).

How it works

In the beginning he makes a large (-17) decoy then make +- pattern all the way to index 7. He scan forwards from to 13 leaving a trail of (+10,-32)+ decoys but when he detects a set he will abort and start a medium*1 rush mode. If no cells are set he will also start the slow*3 rush mode.

*1 In medium rush mode he has detected opponent activity in one of index 7-13 and he starts from index 2. Some opponents leave a zero and other leave a different value and he now have means to detect opponent activity while before making decoys in index 2-6 (-32,+10)+. If cell is not expected value (-1, 1) or he finished making all decoys he goes in fast*2 rush mode.

*2 The fast rush mode he expects he has been detected so decoys won't work. We hope the ones we already have set is stopping the opponent and focus on running through opponents decoys. He starts rushing at the farthest point we know based on the previous scanning [9,14] or index 9 if we were made earlier than that. He has special case for first decoy where we just add 120 and plodd 27 since he doesn't want to reduce tha value below zero incase it's a trap, but for every decoy after we wiggle clear at [-8,8] before increasing by 120 and plodding 27 steps ebfore contiuing forward to next cell.

Slow rush mode was removed since it didn't affect the score with the current hill and it makes my bot a little smaller (but not much).

share|improve this answer
Now we're starting to see insanity. I like it. –  Sp3000 Sep 3 at 16:46
@Sp3000 YandereBotv2 was the reason I needed to think new besides just increasing the decoys and swing values. It had a higher win percentile against the hurd than all the bots last round so you were just unlucky with arena sizes. –  Sylwester Sep 4 at 10:00
Ahaha maybe - I think I need a counterplan against the ever-increasing decoy sizes :/ I really like how you have different modes though –  Sp3000 Sep 4 at 10:37
sigh. I'll have to get my HLL for BF Joust working better so my evolver can stand a chance again. Congratulations on #1~ –  Lymia Aluysia Sep 5 at 16:37
@LymiaAluysia Thanks. I was more surprised of Balder. I'm counting on a new versions of NestDarwin, YandereBot and Mickey :-) –  Sylwester Sep 5 at 19:57

Lightfoot Plodder - EDITED

Based on the Plodder, this speedy behemoth is able to "fast forward" through consecutive 0's quickly until it reaches something nonzero (at which point it starts plodding as expected).

Now improved with a more robust skimming algorithm, which also allows fast-forwarding through small decoys, and bigger decoys of its own.

Edit #2: Now is able to go back to skimming if it finds more pockets of zeros.

> -
share|improve this answer
Nice "convenient" size change there :) –  Istvan Chung Aug 26 at 4:14
@IstvanChung Very convenient. ;) Any more would have slowed me down too much, losing points to several other bots. If you made Bigger bigger, I don't think I'd try to keep pace. –  DLosc Aug 28 at 22:44
Well, I've bumped the size by just a bit to see how it works. I think Bigger might be able to pull off an even larger size, but don't have time to test it thoroughly. Good luck! –  Istvan Chung Aug 28 at 23:31
Love the counter measure against the Cloacking bots and the fact that this actually looks like BF programming :) –  Sylwester Aug 29 at 12:00

ImpatientTripwire (a.k.a. YandereBot)

Tries to be a tripwire so that it can lay decoys of (mostly) the corresponding polarity, but gives up if you take too long and assumes you're the opposite parity instead. Has a reverse tripwire for small boards.

(+)*5                                     Toggles the base
>-                                        Sets up reverse tripwire
>>++>-->                                  Sets up basic decoys    
(+)*20                                    Makes a massive antioffset tripwire
(([)*150                                  Waits for a while
    <<<<                                  Goes to check on the other tripwire
      <                                   Bot found you and is furious
      ((+)*128 (>)*9 (+.)*55 (<)*9)*5     Tries to tie you up
      ((+)*128 (>)*10 (+.)*54 (<)*10)*5   And torture you
      ((+)*128 (>)*11 (+.)*53 (<)*11)*5   As it destroys the world
      ((+)*128 (>)*12 (+.)*52 (<)*12)*5
      ((+)*128 (>)*13 (+.)*51 (<)*13)*6
      ((+)*128 (>)*14 (+.)*50 (<)*14)*6
      ((+)*128 (>)*15 (+.)*49 (<)*15)*6
      ((+)*128 (>)*16 (+.)*48 (<)*16)*6
      ((+)*128 (>)*17 (+.)*47 (<)*17)*6
      ((+)*128 (>)*18 (+.)*46 (<)*18)*6
      ((+)*128 (>)*19 (+.)*45 (<)*19)*6
      ((+)*128 (>)*20 (+.)*44 (<)*20)*6
      ((+)*128 (>)*21 (+.)*43 (<)*21)*6
      ((+)*128 (>)*22 (+.)*42 (<)*22)*7
      ((+)*128 (>)*23 (+.)*41 (<)*23)*7
      ((+)*128 (>)*24 (+.)*40 (<)*24)*7
      ((+)*128 (>)*25 (+.)*39 (<)*25)*7
      ((+)*128 (>)*26 (+.)*38 (<)*26)*7
      ((+)*128 (>)*27 (+.)*37 (<)*27)*7
      ((+)*128 (>)*28 (+.)*36 (<)*28)*8
      ((+)*128 (>)*29 (+.)*35 (<)*29)*8      
    >>>>)*2                                 Waits again
      <(+)*20                               Bot got stood up, is sad
      <(+)*20                               Sets up some decoys
      <(+)*20                               Grabs a knife
      <(-)*20                               Licks the blade
      <(-)*5                                Locks the house
      >>>>>>>>                              Goes to hunt you down
       >                                    Start searching
         +[+[+[                             Search from minus three
         -[-[-[                             To plus three
         (-)*17                             If that's no good, do an offset
         [+]                                Clear by adding
         [-.--]                             Just in case
         ]]]]]]                             I would duplicate the program to skip these like at
       ]                                    the bottom but the file would get too large
       [--.---]                             Also just in case
       -                                    Leave a small trail
  ]                                         Skip the bracket closing
  <(-)*20                                   Bot found you and is happy
  <(-)*20                                   Has just the perfect presents for you
  <(-)*20                                   You like decoys right?
  <(+)*20                                   Here's a plus one in case you are sneaky
  >>>>>>>>                                  Time to hunt you down


Current version: 1.3 - edited to do better on smaller boards, at the expense of losing games due to enemies sneaking past during tripwire checking

Past versions: 1.2.1

(I need a better clear algorithm :/ )

share|improve this answer
OMG 411k fully expanded and stripped :-O Chiper's code just hangs on this. –  Sylwester Aug 26 at 14:41
Just changed a few of the comments so that it now works with Cipher's new code –  Sp3000 Aug 27 at 0:43
since the latest edit, unmatched brackets in parentheses behave weird since the loop logic collides with the abbreviation logic. can i change constructs like ([)*300 back to [[[ and so on ? –  Cipher Aug 27 at 10:34
@Cipher Yeah, go for it - although the pastebin version should be exactly just that –  Sp3000 Aug 27 at 10:38
3rd is a nice place to come in on. Well done. –  AndoDaan Aug 27 at 14:17

Reluctant Rán v2

The strategy is easy. Try to get the opponent to think her flag is a decoy and precede past the board and loose (a kind of tripwire / vibrator). After 10 full rounds she gives up and tries to determine if opponent is at her flag and if not she will make -17 decoys until she hits a set cell. The clearing method she uses is special case for [-12,12] and starts plodding similar to Loke.

>>-<<                                  set a flag
(.)*11                                 wait for sixteenth step
((-)*256)*10                           reduce by ten rounds
                                       We give up check flags
> [(>)*7                               detected fast rush mode
        -[-[-[-[-[-[-[-[-[-[-[-[       from plus one to twelve
        (+)*12                         reduce by twelwe
        +[+[+[+[+[+[+[+[+[+[+[+[       from minus one to twelve
          (+)*66..(+)*41(+.)*17>       increase and plod
>+[(>)*6                               detected fast rush mode
        -[-[-[-[-[-[-[-[-[-[-[-[       from plus one to twelve
        (+)*12                         reduce by twelwe
        +[+[+[+[+[+[+[+[+[+[+[+[       from minus one to twelve
          (+)*66..(+)*41(+.)*17>       increase and plod
[>[                                    propably a trapper so we move slow
    ..+..-(+)*119(+.)*17               plodd the first cell so we dont go to zero on low positive
        -[-[-[-[-[-[-[-[-[-[-[-[       from plus one to twelve
        (+)*12                         reduce by twelwe
        +[+[+[+[+[+[+[+[+[+[+[+[       from minus one to twelve
          (+)*66..(+)*41(+.)*17>       increase and plod

Trivia: Rán is a Nordic Mythology sea goddess that takes sailors before they die at sea.

share|improve this answer


This is closely related to my Geronimo bot. But where Geronimo is playing a sure thing, the Gambler tries to be quicker by doing what it does best -- gambling: It goes to the 20th cell and starts zero-ing from there.

That means that it might easily lose just because the arena isn't that big. But if it is, it might be the few cycles that count.


Fun Fact: I was really considering entering a bunch of bots which all look like (>)*X(>[-])*Y where X in 9..29 and Y = 30 - X. But I think entering twenty bots would be a little too much :) Or even forty if I had two versions, one which zero-s with [+] and one that does it with [-].

share|improve this answer
Wouldn't a number like 13, or 14 give you better win percentages than 20? –  Moop Aug 22 at 21:17
Yes, maybe. I just want for the middle. Interestingly if I just go left instead of right my win chances go down by a lot. Would've expected the opposite. –  Ingo Bürk Aug 23 at 7:08
Since each bot fights then matches against any other bot, even 40 of those wouldn't lift your chances that much - and I had a hard time of copying and pasting :D –  Cipher Aug 23 at 10:55


A remarkably stupid bot that just messes with the environment and hopes that the bots it battles all go off the tape.


(I'm not sure if this even works - it doesn't error out though!)

Annotated (with what I think it does):

(+)*50      Increase home cell by 50
(>-)*7      For next 7 cells, decrement once
(           Open loop
([.])*50    If cell is non-zero, do nothing. If cell is zero... Still do nothing? I'unno.
(+)*50      Now let's increment it fifty times for some reason.
>)*7        And let's do the above two instructions ten times more, in the next 7 cells
([-])*256    If the cell we're on is non-zero, decrement it continuously and hope it's the enemy.

(I will be staggered if this wins a single battle)

share|improve this answer
your second line will actually zero the cell by addition, and then subtract one seven times in a row. –  proud haskeller Aug 22 at 23:37
@proudhaskeller You're right... That's what I get for trying to do Brainfuck stuff with little sleep. Have just made it simpler in lieu of actually working out how to do it properly. –  Sebastian Lamerichs Aug 22 at 23:43


And because everybody should post a bot that will beat the first bot they post, here's a 5+ decoy laying bot:

share|improve this answer



Sets a few small traps, then races over to the other side, and tries to clear everything, above or below zero. Fails on ----.

share|improve this answer
+++ before [-] is indeed clever to avoid simple traps! –  Ingo Bürk Aug 23 at 12:03
Threw exception due to an unmatched (, can I treat it like a comment? –  Cipher Aug 23 at 16:30
@Cipher I'll fix that, sorry. –  isaacg Aug 23 at 21:16



The idea behind this bot is making something total random that is still a valid js code without too much uselessness. I wrote following code (JSFiddle link) for generating it. Lets see how well it does=)

var nchars = 30;
var nbrack = 10;
var alphab = "+ - < >".split(' ');
var s = [];
for(var i=0;i<nchars;i++){
var ind1,ind2;
for(var i=0;i<nbrack;i++){
    ind1 = (s.length*Math.random())|0;
    ind2 = ((s.length-ind1-1)*Math.random())|0 + ind1;
s = s.join('')
for(var i=0;i<Math.max(nchars,nbrack);i++){//remove useless stuff
share|improve this answer

Prussian Roulette

Russian Roulette made a bet with his friend Prussian, and now it's his turn to play.

share|improve this answer
You have 2 pointer decrements and only 1 increment in your main loop - this is going to hop you off your own end of the tape. –  Comintern Aug 24 at 16:26
@Comintern Ahh thanks –  Beta Decay Aug 24 at 16:26
This will still just throw itself out. –  proud haskeller Aug 24 at 23:15
Right at beginning you have a plus followed by a minus. 2 wasted cycles. –  weston Aug 28 at 23:29


The best defense (...) is ignorance.


It does nothing.

EDIT: Wow, I was astonished to see that it did a better job than more than the least 20% of all bots=) (Does this mean it uses a superior strategy or ....?)

share|improve this answer
Some of the other bots take suicide on small arenas. eg. Gambler goes directly to 20th cell and for games wth 10-19 it will loose, even against DoNothingBot –  Sylwester Aug 26 at 22:48
Just out of curiosity, I ran this through my tester (plays all tape lengths) against the other entries. Behold the wall of shame... +1 –  Comintern Aug 27 at 5:01
Haha, Thank you for sharing - I expected that there might be one or two black sheeps but I did not expect that it 'defeats' so many bots=) –  flawr Aug 27 at 7:45


The arms race begins!!

Both builds and destroys walls of height 16 18, bigger than most competitors. Also has a little logic to beat the cloaker, flag-defenders, anti-alternators, and bots that assume an untouched flag


Annotated version

Off by one
Adjust own flag a little for fun

Decoy stage
Build decoys

>->+>+>-        Add four quick walls to deter rushers
                Also throw off bots depending on the alternation
 >(+)*18)*2     Build four large decoys

Clear stage
(               Repeat the following forever:
  >             Move forward
  ([            Skip if the space is zeroed already
      (+)*18    Bust negative decoys smaller than 18
      [-]       Clear
      [-[+]]    Check that the wall is actually cleared; if it isn't,
                clear in the opposite direction to defeat bots that try
                to sense our clear direction and defend the flag
  ])*2          Repeat the "non-zero" check to guard against the cloaker
share|improve this answer

Nyuroki Magical Fantasy

I think it's about time to get serious~ I finished up my compiler for a little HLL to make writing BF Joust programs easier. This was my first serious attempt to make something with it. The bot's concept is pretty simple. It sets up a few decoys of varying polarities, then goes crazy with a large wiggle clear with a reverse offset clear in the middle.

Oh, by the way, the expected score is roughly 577 points against the last round's hill. That's a 93% win rate. <3

Compiled | Source Code

Nyuroki Magical Fantasy by Lymia Aluysia
Released under the terms of MIT license


Edit: I squeezed a few more wins out of Nyuroki.

Edit 2: Hey, look, I did it again!

Edit 3: After wrestling for a while with a stupid parsing bug in Arena.py, I finally got another improvement in~ This is what I mean by "time to get serious", you know. <3

share|improve this answer
Seems like Loke need some adjusting :-) Love your language. Was the bug in Arena.py that you had whitespace between ) and * or between * and number? –  Sylwester Sep 6 at 15:18
@Sylwester Much much worse. Loops going where they shouldn't be going: github.com/redevined/brainfuck/pull/6 –  Lymia Aluysia Sep 6 at 15:28
Congrats with #1. 92,5% win rate is going to be hard to match. –  Sylwester Sep 8 at 15:40
Well done, but isn't this shorthand abuse? The nested loops are effectively 21 factorial = 5*10^19. In other words it's effectively unexpandable into basic brainfuck. –  weston Sep 8 at 20:00
@weston Yes. And most programs on the most developed BF Joust hill (codu.org/eso/bfjoust/in_egobot -- take a look at smartlock, for example) are even worse. It's not a particularly big deal, since this is sort of the point of shorthand. It makes strategies that would be unviable otherwise due to sheer length viable. :) –  Lymia Aluysia Sep 8 at 20:50

Mickey V4

For V4 I used the same method as V3, against the updated bots but with more concurrent populations (30 not 10).

Developed against all 60 bots, including BurlyBalderV3 and LethalLoke (but excluding 2botsonecup which is uncompilable by my strict implementation).

I discovered wildly different bots and success rates if I started with different random seeds. So I decided to separate these different starting points into populations and let them occasionally cross-pollinate.

In 1400 generations, 30 concurrently evolving populations created this program:


I calculate the win rate of this bot to be 90.0% against the current crop. (1135/125/0 tape lengths won/lost/drawn).

V3 info

Calculated win rate of 89.2% (1124/62/74 tape lengths won/lost/drawn).

V2 info

The generation program now has analysis to tell which part of the end of the program is unused and trims it before generating the next generations from it. This means that random mutations happen in used parts of the program only and so evolution is faster.

72% against the current crop at the time. (892/204/143 tape lengths won/lost/drawn).

V1 info

31500 generations, only 12 bots faced. 65% (165/80/7 tape lengths won/lost/drawn). I use all 21 tape lengths.

Potential bots are ranked by:

  • most wins then;
  • most draws then;
  • quickest time drawn then;
  • quickest time won


  • Mickey is named after my cat and;
  • To paraphrase T.S. Elliot: The Naming of Cats is a difficult matter, It isn't just one of your brainfuck bots
  • My java bf vm and genetic algorithm is on github.
  • The vm is capable of running a complete tournament in under 4 seconds on a single core of an i7 (caution - results are not always identical to the tournaments engine).
share|improve this answer
Wouldn't it be better to use all 60 bots? –  Sylwester Aug 31 at 23:51
@Sylwester Maybe, I mainly didn't because it's so slow. Took two hours to do this. Also though it evolved slower the more bots it had to cope with. I figured if it beats the top guys, it will do well. I've not been able to run the actual tournament to confirm, python troubles. So thought I'd just post it and see... –  weston Sep 1 at 7:40
@weston Maybe we could help you with your python troubles? –  Cipher Sep 1 at 8:29
@Cipher thanks, I opened an issue on the github github.com/redevined/brainfuck/issues/2 –  weston Sep 1 at 8:48
@Sylwester I use most of the bots now as my generator is much faster and multithreaded. –  weston Sep 2 at 21:58

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.