Jump to content
BrainDen.com - Brain Teasers
  • 0


unreality
 Share

Question

VNA 2.0

VNA 2.0 is a game of epic cybernetic warfare - it's easy to learn, but from its simple rules comes a lot of thrilling complexity and hardcore battling. In this game of wits and passionate skill, your job is to design a killer program that can destroy its foes in a virtual environment where only one program can emerge victorious. During the actual battle, you play no part (it's run by my emulator) - it's up to your program! You can only wait for the results as two programs duel it out for control of the VNA...

***

Introduction

***

This is an improvement over an earlier game I made (here on Brainden), called VNA. It's a game that involves a cyber-environment called the VNA (which stands for Virtual Node Array), which is just a list of 200 lines of code. The code is written in VNAC (VNA Code), which I've devised based off of an ancient game known as CoreWars, and tweaked to be better and easier to learn & optimize. For VNA 2.0, I've made some changes to allow accessibility and easy learning for people who have never done an ounce of programming in their life.

In the VNA, each of the 200 lines is called a 'node' (thus the name 'Virtual Node Array'), although I use 'line' and 'node' interchangeably, and each node contains exactly one command and then three parameters (a,b,c) that the command uses as input. The parameters are separated by semicolons.

Most commands do not use all three parameters, so the extra parameters can have any value, it doesn't matter (the default is 0). Some programs may use excess values to store data.

The most basic type of command is BLANK 0;0;0, and the VNA begins with all 200 lines filled with these BLANK commands.

Then two players enter the VNA. Each player submits a program with the aim of destroying the enemy program. The two programs get entered into the VNA at random starting points, overwriting the BLANKs that they are copied over. Each program can be a maximum of 40 nodes long, thus the closest two programs can be is 40 nodes away.

