unreality
Members-
Posts
6378 -
Joined
-
Last visited
Content Type
Profiles
Forums
Events
Gallery
Blogs
Everything posted by unreality
-
actually I've decided against adding the "!" thing- it just seems so silly and superfluous for no actual programming effect. So, the perl emulator (emu.pl) is done! It resides in a folder on my computer along with the file "array.txt" (although you don't need that, it will create it if it can't find it) and a couple programs (i have "imp.txt", "hopbomber.txt" and "advancer.txt"). All you need to run it is the file itself (just a text file and name it "emu.pl") with any programs in the same directory. Remember that program text files are like this: program name author name [[actual program here]] for example, the Hopbomber is like this: Hopbomber Unreality a sum(a,137) 1 a mod(sum(a,1),4) 2 prd(a,50) 1 a 0 134 neg(3) 134 + If anyone is still interested in VNA (lol... ;D It's good cuz making the emulator was good practice) then post here by all means and I'll send you the emulator code. I think we should have a duel of say, 250 nodes per contestant, and each contestant enters two programs. So if three of us played, we would have a 750 node arena and 6 programs total
-
keeping up my self-conversation (), the new bomb is a plus sign ("+"). Now the "x" variable can be used as normal. Also the equal sign is now used to parse metacommand instead of dash, ie, "do=5" does 5 rounds, so as to allow negative numbers The only thing I have left to do is the exclamation point ("!") convenience operator in the SET/IF structures, i'll do that later today
-
I've just added a new metacommand called "change" which lets you change any property (name, author, pointer [aka current line position] and any of the 26 variables) of any program, alive or dead. Keep in mind that "edit", "load" and "change", which allow you to personally edit the VNA in the middle of a game, should only be used in-game if there's some pre-arranged system or sequence for doing so (ie, a game in which, every Nth round, players get to change one variable or one line of code or something like that)
-
alright, it's pretty much done! It has all the features of VNA.4 (except what to do about "x" and the variable "x", see my post two above this one to voice your opinion on that) and even more: * you can specify how many nodes you want the array to be * you can specify what the array is initially filled with * you can load as many programs as you want as well as edit lines & load new programs in realtime during the game * you can see the array as well as a status digest of the programs at any time * you can run as many rounds at once as you want (it's EXTREMELY fast) * you can specify the game to quit after someone wins, OR to prompt you to load a new program into the ring * you can exit anytime edit ~ after someone weighs in on the "x" issue, I'll upload the code for everyone to use! I personally think we should make bombs be equal signs ("=") so that the variable "x" is freed up and there's no confusion, and equal signs are easy to see & differentiate from other code
-
right now, everything is loaded when you start the emulator, but I'm thinking of having a pre-game questionairre type thing that lets you enter the $maxnodes variable (default is 200), so you could have an array of 1000 nodes or 80 nodes or whatever (no limits) rather than having $maxnodes be a constant I define in the code. Another option of this pre-load thing would be allowing the user to say what the default non-program nodes of the VNA are filled with. A third option is what to do in the event of a victory... normally it exits the program, but I think dms mentioned something about being able to load a new program in in this case. Hmmm yes... I'll add this pre-game thing. Also I added a metacommand where if you type "ar", "array" or "vna" it will auto-open the "array.txt" file for you (just a convenience thing and it will only work in UNIX or Mac OS X, but hey it's useful)
-
finished the above tasks and both seem to be working properly One thing is that assigning to the variable "x" will result your program dying because I check the first array entry to see if it's "x". This is remedial in a couple ways... [1] introduce other possible bomb structures other than "x" (ie, the word "bomb", the word "xx", a period/dot, an equals sign, etc) [2] make a quick fix that checks if it is x and only x, THEN die. Remember that if you want to jump by the variable x, you have to do "0 0 x" or "0 0 x x" or "0 0 x x x" or somesuch... or just not use the variable x lol. Either solution fine by me. What do you think?
-
yeah I've also been pretty busy but in a minute I will resume working on the perl VNA.4 emulator - it's pretty nice so far I'm just going to add the var() function I was talking about earlier (in case anyone wants to use it) as well as the capital-letter-copy thing [and are there any other featuers you want added?] and then I'll essentially be done save for some more testing
-
The only thing I have left (though I'll do some more extensive testing to make sure) is the capital-letter thing... ie, when you copy a line, any capital letters in the line get evaluated to numbers for the new line... so this: 1 2 0 A b C might look like this afterward: 1 2 0 A b C 27 b 422 that's pretty much the last thing I have left to do. Since I'm at it, any new feature requests? I was thinking of adding a function like this: var(number) where number is 0 to 25. it would specify a spot in the alphabet linked to one of your variables. For example, var(0) would be equivalent to "a", var(1) is "b", etc. They would be lower-case, not capital, and would get copied as normal with the line. The only advnatage would be if you wanted to change which variable was being used without changing the variable itself or something. idk. Tell me if you think I should impliment that. Let me know if you have any ideas Also are there are any meta-commands for the emulator itself you want? Here's what I'm using now: # "load-NAME.txt" will load a program into the array randomly # and give it the last P<number> spot # # "do-x" will do X rounds # if a program dies, the "do" will stop after the round that # the program died in, even if there were more rounds to execute # # "edit-x-___" will edit line X to look like the rest of the line # after the second dash # # "status" will report information on the round count as well as status of each program # -1 means dead, otherwise the first number is the current position of that program's pointer # the string after that is the variable list, a-z, separated by underscores # # "end" will end the game prematurely and exit the program The 'edit' command has been very useful in troubleshooting & testing, but during an actual game it would be off-limits unless we were doing some kind of "live action" game in which you can make edits on the fly (might be fun if we can establish some ground rules).
-
It's looking great so far... like I said, you can have any number of opponents and add new ones in, and edit lines on the fly, and you can make the array any size you want (currently it's set to 200) and fill it initially with anything you want. I just have a few things to tweak (for example, when a program loads near the edge, it needs to be able to load wrapping around to the beginning, I have to give that functionality) and then program the function evaluator (but I've gotten pretty good at making that, and with Perl's powerful string operators it should be a breeze)
-
I'm pretty far into the above emulator in Perl (I changed a few of the things I said above but same idea)... it can host potentially infinite programs, loaded willy-nilly at any point on the array (no check yet for overwriting so programs can start ANYWHERE though it would be redone if one overwrote the other from the very beginning). It's pretty powerful and fast... still have to finish some parts and do some testing...
-
I like it! I'm down for rewriting the emulator. In fact I was thinking of rewriting it in Perl anyway. The Perl will be command line interface so you won't actually get to see the emulator but I have an idea: there will be a constant input line where you can type things in, ie, something like: "put-____.txt" this would put a new program into the array at a random point. I would have all programs beforehand in text files in the same folder. The format for the text files would be like this: line-one: name of program line-two: name of author rest-of-lines: the program itself .. Another command would be: "do-x" where x is the number of rounds you want to run. After each command finishes, it will rewrite a special "array.txt" file in the same folder. When opened, this file will show the array, each of the 200 nodes on a separate line. Or I could write to an "array.html" file but that would be fancier for a loss of viewing speed (you'd have to open a browswer to 'view it in). windows uses .txt, right? or is it .rtf? I'll try my hardest to make it cross-platform and easy for other people to use. After a "do" command, it will inform you if any programs have died, and on what round. In fact, if in the middle of a "do" command, ie, if the round count it was fed is only partway through, and a program dies, it will stop the "do" and stop it at the round that the program died, and tell you about it. How does all this sound? I could make other fancier commands for more "live-action" battles, something like: "edit-x-____" where 'x' is a node number (0 to 199, even though in the actual game there's no absolute addressing of course, only relative addressing) and the rest of the line after the second dash is what the line there is modified to. Might be interesting... you wouldn't use it for normal games though. What do you think of this idea? It would rank programs by the order that they're put in. P1 is the first program entered, P2 is the second, P3 is the third, etc. The system would be truly random in that there's no limits to where the enemy can be as long as they don't overwrite each other from the getgo.
-
I'm game. Do you mean all at once (would have to rewrite the emulator, but that would be awesome) or some kind of round-robin or bracket-based tournament?
-
I think I mentioned it, although it was a few pages back... ceil(x) stands for the CEILING function and is the counterpart to the FLOOR function, which we have as int(x). I thought it might be useful to add it as well and a few days later it came into play so that was a good call... anyway: int/floor is basically truncate. Ie, int(5) = 5 int(5.1) = 5 int(5.5) = 5 int(5.4987) = 5 int(5.9) = 5 int(5.9999) = 5 int(x) or floor(x) returns the LARGEST INTEGER that is SMALLER THAN or EQUAL TO the input ceiling(x) or ceil(x) is similar but returns the SMALLEST INTEGER that is GREATER THAN or EQUAL TO the input ceil(5) = 5 ceil(4.999) = 5 ceil(4.5) = 5 ceil(4.2) = 5 ceil(4.00001) = 5 ceil(4) = 4 you might think CEILING can be made with FLOOR but this is not true because of their behavior on whole numbers/integers. Both are needed to properly represent the integer-izing functions
-
In the search for a pretty-good program I have created a fundamentally-unbeatable program... here is my thought process, recorded in a text file because I had no internet access to post anything for a while. My thought process begins with the "Advancer" program that I posted in the two posts above this one, and then doodles around from there, eventually realizing the existence of an uber-super-program, deadly-accurate. ceil(div(num(3),5)) inc(mul(ceil(div(num(3),5)),2)) inc(mul(ceil(div(num(3),5)),-1)) 0/1 1/3 1/0 Trying the Advancer program above with advancing two each time and bombing four ahead if a nonbomb is encountered: 0/1 2/4 2/0 ceil(div(num(4),5)) sum(mul(ceil(div(num(4),5)),2),2) sub(2,mul(ceil(div(num(4),5)),2)) not good; can run up against uncopies. GENERAL FORMULA: should advance X and copy bomb N in front 0/1 X/N X/0 ceil(div(num(N),5)) sum(mul(ceil(div(num(N),5)),sub(N,X)),X) sub(X,mul(ceil(div(num(N),5)),X)) Advancer: X=1, N=small number (2 to 6 or so I'd say) Flybomber: X=large & coprime with 200, N=decent gap (5 to 15 or so) trying X=137, N=10 ... decent but eventually locked up. any non X=1 program suffers from the same problem of continually trying to copy a nonbomb over a nonbomb and thus being stuck forever. It's still possible for an X=1 to suffer from this but very very unlikely. Trying out a new class of program now, inspired by what I was just doing. If a one-liner can hop and bomb within itself I figure it can stay put and bomb somehow... but the variation in the Advancer/Flybomber technique comes from it moving around and thus the only stimulus to bomb comes from the nearby environment, with num() commands. So this oneliner bomber would have to use num() commands to fuel a continually advancing bomb arsenal. A simple bomber could be a COPY or SWITCH statement... COPY: 1 x 0 SWITCH: 1 x 0 0 where 1 is the bomb location (would have to gamble on that being a bomb of course but it should work), x is the bomb destination, and the 0s instruct it to jump back. The only advantage of using a SWITCH is that it gives an option to jump somewhere else if the switched lines were the same, so maybe only if I have a secondary line somewhere that we can jump to if the bomb after the SWITCH gets corrupted. But that can only work if we know that the target line is a nonbomb, in which case equal switch lines would mean that our bomb was corrupted. But it's highly unlikely even in that case that our corrupted bomb is now exactly the same as the line we're switching. And it's no use replacing bombs with bombs anyway. So there's no need for a SWITCH. So a bare COPY will work just fine: 1 x 0 The problem is, what to do for the x. I have an idea with varsetting: The Jumplauncher: a add(a,40) a inc(a) 1 a -1 A After the first line initialization it will stay in those middle two lines, with a bombing efficiency of 50%. It won't actually send bombs but rather copy the hard A to thus copy a number that the enemy will jump, hopefully jumping them into bomb territory. My original idea was to use hard vars to use them to advance the bombing, but you cant advance the vars without SET, so this loses the entire purpose of the varsetting. So might as well use "x" instead of "A" to have a surefire kill. And my original idea in the first place was to have 100% bombing efficiency, so the Jumplauncher doesn't work. I'll have to rethink... There might be a way to capture the enemy variables and use THEM to increment yourself by using the sum of all 26 of their variables... but the only way to access their variables is if your program finds their code and if they're using hard/capital vars, so you could've bombed them by that time anyhow. So that leads us back to my original idea for this 100% B.E. bomber: using num()s to get a quasirandom number for bombing. ie, in this line: 1 x 0 x equals sum(30,num(0),num(1),num(2),num(3),...,num(198),num(199)) We have 33 at least from the +30 and +num(0), after that bombs in the VNA count as zero and the opponent's lines add on. The problem is that x will never change if the opponent is self-contained, since if they bomb with bombs it will just override bombs for the most part and change nothing. Only if the opponent is some kind of hopper would they add additional nums to the VNA... but not if they're a more-efficient no-trace switch-hopper that deletes the previous copy. So using a massive addition function of nums() can't support a dynamically changing bomb target in a oneliner. It would work much better if it was facing against a bunch of different opponents that were replicating and bombing each other, but not one-on-one. The next idea is a superline of sorts that would work like this: [i believe that plasmid offered a superline that use powers and then roots to find roughly where the opponent was but I was skeptical... I haven't yet checked his superline out yet and I don't have internet access right now, so I'll try constructing my own in a different fashion] * check if num(z) > 0 ... if true, bomb, if not, try num(z+1) Borrowing from the Advancer: ceil(div(num(z),5)) the above snippet outputs 0 if line 'z' contains a BOMB, and outputs 1 for all other structures. A system would have to be rigged where a result of 1 ends it and a result of 0 adds on to the next z. In other words, they would be nested inside of each other, and the z above would itself be identical to the overall snippet, and ad infinitum to a certain point. It would be sneakier than that though because if it's just what I described, finding a nonbomb will then prompt it to check the line right after itself. We need to revamp the snippet to this: sub(1,ceil(div(num(z),5))) Much better. This returns 0 if we need to bomb and 1 to keep looking. If only we could add the result of this snippet to z itself for the next iteration. Then if we ever get to 0, it'll be z+0 and so on until the end, thus outputting z as the line we need to bomb (if we subtract the overall from 1 and then multiply by z for the final most-outside iteration). However, 1 is outputted if there's a bomb, so we need to find a way to add the output to the next z and so search the next node for enemy code. I believe this is possible... say that this: sub(1,ceil(div(num(z),5))) is a function referred to as: snip(z) It just outputs 0 if we've found a nonbomb line, 1 if we've found a bomb line. i think what we need to do is this: snip(z+snip(z+snip(z...))) say that we initialize the value of 'z' with 42, and the innermost section is simply snip(z+snip(z+snip(z))), coming to a halt. it will first evaluate to this: snip(z+snip(z+snip(42))) If line 42 is a bomb, snip(42) it will evaluate to 1 snip(z+snip(z+1)) and we now have: snip(z+snip(43)) oh crap. If snip(43) also evaluates to 1, we're left with 43 again on the outside. It needs to be like this: snip(46+snip(45+snip(44+snip(43+snip(42))))) etc [the above snippet is just the innermost section] so if snip(42)=1, we'll check snip(44) next... crap, then snip(45) if that's a 1, and so on. Unfortunately snip(43) will never be checked but that's okay. The problem is that I don't think this is the right behavior if snip(42) evaluates to zero (since zero means "bomb this line!") since the numbers cascade up. What I'm saying is that for it to work, they ALL have to be 42, they can't cascade down 46,45,44,43,42... But we need an extra addition in each section. Something that retains the value of the line that was just processed, so that a result of 0 is a result of 0+n (where n is the line we found a nonbomb at) cascading ALL THE WAY UP. In other words, each higher-leveled nest needs to check the line that was just checked inside PLUS the output of the line that was checked inside. So we check 42, get 1. 42+1=43. Check 43, get 1. 43+1=44. Etc. Until we check say, 85, and get 0, which means nonbomb. 85+0 means 85 so we check 85 again, and again, and again, until we get out of the superline with the result of 85. So each snip needs to check the line processed by the below snip plus the output of that. Ie, each snip, when evaluated, needs to look like this: snip(x+snip(x)) So if we're checking line 63: snip(63+snip(63)) If we need to bomb at 63, then 63 is returned for the higher level. If we don't, then 64 is returned. So we need to have it so that each snip checks an addition of two things: * the snip checked two levels down [63 in the above example] * the snip checked one level down [snip(63) in the above example] but of course nested. 42 ... the base unit 42+snip(42) ... our initial unit [checks 42] 42+snip(42)+snip(42+snip(42)) ... our next highest unit [checks 43] 42+snip(42)+snip(42+snip(42))+snip(42+snip(42)+snip(42+snip(42))) ... the next highest unit [checks 44] etc. If a unit is this: U then the next highest unit this: U+snip(U) In a second I'm going to write a Perl script that starts with 42 as U and then iterates until we have checked node 199. 42 is checked with two appearances of 42, 43 checked with 4 appearances, 44 with 8 appearances, so node X will have 2^(X-41) appearances of the number "42". So node 199 can only be checked if the superline has 2^(199-41) = 2^158 = 3.65375409 * 1047 occurences. In other words, in no way am I going to write that Perl script lol. General formula to check nodes U through U+X is: U -> U+snip(U) iterated 2 occurences of U for checking U 4 occurences of U for checking U+1 8 occurences of U for checking U+2 ... 2^(X+1) occurences of U for checking from U until U+X so to check from 42 to 199 it will take 2^(199-42+1) = 2^(158) as I already said. But if I were to check, say, 42 to 158, the zone in which the enemy could be, it would only take 2^(117) occurrences of the number "42" in this superline. This is roughly: 1.66153499 * 1035 But that's the smallest it can be to cover all possible starting nodes of the enemy program. I would then generate this string, and instead of the function snip(z) I would use: sub(1,ceil(div(num(z),5))) iterating this out until we have 2^117 occurences of the number 42. Then call that whole string x. The UBERBOMBER would then look like this: 1 x 0 And it would win on round 1 provided it went first. If it goes second, it would win on round 2 unless the enemy jumps out of the zone. In curiosity of what would be physically feasible, I should think that 2^17 or 131072 is acceptable. It'd be a horrendoulsy long line, yes, but it wouldn't be impossible to generate. So that would enabling checking from U to U+16. I could keep a variable 'z' that starts off at 42 and then is incremented the next line by 17. Thus the program could comb through batches at once. But if it's technologically possible under our circumstances teo extend out the snip() line, it can check EVERY SINGLE NODE with 100% ACCURACY and determine the exact spot of the enemy - and then bomb it - in a single turn. *bow*
-
I justed tested it and it works. It advances line by line (I can change it from just +1 to any number if you want) until it sees a non-bomb line 3 ahead from itself, which it proceeds to bomb before marching onward again. See, no special clauses necessary It was a fun challenge and probably a pretty decent program, with some tweaks. To see it in action, make it P1 and make P2 "0 1 1" and distance P2 at 20 away or so. edit - make sure you have the most recent emulator, which supports the ceiling function
-
I believe I've figured it out, no fancy shmancy necessary: ceil(div(num(3),5)) inc(mul(ceil(div(num(3),5)),2)) inc(mul(ceil(div(num(3),5)),-1)) depending on what num(3) is [no-bomb or bomb], the line will reduce to "1 3 0" (bomb), or "0 1 1" (advance)
-
this: should be this: 4 x 0 0 0 0 <actual program here> I have yet to think of how it might work but when I go to bed I'll mull over it
-
sum(num(8),num(9),num(10),num(11),num(12)) 0 1 5 ! k -4 k inc(k) k sum(13,k) 1 k 4 9 9 -2 j inc(j) -7 inc(j) 1 j 5 -6 -6 -2 I haven't yet tested its behavior when it encounters an enemy but it works good from what i've done so far. It's not too efficient, though, of course 0 137 137 137 this has been done in one of dms's programs I think, and more extensive regeneration subroutines were used in one of plasmid's programs the trick here is to have a COPY line like this: 0|1 1|3 1|0 ie, it alternates from this: 0 1 1 to this: 1 3 0 at first glance it's not possible without an additional line to change a variable (which would make the self-copying a lot more complex) but I think it may be possible under a single line with the num function if you do something like this: 3 x 0 0 0 0 <actual program here> it can refer back somehow to those three lines (x, 0, 0 0 0) and use the num() function to get values of 0, 1 or 3. I'll think about how this might be possible I'm not sure what you mean "shifts lines around" but here's a fibonacci incrementer: s 0 t 1 s sum(s,t) t sum(s,t) 2 4 1 2 3 -3 S T x it will generate a continuous ouput over that last "x" starting with 1, then 2,3,5,8,13,etc. It could be changed to make it output the next number each one line down to create a list of fibonaccis a while ago I imagined something called the "hijacker" which would only work if the VNA was filled with 1's instead of x's. In this case, the hijacker would simply be the numeral "1" and would eventually 'hijack' the opponent's code. This is easily avoidable if your first line replaces itself with a bomb and then jumps forward 1 to the actual start of the program, but still, an interesting concept... I don't think such defenses are really warranted unless hijackers are perceived as a very real threat depending on how your program is structured. The pacifist is a bit different though... I think a simple hopper is effectively a pacifist in a way. Even Zebra Warrior, which bombed while hopping, forced a lot of ties while hopping around since the enemy got sucked in. An even faster hopper could easily overtake large programs and catch them in the game. The trick would be to NOT be a switch-hopper since that erases its travel, but a normal copy-hopper... I think a hop constant of something small, like 11 or maybe even as low as 7, would be most effective, provided it's coprime with 200.
-
the point perhaps is in the limitations of the code. There are clever ways to incorporate comparison stuff with the IF structure as well as with moduli and things, and a few other tricks you can do, like capital letter variables allow you to "edit" lines or custom-copy lines with current variables. Try things like that The language structure shouldn't be rewritten in any case to allow for certain programs; in fact it would be too easy if you could heap a bunch of commands on a single line. Usually there are things you can do to create an optimal program that's still efficient... maybe if you tell us some of your ideas we can help or see if it's not too far-fetched to tweak some things on the emulator?
-
yeah - about 4 hours and 15 minutes from now I'll try to make it
-
frog works fine on mine
-
I know that prime numbers are technically defined as 'positive' but -1 is arguably a prime. Its only factors are itself and 1. If you do allow negative numbers, -1 can be the ONLY such negative prime because any other negative prime number has itself and 1 along with -1 and its positive self
-
i just had a bit of time so I wrote a program called "hopcalc.html"... <html> <head> <title>Hop Calculator, by unreality</title> <script LANGUAGE="JavaScript"> var curval = 0; function gogogo() { var numits = document.form1.its.value*1; var numcons = document.form1.cons.value*1; var numnodes = document.form1.nodes.value*1; for (i=0;i<numits;i++) { curval = (curval+numcons) % (numnodes); document.form1.outp.value += (curval + "\n"); } } function ccc() { document.form1.outp.value = ""; curval = 0; } </script> </head> <body> <form name="form1"><h1>Hop Calculator</h1><br><br>Hop Constant: <input type="text" name="cons" length="10" value="0"><br>Iterations: <input type="text" name="its" length="10" value="10"><br>Nodes: <input type="text" name="nodes" length="10" value="200"><br><input type="button" value="Go" onClick="gogogo();"><br><hr><br><textarea name="outp" rows=30 cols=30></textarea><br><input type="button" value="Clear" onClick="ccc();"> </form> </body> </html> the Hop Constant is how much the program hops by, for example it could be 137. Nodes is 200 for this game of course, but you can change that for curiosity. Iterations is how many hops you want to do. It just adds the constant and mods by 200 each time, displaying the lines it will be at. Pretty simple yet useful... it's perhaps more useful as a bomb calculator to see where your bombs will land. The variable is preserved globally so pressing the button again will continue from that point (and if you've changed the parameters, it will still continue from that point with the current variable in the newer settings). If you press Clear, it will wipe the display field and reset the counter variable to zero
-
Thanks for joining the fray, philip! I've been busy and have yet to experiment with the lengthy-line dilemma, but later today I may have sufficient time to play around. Everyone has the most recent version of the emulator, though, I assume... too bad there's no way of editing the OP with the most updated. I also have yet to inspect plasmid's superline and get the logic behind it... it seems impossible to me at first glance but I haven't thought about it carefully yet... anyway, i gtg, bbl...
-
about the 117, yeah my bad... I was thinking about a different number. You are correct that there are 160 nodes that are not in the domain of your initial round-zero program. And to everyone, this is the most recent emulator, with extra changes to make sure there are no numerical errors in regards to dividing by zero, etc. If you think the defaults I gave should be changed (ie, the result shouldn't be 0 for inv(0), div(x,0), etc) just tell me, I think 0 is a useful default though... <html> <head> <title>VNA.4 Emulator, by unreality</title> <script LANGUAGE="JavaScript"> /* global declarations */ var vna = new Array(); var alphastring = "abcdefghijklmnopqrstuvwxyz"; var capalphastring = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; var p1vararray = new Array(26); var p2vararray = new Array(26); /* functions */ function doSwitch() { getp1 = document.form1.p1.value; getp2 = document.form1.p2.value; document.form1.p1.value = getp2; document.form1.p2.value = getp1; } function doClear() { document.form1.p1.value = null; document.form1.p2.value = null; } function doRandomStart() { document.form1.startline.value = Math.floor(117*Math.random())+42 } function loadArray() { var pr1 = new Array(); var pr2 = new Array(); pr1 = document.form1.p1.value.split("\n"); pr2 = document.form1.p2.value.split("\n"); var nStart = document.form1.startline.value; var error1=""; var error2=""; var error3=""; if (pr1.length > 40) error1 = "Program 1 is too long! "; if (pr2.length > 40) error2 = "Program 2 is too long! "; if (nStart=="") error3 = "You must specify a starting node for P2!"; error3 = error1 + error2 + error3; if (error3 != ""){alert(error3); return;} var iString; var cString = document.form1.fillwith.value; for (ihh=0;ihh<200;ihh++) { iString = cString; if (ihh<pr1.length) {iString = pr1[ihh];} if (ihh>=nStart && ihh<nStart+pr2.length) {iString = pr2[ihh - nStart];} if (iString == undefined) iString = cString; vna[ihh] = iString; } document.form1.vnarray.value = vna.join("\n"); document.form1.point1.value = 0; document.form1.point2.value = nStart; document.form1.rnds.value = 0; document.form1.dornd.disabled = false; document.form1.doxrnd.disabled = false; document.form1.xrd.value = 10; // fill variable arrays for(iww=0;iww<26;iww++) { p1vararray[iww] = 0; p2vararray[iww] = 0; } document.form1.seevars.disabled = false; } function doRound() { // increment round counter document.form1.rnds.value++; // pointer locations var lineOne = document.form1.point1.value*1; var lineTwo = document.form1.point2.value*1; // P1 first var zline = vna[lineOne].toLowerCase(); // count the number of spaces in zline var chratloopy = 0; var numspaces = 0; while (chratloopy < zline.length) { if (zline.charAt(chratloopy) == " ") numspaces++; chratloopy++; } var newline; var paramz = zline.split(" "); var valqa = doFunc(paramz[0]+"",lineOne,1)*1; if (numspaces > 0) var valqb = doFunc(paramz[1]+"",lineOne,1)*1; if (numspaces > 1) var valqc = doFunc(paramz[2]+"",lineOne,1)*1; if (numspaces > 2) var valqd = doFunc(paramz[3]+"",lineOne,1); if (numspaces > 3) var valqe = doFunc(paramz[4]+"",lineOne,1); if (valqd != "!") valqd *= 1; if (valqe != "!") valqe *= 1; switch (numspaces) { case 0: if (zline == "x") { document.form1.dornd.disabled = true; document.form1.doxrnd.disabled = true; alert("Program 2 wins!"); return; } else { newline = doMod(lineOne + valqa); } break; case 1: var firstchar = zline.charAt(0); p1vararray[alphastring.indexOf(firstchar)] = valqb; newline = doMod(lineOne + 1); break; case 2: var replacestring = vna[doMod(lineOne+valqa)]; // check for capital variables var zzingl; var dropfwhenzero = 1; while (dropfwhenzero == 1) { zzingl = replacestring.length; dropfwhenzero = 0; for (eee=0;eee<zzingl;eee++) { if (capalphastring.indexOf(replacestring.charAt(eee)) != -1) { replacestring = replacestring.substring(0,eee) + p1vararray[capalphastring.indexOf(replacestring.charAt(eee))] + replacestring.substring(eee+1); dropfwhenzero = 1; } } } vna[doMod(lineOne+valqb)] = replacestring; newline = doMod(lineOne + valqc); break; case 3: var temptemptemp = vna[doMod(valqa + lineOne)]; vna[doMod(valqa + lineOne)] = vna[doMod(valqb + lineOne)]; vna[doMod(valqb + lineOne)] = temptemptemp; if (vna[doMod(valqa + lineOne)] == vna[doMod(valqb + lineOne)]) { newline = doMod(lineOne + valqc); } else { if (valqd != "!") newline = doMod(lineOne + valqd); if (valqd == "!") newline = doMod(lineOne + valqc); } break; case 4: if (valqa == valqb) {newline = doMod(lineOne + valqc);} if (valqa > valqb) {newline = doMod(lineOne + valqd);} if (valqa < valqb && valqe == "!") {newline = doMod(lineOne + valqd);} if (valqa < valqb && valqe != "!") {newline = doMod(lineOne + valqe);} break; } // // // P2 now // // var zline = vna[lineTwo].toLowerCase(); // count the number of spaces in zline var chratloopy = 0; var numspaces = 0; while (chratloopy < zline.length) { if (zline.charAt(chratloopy) == " ") numspaces++; chratloopy++; } var newxline; paramz = zline.split(" "); valqa = doFunc(paramz[0]+"",lineTwo,2)*1; if (numspaces > 0) var valqb = doFunc(paramz[1]+"",lineTwo,2)*1; if (numspaces > 1) var valqc = doFunc(paramz[2]+"",lineTwo,2)*1; if (numspaces > 2) var valqd = doFunc(paramz[3]+"",lineTwo,2); if (numspaces > 3) var valqe = doFunc(paramz[4]+"",lineTwo,2); if (valqd != "!") valqd *= 1; if (valqe != "!") valqe *= 1; switch (numspaces) { case 0: if (zline == "x") { document.form1.dornd.disabled = true; document.form1.doxrnd.disabled = true; alert("Program 1 wins!"); return; } else { newxline = doMod(lineTwo + valqa); } break; case 1: firstchar = zline.charAt(0); p2vararray[alphastring.indexOf(firstchar)] = valqb; newxline = doMod(lineTwo + 1); break; case 2: var replacestring = vna[doMod(lineTwo+valqa)]; // check for capital variables var zzingl; var dropfwhenzero = 1; while (dropfwhenzero == 1) { zzingl = replacestring.length; dropfwhenzero = 0; for (eee=0;eee<zzingl;eee++) { if (capalphastring.indexOf(replacestring.charAt(eee)) != -1) { replacestring = replacestring.substring(0,eee) + p1vararray[capalphastring.indexOf(replacestring.charAt(eee))] + replacestring.substring(eee+1); dropfwhenzero = 1; } } } vna[doMod(lineTwo+valqb)] = replacestring; newxline = doMod(lineTwo + valqc); break; case 3: var temptemptemp = vna[doMod(valqa + lineTwo)]; vna[doMod(valqa + lineTwo)] = vna[doMod(valqb + lineTwo)]; vna[doMod(valqb + lineTwo)] = temptemptemp; if (vna[doMod(valqa + lineTwo)] == vna[doMod(valqb + lineTwo)]) { newxline = doMod(lineTwo + valqc); } else { if (valqd != "!") newxline = doMod(lineTwo + valqd); if (valqd == "!") newxline = doMod(lineTwo + valqc); } break; case 4: if (valqa == valqb) {newxline = doMod(lineTwo + valqc);} if (valqa > valqb) {newxline = doMod(lineTwo + valqd);} if (valqa < valqb && valqe == "!") {newxline = doMod(lineTwo + valqd);} if (valqa < valqb && valqe != "!") {newxline = doMod(lineTwo + valqe);} break; } // render the VNA document.form1.vnarray.value = vna.join("\n"); document.form1.point1.value = newline; document.form1.point2.value = newxline; } function doMod(zeinput) { while (zeinput < 0) { zeinput += 200; } zeinput = zeinput % 200; return zeinput; } function doFunc(param, qline, zpp) { if (param == "") return ""; if (param == "!") return "!"; if (alphastring.indexOf(param) != -1) { return doSuperFunc(param, zpp); } var tempeval; var closeparen; var funcin; var beforeparstring; var commaloc; var parenloc; var rightloc; var funcname; var inputarray = new Array(); /*var xdata = new Array();*/ // loop until param is just a number while (param*1 != param) { closeparen = param.indexOf(")"); openparen = (param.substring(0,closeparen+1)).lastIndexOf("("); funcin = param.substring(openparen+1,closeparen); beforeparstring = param.substring(0,openparen); commaloc = beforeparstring.lastIndexOf(","); parenloc = beforeparstring.lastIndexOf("("); rightloc = Math.max(commaloc,parenloc); funcname = param.substring(rightloc+1,openparen); funcname = funcname.toLowerCase(); // /*alert(closeparen+" -- "+openparen+" -- "+commaloc+" -- "+parenloc+" -- "+rightloc+" -- "+zpp+qline); alert("Name: "+funcname+", Input: "+funcin);*/ // inputarray = funcin.split(","); for (yyyy=0;yyyy<inputarray.length;yyyy++) { inputarray[yyyy] = doSuperFunc(inputarray[yyyy],zpp); } switch (funcname) { case "sum": case "add": tempeval = 0; for (tttt=0;tttt<inputarray.length;tttt++) { tempeval += inputarray[tttt]; } break; case "prd": case "mul": case "mult": tempeval = 1; for (ssss=0;ssss<inputarray.length;ssss++) { tempeval *= inputarray[ssss]; } break; case "inc": case "incr": tempeval = (inputarray[0] + 1); break; case "dec": case "decr": tempeval = (inputarray[0] - 1); break; case "neg": tempeval = (inputarray[0] * -1); break; case "inv": if (inputarray[0] == 0) {tempeval = 0} else {tempeval = 1 / inputarray[0];} break; case "num": var linetoterm = vna[doMod(qline + inputarray[0])]+""; tempeval = 1; for (ccc=0;ccc<linetoterm.length;ccc++) { if (linetoterm.charAt(ccc) == " ") tempeval++; } if (linetoterm == "x") tempeval = 0; break; case "mod": if (inputarray[1] == 0) {tempeval = 0} else{tempeval = (inputarray[0]) % (inputarray[1]);} break; case "pow": tempeval = Math.pow(inputarray[0],inputarray[1]); break; case "div": if (inputarray[1] == 0) {tempeval = 0} else{ tempeval = (inputarray[0]) / (inputarray[1]);} break; case "sub": tempeval = (inputarray[0]) - (inputarray[1]); break; case "log": if (inputarray[0] == 0) {tempeval = 0} else{tempeval = Math.log(inputarray[1]) / Math.log(inputarray[0]);} break; case "abs": tempeval = Math.abs(inputarray[0]); break; case "int": tempeval = Math.floor(inputarray[0]); break; case "ceil": tempeval = Math.ceil(inputarray[0]); break; } // replace part of param with tempeval... then loop again param = param.substring(0,rightloc+1) + tempeval + param.substring(closeparen+1); } return param; } function doSuperFunc(qwerty, zppp) { var qwertest = alphastring.indexOf(qwerty); if (qwertest != -1) { if (zppp == 1) qwerty = p1vararray[qwertest]; if (zppp == 2) qwerty = p2vararray[qwertest]; } else qwerty *= 1; return qwerty; } function doXRounds() { var getx = document.form1.xrd.value; for (bbb=0;bbb<getx;bbb++) { doRound(); } } function seeVars() { var ystr = "P1:\n"; for (inn=0;inn<26;inn++) { if (p1vararray[inn] != 0) ystr += alphastring.charAt(inn)+" = "+p1vararray[inn]+"\n"; } ystr += "\nP2:\n"; for (inn=0;inn<26;inn++) { if (p2vararray[inn] != 0) ystr += alphastring.charAt(inn)+" = "+p2vararray[inn]+"\n"; } alert(ystr); } /* end of script */ </script> </head> <body> <h1>VNA.4 Emulator, by unreality</h1><form name="form1"> <br><br><br>P1 <br> <textarea name="p1" rows=10 cols=100></textarea> <br>P2<br><textarea name="p2" rows=10 cols=100></textarea> <br> <center><input type="button" value="Switch" onClick="doSwitch();"><input type="button" value="Clear" onClick="doClear();"></center> <br><br><br><br> P1 starts at line 0 and goes first<br> P2 starts at line X and goes second<br> X: <input type="text" name="startline" length="10"> <input type="button" value="Random" onClick="doRandomStart();"> <br>(range 42 to 158 please) <br><br><br><br><center>Fill with: <input type="text" name="fillwith" length="10" value="x"></center><br><input type="button" value="Load the Virtual Node Array!" onClick="loadArray();"><br><hr><br> VNA:<br><textarea name="vnarray" rows=30 cols=100></textarea><br> P1 Pointer: <input type="text" name="point1" length="10"><br> P2 Pointer: <input type="text" name="point2" length="10"><center> <input type="button" value="Do 1 Round" name = "dornd" onClick="doRound();"> <input type="button" value="Do X Rounds" name="doxrnd" onClick="doXRounds();"> X:<input type="text" name="xrd" length="10"></center><br> Rounds: <input type="text" name="rnds" length="10"><input type="button" value="See Nonzero Variables" name="seevars" onClick="seeVars();" disabled="true"> </form> </body> </html>