996
|
1 FukYorBrane is a cross between Brainfuck and Corewar. Basically, you have two FYB programs
|
|
2 running simultaneusly. The data buffer for each of them is the opponent's program buffer. The
|
|
3 objective is to cause the opponent's program to quit with a "bomb." The changes you make to the
|
|
4 opponent's program buffer must be committed (see !) before they will have an effect.
|
|
5 Comments can be put into the program either the same way as BF (anything that isn't a command is a
|
|
6 comment) and/or by surrounding comments in (). The advantage of () is that the comments can
|
|
7 contain '.', ',', ':', ';', etc.
|
|
8 The program buffers will always be of the same length - if one is shorter, it will be padded at the
|
|
9 end with nops (see %). When a program pointer reaches the end of a program, it simply goes back to
|
|
10 the beginning.
|
|
11 There are 17 commands in FukYorBrane:
|
|
12
|
|
13 COMMAND | VALUE | EFFECT
|
|
14 --------+-------+--------
|
|
15 % | 0 | nop, does nothing
|
|
16 | |
|
|
17 + | 1 | increments the current value in the opponent's program buffer, looping if
|
|
18 | | necessary
|
|
19 | |
|
|
20 < | 2 | moves the data pointer to the left (NOT looping, if it goes below 0, it stays at
|
|
21 | | 0)
|
|
22 | |
|
|
23 > | 3 | moves the data pointer to the right (looping if necessary)
|
|
24 | |
|
|
25 , | 4 | reserved but has no effect
|
|
26 | |
|
|
27 . | 5 | reserved but has no effect
|
|
28 | |
|
|
29 ! | 6 | commit the current value to the opponent's active program buffer
|
|
30 | |
|
|
31 ? | 7 | uncommit the current value (replace the current value with the value in the
|
|
32 | | original program)
|
|
33 | |
|
|
34 [ | 8 | start a brainfuck-style loop (loop while the value at the current location in the
|
|
35 | | opponent's program buffer is not nop)
|
|
36 | |
|
|
37 ] | 9 | end of a [ loop
|
|
38 | |
|
|
39 { | 10 | loop while the opponent does not have a program pointer at the current location
|
|
40 | |
|
|
41 } | 11 | end of a } loop
|
|
42 | |
|
|
43 : | 12 | start a thread. The parent thread will skip over the matching ;, the child will
|
|
44 | | loop between this and the matching ;
|
|
45 | | NOTE: any given : will only fork once, then it's spent
|
|
46 | |
|
|
47 ; | 13 | end of a ; loop
|
|
48 | |
|
|
49 N/A | 14 | BOMB! This is an important one. If ANY program pointer (even if you have
|
|
50 | | several from threading) hits this, you lose!
|
|
51 | | NOTE: You cannot write a bomb in your own program, so it doesn't have a character.
|
|
52 | |
|
|
53 * | 15 | exit - end the current thread. If you're not in the topmost thread, you can only
|
|
54 | | exit at the very end of a thread: :......*;
|
|
55 | | NOTE: If the current thread is the only thread, you lose!
|
|
56 | |
|
|
57 @ | 16 | defect: instead of editing the opponent's program buffer, this thread will edit
|
|
58 | | your own. You can later defect back.
|
|
59 | | NOTE: If you commit a defect, YOU DEFECT
|
|
60 | | (this is to try to prevent pure manglers from being effective)
|
|
61
|
|
62
|
|
63 ---------------
|
|
64 SIMPLE STRATEGY
|
|
65 ---------------
|
|
66 One of the most simple FukYorBrane programs is:
|
|
67 {>}[+]+++++++++++++!
|
|
68 This very simply:
|
|
69 {>} | tries to find the opponent's program pointer
|
|
70 [+] | blanks the value where you found it (as in BrainFuck, but looping values)
|
|
71 +++++++++++++! | sets the value there to 14 (bomb)
|
|
72
|
|
73 This simple program isn't very effective, as it has tight loops. Tight loops are generally best
|
|
74 avoided, because of how bombs are usually placed. If the enemy finds you and places a bomb, and
|
|
75 you're in a tight loop, you'll hit the bomb long before you can do something about the enemy.
|
|
76
|
|
77
|
|
78 A slightly more complex FukYorBrane program:
|
|
79 :{>}[+[+[+[+[+[+[+[+[+[+[+[+[+[+[+]]]]]]]]]]]]]]]+++++++++++++!>%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
80 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%;
|
|
81 :@[>+++]!;*
|
|
82
|
|
83 Let's break this down:
|
|
84 >} | This is the same as before (and still a tight
|
|
85 | loop, which is bad).
|
|
86 [+[+[+[+[+[+[+[+[+[+[+[+[+[+[+]]]]]]]]]]]]]]] | This is one way to zero a value without a tight
|
|
87 | loop
|
|
88 +++++++++++++! | set the bomb
|
|
89 > | since we already have a bomb here, go on
|
|
90 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%... | by setting a lot of nops, we make the :; loop
|
|
91 | less tight
|
|
92 :@[>+++]!; | this is a simple bomb finding algorithm:
|
|
93 | it defects,
|
|
94 | then loops,
|
|
95 | nop'ing any bombs
|
|
96 | and committing if they were a bomb
|
|
97
|
|
98 Because you can defect, you can have a self-replicating program. But that's up to future hackers
|
|
99 to produce ;)
|
|
100
|
|
101 --------------
|
|
102 PROGRAM STYLES
|
|
103 --------------
|
|
104 Gregor has only written two major styles of programs:
|
|
105 Manglers
|
|
106 and
|
|
107 Seekers.
|
|
108
|
|
109 Of Manglers, there are several subtypes:
|
|
110 Pure mangler: All this does is destroy code with no attempt at any logic. Very quick. It's also
|
|
111 the shortest code: +!>
|
|
112 Logic mangler: Usually look for loops, disable loop beginnings or ends. That way, program
|
|
113 pointers fly through the entire program, so you can bomb anywhere.
|
|
114
|
|
115 Seekers basically seek out program pointers ({>}), then try to bomb where the program pointer was,
|
|
116 since the pointer is likely to come back to the same point. Easily catchable with a false
|
|
117 thread.
|
|
118
|
|
119 -------
|
|
120 LOOPING
|
|
121 -------
|
|
122 It is worth mentioning how many ticks different loop styles take.
|
|
123
|
|
124 If you have a loop of the style [A]B
|
|
125 (where A and B are sections of code)
|
|
126 It will run like so (where every character that isn't A or B is a tick):
|
|
127 [A][A][A][B...
|
|
128
|
|
129 If you have a loop of the style {A}B
|
|
130 It will run like so
|
|
131 {A}{A}{A}{B...
|
|
132
|
|
133 However, if you have a loop of the style A:B;C
|
|
134 It will run like so
|
|
135 A:B;B;B;B;B;B...
|
|
136 C...
|
|
137
|
|
138 Important to note is that while [ and { will take a tick every loop, : will take a tick only on the
|
|
139 first loop.
|
|
140
|
|
141 Where loops are unmatched, any applicable jump will be skipped. That is, in a situation like:
|
|
142 [A[B]
|
|
143 , where the [ before A doesn't have a match, if it hit that [ and decided to jump, it would not.
|
|
144 It would run like this:
|
|
145 [A[B][B][B].....
|
|
146 in either situation.
|
|
147 The situation is similar for ending brackets. This:
|
|
148 [A]B]C
|
|
149 would run like this:
|
|
150 [A][A][A]...B]C
|
|
151
|
|
152 If you produce a : somewhere where one has already existed, it's "spent" status will be maintained.
|
|
153 That is, if one program did this:
|
|
154 :A;B
|
|
155 , and later, the second program turned that into this:
|
|
156 %A;B
|
|
157 , then yet later, the second program turned it back into:
|
|
158 :A;B
|
|
159 , the : before the A would still be spent, and would not fork again. If a : is produced somewhere
|
|
160 where there was not one before, it defaults to unspent.
|