[Note: the programs retain their order. You could have a 20-line program that gets copied onto line, say, 57. Thus your program will replace lines 57 through 76. If the opponent's program was 10 lines and got placed on line 112, their program would occupy lines 112 through 121]

After the programs have been copied into the VNA, the battle begins!

The game progresses in rounds. Each player has a 'pointer', which starts out at the first line of code of the player's program, wherever that may be in the VNA. In each round, player A's pointer runs one line of code (one 'node'), and then player B's pointer runs one node. After a pointer runs a node, it moves itself forward 1 node in preparation for next round [but each round, each pointer only runs ONE node, no exceptions].

[For example, take the previous Note - your program got placed at line 57 and occupied lines 57 through 76. Thus your pointer begins at line 57. Your opponent's program started at line 112, so your opponent's pointer begins at line 112. On the first round, if you go first, your pointer runs line 57. Then your opponent's pointer runs line 112. On the second round, your pointer would run line 58, and your opponent's would run line 113. On the third round, you would run line 59 and your opponent would run line 114. etc. Pointers will always increment by 1 after they are finished executing a command, unless otherwise specified!]

A pointer is destroyed when it executes a BOMB command, and the other player wins!

***

Nodes & Commands

***

So how does VNA Code work? It is very easy to learn! Each node has a simple format:

CMND a;b;c

a command name followed by a space followed by the parameters, which are separated with semicolons.

Each command does a specific action, using the parameters as its input. Here is a list of commands:


COPY a,b copies line a into line b (overriding the current line b)
JUMP a jumps the pointer to line a
BOMB destroys the pointer that ran this node
EDITA a,b a is the line number, b is the new a-value for that node
EDITB a,b a is the line nummber, b is the new b-value for that node
EDITC a,b a is the line number, b is the new c-value for that node
EDITX a,b,c a is the line number, b is the new value, c is 0/1/2 to denote a/b/c to change
BLANK what the original VNA is filled with. You can use BLANK commands too, it's basically a "do-nothing" command
EDITI a,b,c a = line number, b is how much is added to the current value, and c is 0/1/2 to denote a/b/c to change. 'I' stands for increment
SHIFT a,b,c copies line a into line b, then jumps pointer to line c
PCOPY a,b copies only the command part of line a into the command part of line b (stands for "partial copy")
SWAP a,b switches line a & line b (happens immediately)
[/codebox]

Before I go on, let me clarify EDITX and EDITI. The a & b parameters of EDITX are the same as the a & b parameters of EDITA or EDITB or EDITC. That is, the 'a' parameter designates the line number to edit, and the 'b' parameter represents the new value. However EDITX also utilizes the 'c' parameter. The c parameter can be either 0 or 1 or 2. Zero means that it is editing the line's a-param (as per EDITA). 1 means that it's editing the b-param (as per EDITB), and 2 means the c-param (as per EDITC). You wouldn't use EDITX if you knew you would always be editing a specific parameter... you would only use EDITX if the actual parameter you were editing was going to change too.

EDITI is the same thing as EDITX, except that the 'b' parameter is different: instead of representing the NEW value, it represents what is going to be added to the current value [just a shortcut I made because a common use of EDIT is to increment a parameter]

So how do you represent a line number?

The current line is always seen as 'line 0', the next line is 'line 1', the line after that is 'line 2', etc. The line BEFORE the current line is referred to as '-1', the line behind that being '-2', etc. Because of this, there is no absolute definition of line number, and the VNA wraps around as if it were an infinite loop, so line 200 or 400 or -600 is the same thing as line 0 (which is the current line).

For example, say your program is this:

COPY 0;1

when the pointer runs this node, it copies the current line (0) into the next line (1), and looks like this:

COPY 0;1

COPY 0;1

remember that the pointer increments itself each round, so next round it will run the SECOND node, which is also "COPY 0;1", and thus this program is basically an infinitely-repeating program that cannot die and cannot kill anything. After five iterations:

COPY 0;1

COPY 0;1

COPY 0;1

COPY 0;1

COPY 0;1

...etc

[[i]Note: technically, it should be COPY 0;1;0, because even though the c-parameter is not used, it still should be shown[/i]]

***

Parameters & Functions

***

So what can you use for parameters? You already know that you can put numbers in, but usually you want to have a function: a function is something, like add(5,2), that takes in input and produces an output. For example, add(5,2) will add 5 and 2 (5 & 2 are the input) and output the number 7. Functions will always churn out a number as output, and for input, they will accept either numbers or more functions. For example:

add(5,add(3,2))

will add 5 to the addition of 3 and 2, thus the output of that whole thing will be 5+(3+2) or 5+5 = 10

There is no 'official' limit to the number of functions you can have nested within other functions, but at a certain point it may clog up my VNA emulator, and usually there's no need for such uber-nesting :D

So what are the functions? [btw, a fancy name for "output" is "return". For example, add(7,2) returns 9]

[codebox]
a(n) returns the a value of the node at line n
b(n) returns the b value of the node at line n
c(n) returns the c value of the node at line n
add(m,n) returns m+n
sub(m,n) returns m-n
mul(m,n) returns m*n
div(m,n) returns m/n
mod(m,n) returns the remainder of m/n
pow(m,n) returns m^n
log(m,n) returns log (base m) of n
abs(n) returns the absolute value of n
int(n) returns the integer part of n
com(m,n,o,p,q) compares m & n. If they are equal, returns o. If m>n, returns p. If n>m, returns q
equ(m,n,o,p) compares m & n. If they are equal, returns o. Otherwise, returns p
geq(m,n,o,p) compares m & n. If m>n or m=n, return o. Otherwise, p
leq(m,n,o,p) compares m & n. If m<n or m=n, return o. Otherwise, p
nzero(n) if all three parameters of line n are 0, returns 0. Otherwise, returns 1
rand(m,n) returns a random integer from m to n, including m&n. 'n' must be greater than 'm'

As you can see, functions are pretty useful for evaluating data and deciding what to do.

***

That's It!

***

That's all you need to know! Simple, right? You may not think so yet, but it actually is. With the above stuff, you can make some awesome programs. Take this, for example:

COPY 3;40;0

EDITI -1;3;1

JUMP -2;0;0

BOMB 0;0;0

Believe it or not, this simple thing is actually a powerful program. Let's analyze what it does, line by line:

COPY 3;40;0

Okay, 'COPY a,b' copies line a into line b, overriding the current line b.

a=3

b=40

So line 3 is the line three lines forward from 'COPY'. This is the 'BOMB' line! The 40 means it copies the BOMB line into a node 40 nodes forward from the current line. Note that 40 is the minimum distance the two programs can be apart from each other, and thus the first possible space that the opponent's program could be on.

After running the COPY line, the new VNA state would be this:

COPY 3;40;0

EDITI -1;3;1

JUMP -2;0;0

BOMB 0;0;0

...

... (36ish BLANK commands would be here, I just don't have the space ;D)

...

BOMB 0;0;0

Simple so far! Next, the EDITI command. It edits line -1, which would be the COPY line, and it edits the b-parameter of the COPY line because the c-parameter of the EDITI line is 1, which corresponds with 'b'. So 3 means that the b-parameter is incremented by 3. Thus, the new copy line looks like this:

COPY 3;43;0

in other words, the EDITI command added 3 to the COPY line's b-parameter, turning 40 into 43

The next line is JUMP -2, which sends the pointer back 2 lines, to the COPY line. That means the next line that the pointer will run is the COPY line... the COPY line which was modified. Now the COPY line will copy the BOMB 43 spaces forward, instead of 40 like last time. Each iteration of the program will churn out another BOMB another 3 spaces forward!

As you can see, the BOMB command is part in the program but is never actually run by the program (unless it gets corrupted by the enemy prpogram), just copied across the VNA in an attempt to destroy the opponent

This type of program is called a "Bomber", and is one of the simplest possible forms of Bombers. Other Bombers may have defense mechanisms built in (to stop if it gets close to bombing itself), or better methods for efficiency, etc

So I'm going to start out VNA 2.0 with an "Opening Day Tournament", in which I need 8 battle programs submitted to me to compete in a bracketed tournament format.

If you have any questions about VNA or VNA Code, feel free to PM me!

I call this one 'the Hopper':

COPY 0;add(a(0),c(0));170

EDITI -1;1;0

JUMP com(a(-2),3,168,168,-2);0;0

It works by copying all three lines of itself 170 spaces forward, then when that is complete, jumping itself to the new copy 170 nodes forward and doing it all over again. The Hopper is very versatile and extremely hard to kill. After just 9 rounds it has sent itself to the next location. However the Hopper has its setbacks, and the major one is that it relies on the opponent bombing themselves... the only way that a Hopper can actively kill the enemy is if it (by luck) overwrites key parts of the enemy's program that causes it to completely mess up and possibly hit a BOMB

This is an even simpler form of the Hopper:

SHIFT 0;170;170

It does what the Hopper does with one third the nodes and one ninth of the total rounds it takes! This Hyper-Hopper is extremely hard to kill (a BOMB has to nail right on top of its new location right before it runs it and before it goes elsewhere), but of course it has no ability to kill the opponent, and could only win if the opponent tears themselves apart.

This one is a bit more complex, but more efficient than a simple bomber. It searches for nodes that have nonzero parameters (and thus probably at or near the enemy's program) and then bombs the area. Meanwhile it takes advantage of the new SHIFT command I added to splatter bombs around at the same time as jumping with JUMP

SHIFT 3;40;equ(nzero(b(0)),0,1,4)

EDITI -1;5;1

JUMP -2;0;0

BOMB 0;0;0

EDITI -4;1;1

COPY -2;b(-5);0

JUMP -2;0;0

This program can be improved upon, of course. It has no defense mechanisms that check to see if it's getting close to bombing itself and jump it to a next step which does something different. It also becomes an inefficient 1-node-at-a-time bomber in the last three lines. You can help yourself learn about VNA by adding onto this program and making it better

Spoiler for my best on the above:

Much more efficient, 5 lines not 7 and runs way less of them, going through iterations faster and with more accuracy. Also reduces function lag by evaluating nzero and taking out the equ around nzero (see later when I explain nzero). Basically the big thing in the c-parameter of the SHIFT command evaluates the line denoted by its own b-parameter, checks if all of its parameters are zero. If so, back one. If not, up 2

The Hunter

EDITI 1;5;1

SHIFT 1;40;equ(a(b(0))+b(b(0))+c(b(0)),0,equ(a(b(0)),b(b(0)),equ(c(b(0)),0,-1,2),2),2)

BOMB 0;0;0

EDITI -2;1;1

SHIFT -2;sub(b(-3),3);-1

I call this one 'the Liberator'. It's a devastatingly simple and powerful program that takes advantage of the new SHIFT command and random function:

SHIFT 1;rand(40,160);0

BOMB 0;0;0

The rest I've made for VNA 2.0 so far are well-thought out warrior programs that I would use in a battle and not post here :D

If you understand how it all works, and can decipher programs... but have no idea where to start in making your own, then...

Make sure you have a clear goal on what you want your program to do (this is probably the most important step). Once you have a definite idea on how you want it to work, start to think about what commands you could use to make that happen in the best way...

If you want to know about things you cannot do that cause infinite loops,

COMMANDNAME b(0);a(0);7

Look at this. It's a-param references it's b-param, which references it's a-param!! I call this a 'paradox node'

COMMANDNAME a(1);2;25

COMMANDNAME a(-1);36;0

Same thing. Or it could be a-to-b like this:

COMMANDNAME b(1);2;25

COMMANDNAME 3;a(-1);0

or you could have three nodes that work this way, or four, or five! :o The possibilities are endless! The paradox nodes don't have to be next to each other either, of course

~~

The second kind is this:

COMMANDNAME a(0);8;15

You can NEVER have a(0) in the 'a' parameter, b(0) in the 'b' parameter, or c(0) in the 'c' parameter! (Or anything that equates to 0)

Note that nzero(n) = equ(a(n)+b(n)+c(n),0,equ(a(n),b(n),equ(c(n),0,AZ,NZ),NZ),NZ)

Where AZ is the result if line n has all-zero parameters, and NZ is the result if line n has at least one nonzero parameter. I didn't actually program nzero as a function in my emulator, I just added that to help you out - if I see a use of nzero, I'll replace it with the above longer version and use 0 for AZ and 1 for NZ... but the longer version is better for you to use raw because you can make the AZ and NZ anything you want that suits the specific purpose

The modulus is your friend

mod(a,b) = a % b, or "a modulo b" or "the remainder of a/b"

The function mod(x,3) will always produce a number that is either 0, 1 or 2, regardless of the value of x. A multiple of three (such as 33) will produce 0. One over a multiple of three (such as 34) will produce 1. Two over a multiple three (such as 35) will produce 2. For example:

mod(17,3) = 2

This is extremely useful in the 'c' parameter for the EDITX or EDITI commands, where a 0/1/2 value is required to specify a/b/c to edit. Using the mod function in combination with other values will allow you to manipulate that in a more complex/efficient program that uses a single EDITX or EDITI to do all of its editing

com is even MORE your friend!

The function I use most is probably com, though in VNA 2.0 with the addition of com's sister functions (equ, geq and leq) you can make your coms look simpler. Com just has more options, but when you know how you want to compare two things, using one of the other three will make your program less cluttered by removing the fifth input value (otherwise no actual advantage).

The command I almost always pair 'com' with is JUMP (or also the c-value of SHIFT) to tell it where to jump to in the program. Thus my JUMP commands act as switching stations that take in info, analyze with 'com' (or its sister functions) and then jump to the desired location

Efficiency is key

When you can use one line to do multiple things, do it! Each round, only one node is ran by your pointer, so you want to be as efficient as possible and make your actions take up the least amount of time to complete. For example, the SHIFT command I added in 2.0 allows for simultaneous copying and then jumping, with one node. So if you ever have a situation where you need to copy and then jump, SHIFT is the command for you.

Another tip for efficiency is placing any BOMB command your program might have at the end (or in middle if you're guaranteed to not run into it) of the code, and then reference it from earlier.

Integers and decimals

int(n) gives the integer part of n, for example int(5.78) = 5, though if you wanted just the .78 part, just do sub(n,int(n))

Plan for eventualities!

Make sure you have a backup plan if your program's initial goal fails! If you are a Bomber, when you jump back to re-bomb (if yours works like that), use a com with the JUMP to make sure that the bombs aren't getting too close to home. Creating a program that is capable of doing multiple tasks and planning for various types of enemy programs is a good idea :D Especially in the Tournament Game I'm going to start, where your program must be able to vanquish different kinds of foes

Editing input values

You may have noticed there are no commands for editing input values of functions... that's because it's just not feasible to do without unnecessary complications and complexities.

Instead, there is an efficient, elegant and much easier solution... if you have an input value of a function (no matter how nested it is within other functions, doesn't matter) that you know you want to change, just use in place of it one of these functions: a(n), b(n) or c(n), pointing to an unused parameter of a line. For example, if the previous line is a JUMP command, which doesn't use its b or c parameters, you could use b(-1) or c(-1) to reference one of those unused parameters of the JUMP command, which is where you would store the value which you could then easily change with an edit command.

I also do this when I want to increment, say two different values, by the same amount. I only use 1 round to increment ONE of those values, and have the other value piggyback off of the first and reference it. For example, if two values start at 0 and 7, and every xth round I want to increment them both by 1, I just increment the first one, and have the 7 instead be add(7,v) where v is the reference to the first value (such as a(3) or something similar). This saves a lot of efficiency!! :D

The random function...

rand(m,n) is special in that given the same two input values, the output can (and usually will) differ. Every time rand is evaluated by the VNA, it will return a different value. So when is it evaluated?

* when the node which it is a part of is ran by any pointer

* when a(n), b(n) or c(n) is used to reference the parameter [a, b or c] in which the 'rand' is used

* when EDITI is used to increment the parameter that the 'rand' is part of. EDITI just uses a shortcut of add(x,i) where x is the current value and i is the amount to increment by. Thus in this case, when an operation is performed on rand (such as adding to it, subtracting, etc), it fixes the value, because a(n) or b(n) or c(n) evaluate the current value of the whole parameter (including a random output if a 'rand' is there), and thus if you add something to that, it creates a fixed number, and if you plug that fixed number back into the parameter using EDIT, it is just a number now

** the same is true of all functions. For example, you could have a nested function system that continually evaluates the line 80 in front and adds all three of its parameters together [something like add(a(80),add(b(80),c(80))) ...], but when you use a(n), b(n) or c(n) on the parameter that contains that function, it evaluates it for the CURRENT case, into a fixed value - so if you plug that fixed value back into the parameter (after, say, incrementing it or something) it is no longer a function but a fixed number

So keep that in mind when using rand :D

So if you're interested, feel free to PM me about the game and submit your program today ;D I'm hoping to get 8 people for the Opening Day Tournament :P

Link to comment
Share on other sites

  • Answers 112
  • Created
  • Last Reply

Top Posters For This Question

Top Posters For This Question

Posted Images

Recommended Posts

  • 0
Prime: well I ran the version you gave me for the tournament. If you've fixed it since then, I obviously have no idea if it works or not :) I can run your newer version if you want (post it again)

FOTH: if you're running Prime's newer versions, he's probably fixed it, but if you ran the same version mine did, it should have gotten stuck fairly quickly (first few rounds). If not, no offense, but something is wrong with your Excel emulator :D My emulator runs all commands & functions perfectly as they should be, I've extensively tested it.

Firstly, please don't dismiss our concerns so lightly and with what sounds like distain Secondly, whilst I appreciate the this is your topic/game, we have all made the effort to participate and deserve the chance to discuss what went wrong. As far as Prime and I are concerned his program should do what it is intended to (btw, i have been using the version you posted in your results). It is therefore natural for us to question your emulator as we haven't seen it! Alternatively, we may have misunderstood how the VNA works and your emulator is operating perfeclly, as you say. ;)

and, again, you can't have any c(0) in a c-parameter. If you have something that COULD evaluate to it, it's a risk. If it's never supposed to happen, why not make it something other than 0? Because 0 just causes an infinite loop that jams the emulator. It was in the OP of this topic but I'll say it again: No a(0) in the a-param, b(0) in the b-param, or c(0) in the c-param! There are other logical impossibilities, all detailed in the spoiler near the bottom of the OP. If an emulator encounters such a logical paradox it should end the game immediately and report the problem. Or just leave it, because nobody should have anything like that in their program

Of course such a circular reference is not preferable, but my point is that they can occur safely if they are managed. I'll use the example which raised the issue for me.

A Line has a c-value of equ(b(-1),0,1,c(b(-1)))

b(-1) has a function which is regularly repeated so is put here for easy reference. Actually, it returns the next target for my bomb. And this line checks to see what the c value of that target is before and after bombing. But what if b(-1) gets overwritten as 0 by the opposition or returns 0 for some reason? The equ protects the line from needing to evaluate a c(0), but as i said, excel currently wants to evaluate every argument even if it's not going to be needed. And I know there are alternative ways of achieving the same thing but the problem may be less obvious and circling several more nodes to indirectly come back to equ(0,0,1,c(0).

oh and the VNA is initially filled with BLANK 0;0;0, not BOMB 1;1;1. I considered doing all bombs, but decided that BLANKs were better

I know. But i've been running alternatives for fun! Filling it with bombs and non-zero arguments makes a good alternative starting situation.

Link to comment
Share on other sites

  • 0

I appreciate your concern and I wasn't "dismissing you with dismay", sorry if it seemed that way :o I'll run it again if you want, but the result was the same every time I ran through it, regardless of the opponent. I'll test it and then run it through manually with just myself. If there happens to be an error with my emulator, then I'm deeply sorry... we'll see though.

For the infinite loop thing, I didn't realize that 0 wasn't part of the com at the end, but rather a possibility of the previous line. In that case, I don't know what to tell you, sorry. Does your emulator do this even when the infinite loop would never occur? If I understand correctly, it's checking every possible route, and is seeing possibility of error? Is 0 an in-built possibility of the previous line or is it just if it gets overwritten?

Link to comment
Share on other sites

  • 0

I did some investigating. My logical analysis of Fish3 followed your guys' convictions, so I did some testing with my emulator and started looking into how it could mistranslate the clear logical command. After thinking about it (and mostly staring at it blankly and rereading :D) I made a test program and tried it:

SHIFT 100;105;1

JUMP c(-1);0;0

JUMP b(a(-1));0;0

BLANK 0;7;0

as I suspected, it sat there on line 3, when it instead should have jumped 7. Rather, it seemed to fail bigtime and just repeat line 3 over and over again.

I can't believe this... I'm so sorry... when I was first making the emulator, I tested function nesting and everything appeared to work fine. I may have changed something since then, or the design doesnt loop right to process potentially infinite a/b/c nesting, but something is wrong. I feel like an idiot. I am an idiot. I was being all confident that my emulator was fine when of course it wasn't, the code is complex enough to mean there's bound to be bugs, gah I should've known that!!! Gahhhhh.... I'm clearly not fit to be VNA host ;D One of you guys should take over, you would do a better job. I like working on the abstract of inventing the language and making programs, but clearly one of you guys would be a better host for running games, tournaments, etc. I'll happily just play from now on :) I'll be trying to fix and debug the emulator in the meantime. Oddly, the only times this problem has been encountered, ever, in VNA and 2.0, has been with your two programs [possibly just Prime's program, I dont know about FOTH's or why it froze] because no other program has ever gone into that kind of loop. This is really strange, because I would an expect an a/b/c nesting problem to be universally apparent. Luckily this means that the damage was contained, but it also means it'll be a b*tch to debug. Wish me luck ;)

So, yeah, sorry... I feel so stupid right now. I'm sure Prime or FOTH will make a much better game-runner than me :D Again, sorry. Wow. ergh

Link to comment
Share on other sites

  • 0
...

Of course such a circular reference is not preferable, but my point is that they can occur safely if they are managed. I'll use the example which raised the issue for me.

A Line has a c-value of equ(b(-1),0,1,c(b(-1)))

b(-1) has a function which is regularly repeated so is put here for easy reference. Actually, it returns the next target for my bomb. And this line checks to see what the c value of that target is before and after bombing. But what if b(-1) gets overwritten as 0 by the opposition or returns 0 for some reason? The equ protects the line from needing to evaluate a c(0), but as i said, excel currently wants to evaluate every argument even if it's not going to be needed. And I know there are alternative ways of achieving the same thing but the problem may be less obvious and circling several more nodes to indirectly come back to equ(0,0,1,c(0).

...

I don't think Excel could be blamed for not being able to handle the statement as above. It is up to your implementation of the "equ" function. Traditionally, interpreters have a recursive structure themselves, resolving references as they go. Your emulator resolves the arguments for the "equ" before it calls it:

Public Function equ(a As Double, b As Double, c As Double, d As Double) As Double

If a = b Then equ = c Else equ = d

End Function

To handle an equ statement as that, the implementation of the equ function could be something like:

Public Function equ(equ_parms As String) As Double

Dim a, b, c, d As String

a = parm(1, eq_parms)

b = parm(2, eq_parms)

c = parm(3, eq_parms)

d = parm(4, eq_parms)

If resolve(a) = resolve(b) Then equ = resolve( c) Else equ = resolve(d)

End Function

Where "resolve()" is another function, which resolves the reference, and "parm()" is a function which separates equ's arguments delimited by commas.

Edited by Prime
Link to comment
Share on other sites

  • 0
I did some investigating. My logical analysis of Fish3 followed your guys' convictions, so I did some testing with my emulator and started looking into how it could mistranslate the clear logical command. After thinking about it (and mostly staring at it blankly and rereading :D) I made a test program and tried it:

SHIFT 100;105;1

JUMP c(-1);0;0

JUMP b(a(-1));0;0

BLANK 0;7;0

as I suspected, it sat there on line 3, when it instead should have jumped 7. Rather, it seemed to fail bigtime and just repeat line 3 over and over again.

I can't believe this... I'm so sorry... when I was first making the emulator, I tested function nesting and everything appeared to work fine. I may have changed something since then, or the design doesnt loop right to process potentially infinite a/b/c nesting, but something is wrong. I feel like an idiot. I am an idiot. I was being all confident that my emulator was fine when of course it wasn't, the code is complex enough to mean there's bound to be bugs, gah I should've known that!!! Gahhhhh.... I'm clearly not fit to be VNA host ;D One of you guys should take over, you would do a better job. I like working on the abstract of inventing the language and making programs, but clearly one of you guys would be a better host for running games, tournaments, etc. I'll happily just play from now on :) I'll be trying to fix and debug the emulator in the meantime. Oddly, the only times this problem has been encountered, ever, in VNA and 2.0, has been with your two programs [possibly just Prime's program, I dont know about FOTH's or why it froze] because no other program has ever gone into that kind of loop. This is really strange, because I would an expect an a/b/c nesting problem to be universally apparent. Luckily this means that the damage was contained, but it also means it'll be a b*tch to debug. Wish me luck ;)

So, yeah, sorry... I feel so stupid right now. I'm sure Prime or FOTH will make a much better game-runner than me :D Again, sorry. Wow. ergh

Woah! I wasn't suggesting a bad host! Quite the contrary: you are a great host, and noone else would have made the effort to run through all those matches! As for your emulator error, I imagine it is something to do with the relativeness of the functions. In that program, it should reduce b(a(-1)) down to b(c(-1 relative to previous line)). The only way I found to do this in my emulator was to recalculate the entire array every time, and is the main reason why some programs are prone to gettin circular references - line A refers to line B, refers to line C which refers to line A.

I'd like to help find the bug in your emulator - please don't just throw all your hard work away! This is still your game, but we are part of it! And do we know this is definitely why Prime's program failed? I know that mine probably wouldn't have worked anyway - there were too many other bugs in it!

edit: Maybe try this program and see if it jumps 4

SHIFT 100;105;1

JUMP c(-1);0;2

JUMP b(a(-1));0;0

BLANK 0;7;0

BLANK 0;4;0

Edited by foolonthehill
Link to comment
Share on other sites

  • 0
I don't think Excel could be blamed for not being able to handle the statement as above. It is up to your implementation of the "equ" function. Traditionally, interpreters have a recursive structure themselves, resolving references as they go. Your emulator resolves the arguments for the "equ" before it calls it:

Public Function equ(a As Double, b As Double, c As Double, d As Double) As Double

If a = b Then equ = c Else equ = d

End Function

To handle an equ statement as that, the implementation of the equ function could be something like:

Public Function equ(equ_parms As String) As Double

Dim a, b, c, d As String

a = parm(1, eq_parms)

b = parm(2, eq_parms)

c = parm(3, eq_parms)

d = parm(4, eq_parms)

If resolve(a) = resolve(b) Then equ = resolve( c) Else equ = resolve(d)

End Function

Where "resolve()" is another function, which resolves the reference, and "parm()" is a function which separates equ's arguments delimited by commas.

I like your implementation but it's the parm function which takes a bit more effort I think. I have just been relying on Excel's own parser rather than trying to write my own, with an implementation like you suggest. The alternative is to parse it into an 'if' function, because 'if' only executes the relevant part in Excel. The biggest problem with excel is the limit to nesting levels, especially with all of the mul and add functions. So maybe I will write my own parser.....

Link to comment
Share on other sites

  • 0
I did some investigating. My logical analysis of Fish3 followed your guys' convictions, so I did some testing with my emulator and started looking into how it could mistranslate the clear logical command. After thinking about it (and mostly staring at it blankly and rereading :D) I made a test program and tried it:

SHIFT 100;105;1

JUMP c(-1);0;0

JUMP b(a(-1));0;0

BLANK 0;7;0

as I suspected, it sat there on line 3, when it instead should have jumped 7. Rather, it seemed to fail bigtime and just repeat line 3 over and over again.

I can't believe this...

Don't beat yourself up too hard. Such things are in the nature of computer programming.

My SHIFT statement has less levels of indirection than your test case. It simply refers to b(-2), which, in turn, has a simple arithmetic expression in it. Maybe, there is something wrong specifically with the "b" argument resolving.

I ran few matches in FOTH's emulator and was gratified to see that the "repair" mode saved Fish3 on several occasions. Even twice in one of the matches. It beat Awesome 3 times out of 4. However, Flawless beats Fish3 consistently. Fish3 does not do well against a program that moves around, it has several serious weaknesses. E.g. an opponent could hide inside Fish3's 40-node body and be forever safe. I am going to try my Fish2 version, which is also a hopper.

When I tried to load Pinguin Bomber also included with FOTH's emulator, the emulator crashed on "Reset Array" button press. There appears to be an invalid/unresolved reference in the statement:

.Names("prog_" & .Names("Player2").RefersToRange.Value).RefersToRange.Copy

in the CommandButton2_Click() Sub.

Edited by Prime
Link to comment
Share on other sites

  • 0
I ran few matches in FOTH's emulator and was gratified to see that the "repair" mode saved Fish3 on several occasions. Even twice in one of the matches. It beat Awesome 3 times out of 4. However, Flawless beats Fish3 consistently. Fish3 does not do well against a program that moves around, it has several serious weaknesses. E.g. an opponent could hide inside Fish3's 40-node body and be forever safe. I am going to try my Fish2 version, which is also a hopper.

I have made a couple of changes to Flawless now that I have the emulator - I expect you would have beaten my original version. Previously it used to bomb near itself, but I realised there was no point in doing so, so now it bombs a totally different part of the array.

When I tried to load Pinguin Bomber also included with FOTH's emulator, the emulator crashed on "Reset Array" button press. There appears to be an invalid/unresolved reference in the statement:

.Names("prog_" & .Names("Player2").RefersToRange.Value).RefersToRange.Copy

in the CommandButton2_Click() Sub.

The problem is that it can't find the "Penguin Bomber" Program. To get Penguin Bomber to load properly I named it "Penguin", so type that at Program 1 or 2. It uses a named range to locate each of the programs, so the Flawless program is at "prog_Flawless". Penguin Bomber is at "prog_Penguin" and you can add your own using Insert/Name/Define... or using the drop-down box on the left of the formula bar. I'll put the rest in later.

It looks like there is certainly some error handling to be done....VBA is rubbish at telling you about errors!

edit: oh, and it appears to run much quicker if you move focus away from the Excel window.

Edited by foolonthehill
Link to comment
Share on other sites

  • 0

thanks but I can't trust my emulator until I'm sure it's working... I think I'm going to rewrite it, in a different language maybe :D I downloaded your excel emulator, it looks cool, but I'm an excel newb and can't make heads or tail of it... I figured out that I have to ctrl-click (rt-click on a windows then?) to use the buttons but I have no idea why there are two game columns or how to enlarge them or input a new program or anything

Just curious, have you checked the battles between the programs that I DID run for the tournament (ie, with the programs of me and frost and mekal and DMS)? I think those should check out, they worked just as they should

FOTH: thanks for helping with the debug, I'll look at the issue more closely later :)

Link to comment
Share on other sites

  • 0

As soon as I looked at the code, I saw what was wrong immediately - I just had to type in a couple of characters and that test program worked perfectly :D I'll go ahead and test Prime's again now

what was wrong was that, my function evaluator function, called ivec, at first only had one parameter, the string to parse. I had forgotten that a line was also needed as input, so I added that partway in. Well, the a/b/c function code calls the ivec function again with the new processed value from the other line, but I had forgotten to put in the second parameter, which would then be the line number for the line denoted within the a/b/c function. This may make no sense to you but it's okay because it makes 100% sense to me :) I know now why it wasn't working before and why it is now

So I'll test Prime's now

update: just tested Prime's, and it works perfectly ;D Whoo. I'll test my emulator a little bit more, but now I'm pretty sure it has the capacity for infinite crazy functions with crazy combos of a/b/c and stuff

FOTH: if you want to know how it works without rendering the whole array, the ivec function [i made the name for my original emulator of VNA 1, which called parameters "input vectors"] is given the parameter string of the line as input, as well as the current line. It runs a loop on the parameter string, stopping the loop and returning if it detects that it has just a number, and each time finds the innermost function by running through the characters, keeping track of the most recent "(" until it hits a closing ")", then counts backwards, taking the stuff between the parantheses as 'funcinput' and the text before the left "(" and after a comma or another "(" as 'funcname'. Then it runs a switch on 'funcname' to give different code for each function, which is how it knows how many commas to look for in 'funcinput' and what to do with the numbers. If the funcname is a/b/c, it uses 'funcinput' as an addition onto the current line running the function and takes the designated line and dissects it for the a/b/c parameter. Then it runs the ivec function (while still inside the first ivec function) on this parameter text and the modified line, ie, the line that the parameter text is from

This allows for infinite a/b/c nesting

The bug that it was having was that, when I called the ivec function again, I forgot the second parameter, the line designated by the a/b/c function. I'm not sure how it even worked before without having that crucial second parameter, but it's fixed now :)

Edited by unreality
Link to comment
Share on other sites

  • 0

I definitely intend to - tomorrow probably. The Awesome is a very good bomber, fast and efficient, but Fish3 may have a better bombing strategy (and clearly is designed like a freaking bomb shelter to account for enemy invasions), we'll see :) I trust Prime's results that his beats mine 75% of the time but I want to see the games for myself ;D

Also I have begun working on a new program

Oh and if anyone wants a detailed schematic on how the Awesome works, just PM me or ask her... it took me a while to figure out its central concept, which is immediately obvious after you see it, it's one of those dumb "aha" things, at least for me :P

Kind of like when, about a week ago, when I was planning the VNA Riddles, I was coming up with the most efficient copy-eraser program I could. My first one consisted of two lines, then I saw that it could be one, over 2 rounds - it was another "aha" moment, because this simple VNA language that I made hides some ghosts in the machine that I never expected ;D

Speaking of that, that's my next program's name:

"Ghost in the Machine", for possibly a different reason, maybe. It's still in the first stages of thoughts in my head ;D

Link to comment
Share on other sites

  • 0

:o Cool idea! Absolutely amazing! A few things that could be improved though...

  • The VNA language isn't very appealing to us non-programmers (it's hard to understand) - our fault, not yours (probably little anyone can do about it anyway)
  • I've had to scroll through nine pages to find a downloadable emulator for VNA (please include it in your first post for anyone else who wants it)
  • The VNA emulator could be improved (add a list of commands, add a loop until win/loose button, make it easier to copy programs into it (or add clearer instructions how to do it right)
  • You should make a website where people can submit these VNA bot things, battle with them, test them, get help with them, etc.

I'm going to try and make a program, but I'll probably epically fail. If I succeed in make anything half-decent, I'll post it here.

P.S. In advance to your next question: Yes, I am a dumb $%£&er. :P

Link to comment
Share on other sites

  • 0

hey Bad-Riddler: First of all, thanks and welcome to BD & VNA :) Second of all, I designed VNA 2.0 specifically to make it easier to swallow for non-programmers. If you think this gets complicated you should see VNA 1 :D The truth is, the game's just not for everyone. I made the OP as engaging as I think the game requires to draw in people, and it did draw in a pretty good number of non-programmers, but you can't dumb everything down and it does take some abstract thinking to understand some of the concepts.

As for the emulator... uhh I never said I would supply an emulator, all "official" are (or were) run by me ;D I could post my own emulator for download but it's written in an archaic language for pre-OSX macs called 'Hypercard' and I doubt anyone here could run the actual application. I would if I could, trust me. No other 2.0 emulator was made until FOTH made his excel version, which was only a page ago or so. On Brainden, OPs only have a 10min edit time.

And I agree about some things with the excel emulator. It is not "the VNA emulator", it's just FOTH's version, I don't understand it much either (cuz I fail at Excel :D), so if you have a problem, take it up with him

And lastly... why would I make a site, especially when the "fanbase" is so small. I don't even know how to make a site, and there would be no reason for the effort :PThis is VNA's site ;D

edit: and cool, good luck making a program and stuff. It's always good to get more players! :)

Edited by unreality
Link to comment
Share on other sites

  • 0

Hmmmm...I wonder if I could make an emulator in Java. It would probably be easier to use. If I have time, I might look into making one, I'm sure a number of people would find that helpful.

Link to comment
Share on other sites

  • 0

In BNF, the syntax of VNA could be defined as following:

Argument ::= Number | Function

Function ::= FunctionName, (, ArgList, )

Arglist ::= Argument, [, Arglist]

Following this model I wrote a parser in VBA in Excel. I include here the following routines:

1). VNA() -- macro used to test parsing. On Excel worksheet put Location numbers from 0 to 199 in column 1 (optional); Command name in column 2 (optional); arguments a, b, and c into columns 3, 4, and 5. Select (bring in focus) an argument you want to parse and run the VNA macro. It should print resulting evaluation for argument "a" in column 7 on the same line, if you selected "b" in column 4, result will be in column 8; for "c" the result of parsing would appear in column 9, and column 10 will have an error message should an error occur.

2). Parse() -- recursive function for parsing arguments.

3). c_arg() -- recursive function for evaluating VNA functions a(x), b(x), and c(x)

4). p_add() -- recursive function for evaluating VNA fucntion add(x,y)

To save space, I do not include other VNA function implementations, since they are very similar to c_arg() and p_add().


Const QSTART = 2 'Excel row number where the first node of the Queue (node array) is
Const NESTMAX = 100 'Maximum allowed nesting levels
Enum Argnames 'Argument name number corresponds to the column number in which it resides
arg_a = 3
arg_b = 4
arg_c = 5
End Enum
Public Sub Vna()
'
' VNA Macro
' Macro Recorded by Prime, Dec 5, 2008
'
Dim in_str As String 'Input string -- the line argument to parse
Dim errmsg As String 'Error message, also serves as an error flag in the program
Dim slen As Integer 'Input string length
Dim sptr As Integer 'Pointer to parse() location in the input string
Dim loc_ptr As Integer 'Line in which parsed argument resides
Dim nest As Integer 'Counter for the nesting level
Dim arg_val As Double 'Return value of the parser
Dim loc_col As Integer 'Column in which parsed argument resides

' Test operation of parse() function by selecting (bringin in focus) the cell with the argument to be parsed in the worksheet,
' and then running this macro.
With ActiveSheet

in_str = ActiveCell.Value
loc_ptr = ActiveCell.Row - QSTART 'Locations run from zero to QSIZE - 1 (0 to 199 in this instance).
loc_col = ActiveCell.Column
in_str = Replace(in_str, " ", "")
slen = Len(in_str)
sptr = 1
errmsg = ""
nest = 0
If slen > 0 Then
arg_val = parse(in_str, sptr, slen, loc_ptr, nest + 1, errmsg)
Else
arg_val = 0
End If
If errmsg = "" And sptr <= slen Then
errmsg = "Invalid argument in line " & str(loc_ptr)
End If
.Cells(loc_ptr + QSTART, loc_col + 4).Value = arg_val
.Cells(loc_ptr + QSTART, arg_c + 5).Value = errmsg

End With
End Sub

'
Function parse(ByRef in_str As String, ByRef sptr As Integer, ByVal slen As Integer, ByVal loc_ptr As Integer, ByVal nest As Integer, ByRef errmsg As String)
Dim i As Integer, num_signs As Integer

If nest > NESTMAX Then
errmsg = "Maximum nesting level exceeded"
Exit Function
End If

If Mid(in_str, sptr, 2) = "a(" Then
sptr = sptr + 2
parse = c_arg(arg_a, in_str, sptr, slen, loc_ptr, nest + 1, errmsg)
Exit Function
End If

If Mid(in_str, sptr, 2) = "b(" Then
sptr = sptr + 2
parse = c_arg(arg_b, in_str, sptr, slen, loc_ptr, nest + 1, errmsg)
Exit Function
End If

If Mid(in_str, sptr, 2) = "c(" Then
sptr = sptr + 2
parse = c_arg(arg_c, in_str, sptr, slen, loc_ptr, nest + 1, errmsg)
Exit Function
End If

If Mid(in_str, sptr, 4) = "add(" Then
sptr = sptr + 4
parse = p_add(in_str, sptr, slen, loc_ptr, nest + 1, errmsg)
Exit Function
End If

If Mid(in_str, sptr, 4) = "sub(" Then
sptr = sptr + 4
parse = p_sub(in_str, sptr, slen, loc_ptr, nest + 1, errmsg)
Exit Function
End If

If Mid(in_str, sptr, 4) = "mul(" Then
sptr = sptr + 4
parse = p_mul(in_str, sptr, slen, loc_ptr, nest + 1, errmsg)
Exit Function
End If

If Mid(in_str, sptr, 4) = "div(" Then
sptr = sptr + 4
parse = p_div(in_str, sptr, slen, loc_ptr, nest + 1, errmsg)
Exit Function
End If

If Mid(in_str, sptr, 4) = "pow(" Then
sptr = sptr + 4
parse = p_pow(in_str, sptr, slen, loc_ptr, nest + 1, errmsg)
Exit Function
End If

If Mid(in_str, sptr, 4) = "mod(" Then
sptr = sptr + 4
parse = p_mod(in_str, sptr, slen, loc_ptr, nest + 1, errmsg)
Exit Function
End If

If Mid(in_str, sptr, 4) = "log(" Then
sptr = sptr + 4
parse = p_log(in_str, sptr, slen, loc_ptr, nest + 1, errmsg)
Exit Function
End If

If Mid(in_str, sptr, 4) = "aabs(" Then
sptr = sptr + 4
parse = p_abs(in_str, sptr, slen, loc_ptr, nest + 1, errmsg)
Exit Function
End If

If Mid(in_str, sptr, 4) = "int(" Then
sptr = sptr + 4
parse = p_int(in_str, sptr, slen, loc_ptr, nest + 1, errmsg)
Exit Function
End If

If Mid(in_str, sptr, 4) = "com(" Then
sptr = sptr + 4
parse = p_com(in_str, sptr, slen, loc_ptr, nest + 1, errmsg)
Exit Function
End If

If Mid(in_str, sptr, 4) = "equ(" Then
sptr = sptr + 4
parse = p_equ(in_str, sptr, slen, loc_ptr, nest + 1, errmsg)
Exit Function
End If

If Mid(in_str, sptr, 4) = "geq(" Then
sptr = sptr + 4
parse = p_geq(in_str, sptr, slen, loc_ptr, nest + 1, errmsg)
Exit Function
End If

If Mid(in_str, sptr, 4) = "leq(" Then
sptr = sptr + 4
parse = p_leq(in_str, sptr, slen, loc_ptr, nest + 1, errmsg)
Exit Function
End If

If Mid(in_str, sptr, 6) = "nzero(" Then
sptr = sptr + 6
parse = p_nzero(in_str, sptr, slen, loc_ptr, nest + 1, errmsg)
Exit Function
End If

' Parse numeric entry
' Val and IsNumeric allow for commas in a number. Here comma is used as a delimiter
' This parser allows numeric argument to end with a period.

i = 0
num_signs = 0
If (Mid(in_str, sptr, 1) Like "[+,-]") Then 'Parse the sign (+ or -) in front of the number, if any
i = 1
num_signs = 1
End If
Do While sptr + i <= slen And ((Mid(in_str, sptr + i, 1)) Like "#") 'Parse integer portion
i = i + 1
Loop
If sptr + i <= slen And Mid(in_str, sptr + i, 1) = "." Then 'Check for decimal point
num_signs = num_signs + 1
i = i + 1
Do While sptr + i <= slen And ((Mid(in_str, sptr + i, 1)) Like "#") 'Parse decimal portion
i = i + 1
Loop
End If
If i - num_signs > 0 Then 'A number must have some digits, not just a sign and a decimal point
parse = Val(Mid(in_str, sptr, i))
sptr = sptr + i
Else
parse = 0
errmsg = "Invalid or missing argument in line " & str(loc_ptr) & " position " & str(sptr)
End If

End Function

'
Function c_arg(ByVal arg_x As Argnames, ByRef in_str As String, ByRef sptr As Integer, ByVal slen As Integer, ByVal loc_ptr As Integer, ByVal nest As Integer, ByRef errmsg As String)
Dim n_str As String 'A new set of arguments (except errmsg and nest) for parsing an argument at another location
Dim n_slen As Integer
Dim n_sptr As Integer
Dim n_loc As Long
Dim n_nest As Integer
Dim arg_val As Double

With ActiveSheet

arg_val = parse(in_str, sptr, slen, loc_ptr, nest + 1, errmsg) 'Evaluate location argument
If errmsg <> "" Then Exit Function
If sptr > slen Or Mid(in_str, sptr, 1) <> ")" Then 'Must be delimited by a parenthesis a()
errmsg = "Unbalanced parenthesis"
Exit Function
Else
sptr = sptr + 1
End If

' Initialize the parameters for parsing another line argument
n_loc = (((Int(arg_val) + loc_ptr) Mod QSIZE) + QSIZE) Mod QSIZE 'Calculate the location referred to. Converting negative loc to QSIZE+loc
n_str = Replace(.Cells(n_loc + QSTART, arg_x).Value, " ", "") 'The argument at another line minus blanks
n_slen = Len(n_str)
If n_slen = 0 Then 'Count blank argument as zero
c_arg = 0
Exit Function
End If
n_sptr = 1

c_arg = parse(n_str, n_sptr, n_slen, n_loc, nest + 1, errmsg) 'Evaluate new location argument
If errmsg = "" And n_sptr <= n_slen Then 'If no parsing errors, but did not parse the entire argument - error
errmsg = "Invalid argument in line " & str(n_loc)
End If

End With
End Function

'
Function p_add(ByRef in_str As String, ByRef sptr As Integer, ByVal slen As Integer, ByVal loc_ptr As Integer, ByVal nest As Integer, ByRef errmsg As String)
Dim arg1_val As Double
Dim arg2_val As Double

arg1_val = parse(in_str, sptr, slen, loc_ptr, nest + 1, errmsg) 'Evaluate first argument of add() function
If errmsg <> "" Then Exit Function
If sptr > slen Or Mid(in_str, sptr, 1) <> "," Then 'arguments must be separated by comma
errmsg = "Invalid argument list in Add function"
Exit Function
Else
sptr = sptr + 1
End If

arg2_val = parse(in_str, sptr, slen, loc_ptr, nest + 1, errmsg) 'Evaluate second argument of add() function
If errmsg <> "" Then Exit Function
If sptr > slen Or Mid(in_str, sptr, 1) <> ")" Then 'Add() function must end with ")"
errmsg = "Invalid argument list in Add function or unbalanced parenthesis"
Exit Function
Else
sptr = sptr + 1
End If

p_add = arg1_val + arg2_val

End Function
Const QSIZE = 200       'Size of the battle field (node array)

VNA driver executing commands and moving pointers together with user interface and utilities could be developed separately in accordance with personal taste.

I am planning on doing it as an exercise to brush up my Excel programming skills.

Link to comment
Share on other sites

  • 0

Ghost in the Machine is complete :D And it's really really good - superefficient (it only runs one line over and over again) and incredibly hard to kill. It's a self-repairing hopping/bombing hybrid

here's the code:

SHIFT 1;0;16

BOMB -13;8;4

BOMB 40;6;-1.5

BOMB 0;8;0

BOMB 6;-1;72

BOMB 4;4;4

BOMB 7;6;5

BOMB 4;3;2

BOMB 1;0;-1

BOMB 1;2;3

BOMB 4;5;6

BOMB 7;8;9

BOMB 10;20;30

BOMB 6;8;9

BOMB 5;8;13

BOMB -6.7;-6.7;-6.7

SHIFT equ(b(0),87,0,equ(c(1),-6.7,1,-1));equ(c(86),-6.7,87,equ(c(88),-6.7,86,equ(c(103),-6.7,88,equ(c(133),-6.7,103,equ(c(73),-6.7,133,73)))));equ(b(0),87,87,0)

BOMB -6.7;-6.7;-6.7

BOMB 11;2;8

BOMB -1;0;5

BOMB 0;0;0

BOMB 1;1;1

BOMB 17;26;2

BOMB 11;9;1

BOMB 6;8;4

SHIFT 0;87;87

BOMB 2;3;6

PCOPY 1;0;0

BOMB 5;5;5

BOMB 6;6;6

BOMB 7;7;7

SWAP 0;1;0

BOMB 1;5;9

BOMB 34;0;5

BOMB 35;0;4

BOMB 36;0;3

BOMB 37;40;2

BOMB 38;40;1

BOMB 39;40;0
Though most of that is its "nest" (mostly bombs with some other random stuff thrown in, none of which is ever executed). The core part of the program is this:
BOMB -6.7;-6.7;-6.7

SHIFT equ(b(0),87,0,equ(c(1),-6.7,1,-1));equ(c(86),-6.7,87,equ(c(88),-6.7,86,equ(c(103),-6.7,88,equ(c(133),-6.7,103,equ(c(73),-6.7,133,73)))));equ(b(0),87,87,0)

BOMB -6.7;-6.7;-6.7

It went through a few cycles of development, and I made the most recent major change this morning, and decided it was complete. I ran test battles against The Awesome (and Ghost in the Machine won basically every time) and also against Prime's Fish3 (Ghost won about 9 in 11 battles). So yeah, enjoy :D

Link to comment
Share on other sites

  • 0
also, I'm going to start working on a JavaScript emulator soon :D When done, I'll post it as an attachment, then just drag the text file onto your web browser ;D

I have developed a VNA interpreter in Excel with own parser and some rudimentary user interface: command validation, error checking, and argument test. I'll test it some more and then publish a downloadable copy for common use.

The interpreter runs each match in just a few seconds. If you want to observe a battle closely, it allows to execute one step at a time. It has a limitation -- a set limit for nesting currently set at 100.

I just ran Ghost against Fish3 and Fish2 in my interpreter. Ghost did well against both of them. Most of the time it beat Fish3 with a few ties, when it copied its SHIFT command over Fish3's pointer and both pointers became Ghosts.

Fish2 was built on a similar principle as Ghost, but in never managed to bomb it, whereas Ghost did bomb Fish2 few times. Most of the time those two programs end up running over each others pointers and chase each other endlessly. More often it was Fish2 that copied itself over Ghost. Then the entire field gets covered with bombs with only two SHIFT commands jumping around.

I will write slightly improved version of Fish2 (Fish2.2) and see how it fairs against Ghost and against the last version of FOTH's Flawless.

Link to comment
Share on other sites

  • 0

yeah I'm teaching myself JavaScript as I work on the emulator, hehe :) But I've got the hang of it I think - I didn't have much time to work on it today, but tomorrow I will.

Yep I think the key advantage of Ghost is that it only runs one line, the SHIFT line, and is also self-repairing if one of its -6.7bombs gets overwritten with a null-bomb. The only situation it can't recover from if the SHIFT line is bombed (obviously, every single program has the main weakness area, but Ghost's is only in the one SHIFT) OR if BOTH of its bombs are somehow miraculously bombed within a 5-round period before it can repair itself during its leap to the next location. This will cause Ghost to sit in one place and bomb the same spot over again.

Also what do you think is the best "jump-constant", ie, the number that a hopper-like program jumps by each "hop"? I picked 87 for Ghost mostly on whim but also I tried my other "whim" picks and they ended up repeating a cycle close to repetition after a certain number of cycles. Jumping by 87 throughout the VNA seemed to be a very chaotic and stealthy pattern, which is what I was going for. What do you think the ideal number is? It has to be coprime with 200 at the very least, of course

Link to comment
Share on other sites

  • 0
yeah I'm teaching myself JavaScript as I work on the emulator, hehe :) But I've got the hang of it I think - I didn't have much time to work on it today, but tomorrow I will.

Yep I think the key advantage of Ghost is that it only runs one line, the SHIFT line, and is also self-repairing if one of its -6.7bombs gets overwritten with a null-bomb. The only situation it can't recover from if the SHIFT line is bombed (obviously, every single program has the main weakness area, but Ghost's is only in the one SHIFT) OR if BOTH of its bombs are somehow miraculously bombed within a 5-round period before it can repair itself during its leap to the next location. This will cause Ghost to sit in one place and bomb the same spot over again.

Also what do you think is the best "jump-constant", ie, the number that a hopper-like program jumps by each "hop"? I picked 87 for Ghost mostly on whim but also I tried my other "whim" picks and they ended up repeating a cycle close to repetition after a certain number of cycles. Jumping by 87 throughout the VNA seemed to be a very chaotic and stealthy pattern, which is what I was going for. What do you think the ideal number is? It has to be coprime with 200 at the very least, of course

JavaScript? I think you need some real language, to write a good VNA emulator. Like Java, for example.

In my tests of your Ghost against my Fish2 that situation where both programs got stuck on the same spot happened several times.

As for the ideal number to jump...

Any number that is mutually prime with 200 (the queue size) will cover the entire field. If your increment number has some of the same factors as 200 (that is 2 and 5), then it will not cover every node in the field ever. For example, if your increment is 45, after 9 circles around the field it will have covered every 5th node leaving other nodes untouched, whereupon it would land in the nodes already visited.

Thereafter there are some probabalistic considerations in choosing best increment.

That said, proper increment for bomb placing or jumping is not the only area for improvement. There are other considerations.

Link to comment
Share on other sites

  • 0

I upgraded my Fish2 into Fish2.2 and ran few matches against the evasive Ghost with the following results:

Ghost......................Fish2.2

Start Loc. Result ...Start loc. Result....Rounds Comment

..0 ......... -1.........160.........+1..........57

..160..........0.........0.............0..........3011.....I decided, if programs failed to kill one another in 3000 rounds - that's a draw

..0........... -1........ 121........+1..........23

..121..........0..........0............0..........3000

..0.............0..........144.........0...........--........Fish 2.2 ran over Ghost's pointer, whereupon 2 Fishes ran in a harmless cycle

..144..........0..........0............0...........< 100....Both treaded on the same spot fighting to put their signature bombs into same spot

..0..............0.........40..........40..........3200....Failed to kill one another

..40...........-1.........0...........+1...........56

But why Prime and Unreality should have all the fun? I have developed my Excel VNA Emulator to some useable point with some user interface and published it on the internet. I decided that warrants a start of a new topic VNA2.e where I give a link to download my emulator. This topic has run for 10 pages. So we can refresh and start new tournaments. Everyone is invited. Now you can test your VNA programs before submitting them for the tournament. :)

Link to comment
Share on other sites

  • 0

so your Fish2 is also a hopper? Hopper vs Hopper matches have always been pointless, I think. It was that way in VNA also. A real test of a hopper is how often it beats non-hoppers, you know? If we're competing Ghost against Fish2, we should run them against other programs :D

Also, just curious, what is the new Fish2.2? What was changed? I'd like to see its code and learn from it

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...