Initial import of noit o' mnain worb 1.1 revision 2000.0719.
Cat's Eye Technologies
12 years ago
0 | Copyright (c)2000, Cat's Eye Technologies. | |
1 | All rights reserved. | |
2 | ||
3 | Redistribution and use in source and binary forms, with or without | |
4 | modification, are permitted provided that the following conditions | |
5 | are met: | |
6 | ||
7 | Redistributions of source code must retain the above copyright | |
8 | notice, this list of conditions and the following disclaimer. | |
9 | ||
10 | Redistributions in binary form must reproduce the above copyright | |
11 | notice, this list of conditions and the following disclaimer in | |
12 | the documentation and/or other materials provided with the | |
13 | distribution. | |
14 | ||
15 | Neither the name of Cat's Eye Technologies nor the names of its | |
16 | contributors may be used to endorse or promote products derived | |
17 | from this software without specific prior written permission. | |
18 | ||
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | |
20 | CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, | |
21 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
22 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
23 | DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE | |
24 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, | |
25 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
26 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, | |
27 | OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
28 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
29 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
30 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
31 | POSSIBILITY OF SUCH DAMAGE. |
0 | <html><head> | |
1 | <meta http-equiv="Content-Type" content="text/html;CHARSET=iso-8859-1"> | |
2 | <meta name="Description" content="Cat's Eye Technologies: The "noit o' mnain worb" Language"> | |
3 | <title>Cat's Eye Technologies: The "noit o' mnain worb" Language</title> | |
4 | <meta name="Keywords" content=" Cat's Eye Technologies Language | |
5 | Programming computational computation non-deterministic | |
6 | bobule concurrency constraint-based physics mechanics electronics | |
7 | nondeterminstic fungeoid funge befunge experimental "> | |
8 | </head> | |
9 | <body> | |
10 | <center> | |
11 | <h1>noit o' mnain worb</h1> | |
12 | </center><p><font size=-1>Version 1.1</font> <font size=-1> <img src="/images/icons/copyright.gif" | |
13 | align=absmiddle width=12 height=12 alt="(c)" border=0>2000-2004 <a href="/">Cat's Eye Technologies</a>. All rights reserved.<br> | |
14 | This software is OSI Certified Open Source Software.<br> | |
15 | OSI Certified is a certification mark of the <a href="http://www.opensource.org/"><img src="/images/icons/webicon.gif" alt="[WWW]" border=0 width=12 height=12>Open Source Initiative</a>.<br> | |
16 | See the file <a href="license.txt">license.txt</a> for license information.</font> | |
17 | <hr> | |
18 | ||
19 | <h3>What is <u>noit o' mnain worb</u>?</h3> | |
20 | ||
21 | <p>The <u>noit o' mnain worb</u> language is a | |
22 | non-deterministic particle automaton based on brownian motion (or entropy). | |
23 | ||
24 | <p>A <u>noit o' mnain worb</u> runtime has an orthogonal gridwork | |
25 | playfield (of any reasonable size or number of dimensions) | |
26 | which is populated by any number of <i>bobules</i>. Bobules are <i>solid</i> | |
27 | elements in this grid - that is, no two bobules may occupy the same location. | |
28 | Bobules are also capable of motion - in fact they can hardly avoid it - and it is | |
29 | important to note that they are stateless. As such, they have no idea which | |
30 | direction they are going, nor what they are going to do when they get there.</p> | |
31 | ||
32 | <p>Each time quantum, or <i>tick</i>, each bobule chooses an adjacent square | |
33 | to move to, at random (in two dimensions, that's 8 possibilities | |
34 | plus the possibility of not moving = 9 possibilities.) | |
35 | If, during some tick, this randomly-chosen new location does not allow entry - | |
36 | that is, if it is already occupied by a solid element (a bobule or a wall) - the | |
37 | bobule does not move during that tick.</p> | |
38 | ||
39 | <p>[Implementation note: each tick that a bobule is blocked from moving, | |
40 | its "pressure" increases, although this is merely for visual effect.]</p> | |
41 | ||
42 | <p>The playfield is made more interesting by the addition of: | |
43 | <ul> | |
44 | <li> <tt>#</tt> <i>walls</i> which are merely static solid elements that take up space and do not move; | |
45 | <li> <tt>^v><</tt> <i>diodes</i> which disallow bobules from passing through them backwards; | |
46 | <li> <tt>+-</tt> <i>sources & sinks</i> which represent large repositories or vacancies of bobules; and | |
47 | <li> <tt>!</tt> <i>loads</i> which represent something that the bobules can 'do'. | |
48 | </ul></p> | |
49 | ||
50 | <h3>Notes</h3> | |
51 | ||
52 | <p>[Historical note: In version 1.0 (Jul 5 2000) of the language, which was released only | |
53 | on the Cat's Eye Technologies Mailing List, | |
54 | <tt>+-</tt> had much different (and much more myopic) | |
55 | semantics than they do in v1.1.]</p> | |
56 | ||
57 | <p>The sources and sinks are simply convenient 'macros', so that you can | |
58 | build something like:</p> | |
59 | ||
60 | <pre> | |
61 | ### | |
62 | ###+### | |
63 | </pre> | |
64 | ||
65 | <p>instead of saying something like:</p> | |
66 | ||
67 | <pre> | |
68 | ####### | |
69 | #.....# | |
70 | #.....# | |
71 | #.....# | |
72 | ###.### | |
73 | #.# | |
74 | ###v### | |
75 | </pre> | |
76 | ||
77 | <p>Using the <tt>+</tt> sources and <tt>-</tt> sinks simply saves you | |
78 | from specifying large chambers of bobules or emptiness explicitly.</p> | |
79 | ||
80 | <p>[Implementation note: It is not the intention of the <tt>+</tt> element | |
81 | to violate entropy, but the fact that, in the reference implementation, <tt>+</tt> | |
82 | keeps producing bobules indefinately at a uniform rate of 10% chance per tick | |
83 | does bend the rules a bit. In a more "entropically correct" implementation, the | |
84 | chance per tick should decrease over time. Note that the language proper | |
85 | does not specify any particular rate of bobule creation, but encourages | |
86 | implementations to be flexible on this point.]</p> | |
87 | ||
88 | <p>The <tt>!</tt> loads simply cause the implementation to react in some | |
89 | noticable way when a bobule enters into their location, so that the | |
90 | <u>noit o' mnain worb</u> programmer can pretend to themselves that their | |
91 | bobules are 'doing something' during program runs.</p> | |
92 | ||
93 | <p>[Implementation note: The reference interpreter simply outputs an ASCII | |
94 | BEL character when this happens. On most terminals, this affects a beeping | |
95 | sound.]</p> | |
96 | ||
97 | <p>The idea is that the bobules, spaces, walls, and diodes alone constitute a (nearly) | |
98 | Turing-Complete system.</p> | |
99 | ||
100 | <p>I say "nearly" because it's actually missing a dimension in this form. The | |
101 | <u>noit o' mnain worb</u> language isn't dimensionally-independent. | |
102 | Notably, it doesn't work in one dimension at all.</p> | |
103 | ||
104 | <p>It <i>almost</i> works in two dimensions, but the fact is that if you do not address | |
105 | the 'wire-crossing problem' (see <a href="/projects/befunge93/">Befunge-93</a>'s | |
106 | <tt>#</tt> instruction), you cannot | |
107 | guarantee being able to connect two arbitrarily-chosen paths in two dimensions. | |
108 | You need to have a way for coincident paths to cross, which is not strictly | |
109 | just two dimensions anymore.</p> | |
110 | ||
111 | <p>[Theoretical note: we suspect, but would surely have a hard time proving, | |
112 | that this limitation is somehow related to the four-colour map theorem.]</p> | |
113 | ||
114 | <p>So, it really only works in three dimensions and above. For that reason, | |
115 | adding 'wormholes' to the <u>noit o' mnain worb</u> playfield is a possible | |
116 | extension in the near future, to simulate three dimensions a la 'wire crossing'.</p> | |
117 | ||
118 | </body></html> |
0 | ############ | |
1 | #..........# | |
2 | #######v#### | |
3 | # # | |
4 | #v#### | |
5 | # # | |
6 | #v#### | |
7 | # # | |
8 | #v#### | |
9 | # # | |
10 | ###### |
0 | ###################### | |
1 | # # | |
2 | # # | |
3 | # # | |
4 | # # | |
5 | # # | |
6 | # + # | |
7 | # # | |
8 | # # | |
9 | # # | |
10 | # # | |
11 | ###################### |
0 | ######### | |
1 | #! ! ! !# | |
2 | ###### ! ! ! ###### | |
3 | #+ ! ! ! ! -# | |
4 | ###### ! ! ! ###### | |
5 | #! ! ! !# | |
6 | ######### |
0 | ###################### | |
1 | # # | |
2 | # # | |
3 | # # | |
4 | # # | |
5 | # - # | |
6 | # + # | |
7 | # # | |
8 | # # | |
9 | # # | |
10 | # # | |
11 | ###################### |
0 | ##### ##### | |
1 | # ########### # | |
2 | # . > < . # | |
3 | # #####v##### # | |
4 | ##### # ######## | |
5 | # >!# | |
6 | #v######### | |
7 | # # | |
8 | ### |
0 | ##################### | |
1 | # < # | |
2 | # ################# # | |
3 | # # # # | |
4 | # # #.# | |
5 | # # # # | |
6 | # ################# # | |
7 | # > # | |
8 | ##################### |
0 | ###################### | |
1 | #.......... # | |
2 | #.......... # | |
3 | #.......... # | |
4 | #.......... # | |
5 | #.......... # | |
6 | #.......... # | |
7 | #.......... # | |
8 | #.......... # | |
9 | #.......... # | |
10 | #.......... # | |
11 | ###################### |
0 | #/usr/local/bin/perl -w | |
1 | ||
2 | # noit o' mnain worb - fungeoid language based on brownian motion | |
3 | # v1.1 Jul 19 2000 Chris Pressey, Cat's Eye Technologies | |
4 | ||
5 | # Copyright (c)2000, Cat's Eye Technologies. | |
6 | # All rights reserved. | |
7 | # | |
8 | # Redistribution and use in source and binary forms, with or without | |
9 | # modification, are permitted provided that the following conditions | |
10 | # are met: | |
11 | # | |
12 | # Redistributions of source code must retain the above copyright | |
13 | # notice, this list of conditions and the following disclaimer. | |
14 | # | |
15 | # Redistributions in binary form must reproduce the above copyright | |
16 | # notice, this list of conditions and the following disclaimer in | |
17 | # the documentation and/or other materials provided with the | |
18 | # distribution. | |
19 | # | |
20 | # Neither the name of Cat's Eye Technologies nor the names of its | |
21 | # contributors may be used to endorse or promote products derived | |
22 | # from this software without specific prior written permission. | |
23 | # | |
24 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | |
25 | # CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, | |
26 | # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
27 | # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
28 | # DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE | |
29 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, | |
30 | # OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
31 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, | |
32 | # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
33 | # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
34 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
35 | # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
36 | # POSSIBILITY OF SUCH DAMAGE. | |
37 | ||
38 | # usage: [perl] worb[.pl] worb-playfield-file | |
39 | # requirements: ANSI terminal emulation, for animation. | |
40 | ||
41 | # history: v1.0 Jul 5 2000 - original release. | |
42 | # v1.1 Jul 19 2000 - changed + and - | |
43 | # optimized display routine for ANSI | |
44 | # optimized is_bobule_at (cached) | |
45 | # relicensed & released on web site | |
46 | ||
47 | ### GLOBALS ### | |
48 | ||
49 | @bobule = (); | |
50 | @source = (); | |
51 | @sink = (); | |
52 | @playfield = (); | |
53 | ||
54 | @bobule_at_cache = (); | |
55 | ||
56 | $x = 0; $y = 0; | |
57 | ||
58 | ### SUBS ### | |
59 | ||
60 | sub draw_playfield | |
61 | { | |
62 | printf "%c[1;1H", 27; # gotoxy 1,1 | |
63 | my $i; my $j; my $p; | |
64 | for($j = 0; $j <= $maxy; $j++) | |
65 | { | |
66 | for($i = 0; $i <= $maxx; $i++) | |
67 | { | |
68 | if ($p = is_bobule_at($i,$j)) | |
69 | { | |
70 | if ($p == 1) { print '.'; } | |
71 | elsif ($p >= 2 and $p <= 3) { print 'o'; } | |
72 | elsif ($p >= 4 and $p <= 6) { print 'O'; } | |
73 | elsif ($p >= 7 and $p <= 10) { print '0'; } | |
74 | else { print '@'; } | |
75 | } else | |
76 | { | |
77 | print $playfield[$i][$j]; | |
78 | } | |
79 | } | |
80 | print "\n"; | |
81 | } | |
82 | } | |
83 | ||
84 | sub is_bobule_at | |
85 | { | |
86 | my $x = shift; my $y = shift; | |
87 | return $bobule_at_cache[$x][$y] || 0; | |
88 | } | |
89 | ||
90 | sub get_bobule_number_at | |
91 | { | |
92 | my $x = shift; my $y = shift; | |
93 | my $i; | |
94 | for ($i = 0; $i <= $#bobule; $i++) | |
95 | { | |
96 | return $i if $bobule[$i][0] == $x and $bobule[$i][1] == $y; | |
97 | } | |
98 | return undef; | |
99 | } | |
100 | ||
101 | sub vacant | |
102 | { | |
103 | my $x = shift; my $y = shift; | |
104 | return 0 if $playfield[$x][$y] eq '#'; | |
105 | return 0 if is_bobule_at($x,$y); | |
106 | return 1; | |
107 | } | |
108 | ||
109 | ### MAIN ### | |
110 | ||
111 | open PLAYFIELD, $ARGV[0]; | |
112 | while(defined($line = <PLAYFIELD>)) | |
113 | { | |
114 | my $i; | |
115 | chomp($line); | |
116 | for($i = 0; $i < length($line); $i++) | |
117 | { | |
118 | my $c = substr($line, $i, 1); | |
119 | if ($c eq '.') | |
120 | { | |
121 | $c = ' '; | |
122 | push @bobule, [$x, $y, 1]; | |
123 | $bobule_at_cache[$x][$y] = 1; | |
124 | } | |
125 | elsif ($c eq '+') | |
126 | { | |
127 | push @source, [$x, $y]; | |
128 | } | |
129 | elsif ($c eq '-') | |
130 | { | |
131 | push @sink, [$x, $y]; | |
132 | } | |
133 | $playfield[$x][$y] = $c; | |
134 | $x++; if ($x > $maxx) { $maxx = $x; } | |
135 | } | |
136 | $x = 0; | |
137 | $y++; if ($y > $maxy) { $maxy = $y; } | |
138 | } | |
139 | close PLAYFIELD; | |
140 | ||
141 | printf "%c[2J", 27; # clear screen | |
142 | ||
143 | draw_playfield(); | |
144 | ||
145 | $start_time = time(); | |
146 | $tick = 1; | |
147 | while(1) | |
148 | { | |
149 | my $bobule; my $pole; | |
150 | foreach $bobule (@bobule) | |
151 | { | |
152 | $bobule->[2]++; | |
153 | if ($bobule->[2] == 2 or $bobule->[2] == 4 or $bobule->[2] == 7 or $bobule->[2] == 11) | |
154 | { | |
155 | my $p = $bobule->[2]; | |
156 | printf "%c[%d;%dH", 27, $bobule->[1]+1, $bobule->[0]+1; | |
157 | if ($p == 2) { print 'o'; } | |
158 | elsif ($p == 4) { print 'O'; } | |
159 | elsif ($p == 7) { print '0'; } | |
160 | elsif ($p == 11) { print '@'; } | |
161 | } | |
162 | $new_x = $bobule->[0] + int(rand(1) * 3)-1; | |
163 | $new_y = $bobule->[1] + int(rand(1) * 3)-1; | |
164 | next if not vacant($new_x, $new_y); | |
165 | next if $playfield[$new_x][$new_y] eq '<' and $bobule->[0] < $new_x; | |
166 | next if $playfield[$new_x][$new_y] eq '>' and $bobule->[0] > $new_x; | |
167 | next if $playfield[$new_x][$new_y] eq '^' and $bobule->[1] < $new_y; | |
168 | next if $playfield[$new_x][$new_y] eq 'v' and $bobule->[1] > $new_y; | |
169 | next if $new_x == $bobule->[0] and $new_y == $bobule->[1]; | |
170 | print chr(7) if $playfield[$new_x][$new_y] eq '!'; | |
171 | printf "%c[%d;%dH%s", 27, $bobule->[1]+1, $bobule->[0]+1, | |
172 | $playfield[$bobule->[0]][$bobule->[1]]; | |
173 | $bobule_at_cache[$bobule->[0]][$bobule->[1]] = 0; | |
174 | $bobule->[0] = $new_x; | |
175 | $bobule->[1] = $new_y; | |
176 | $bobule_at_cache[$bobule->[0]][$bobule->[1]] = 1; | |
177 | printf "%c[%d;%dH.", 27, $bobule->[1]+1, $bobule->[0]+1; | |
178 | $bobule->[2] = 1; | |
179 | } | |
180 | foreach $pole (@source) | |
181 | { | |
182 | if (not is_bobule_at($pole->[0], $pole->[1]) and rand(1) < .1) | |
183 | { | |
184 | push @bobule, [$pole->[0], $pole->[1], 1]; | |
185 | $bobule_at_cache[$pole->[0]][$pole->[1]] = 1; | |
186 | } | |
187 | } | |
188 | foreach $pole (@sink) | |
189 | { | |
190 | if (is_bobule_at($pole->[0], $pole->[1]) and rand(1) < .1) | |
191 | { | |
192 | my $q = get_bobule_number_at($pole->[0], $pole->[1]); | |
193 | $bobule_at_cache[$pole->[0]][$pole->[1]] = 0; | |
194 | $bobule[$q] = $bobule[$#bobule]; pop @bobule; | |
195 | } | |
196 | } | |
197 | # track_time(); | |
198 | } | |
199 | ||
200 | sub track_time | |
201 | { | |
202 | $tick++; | |
203 | if ($tick > 1000) | |
204 | { | |
205 | $total_time = time() - $start_time; | |
206 | $fps = int(1000 / $total_time); | |
207 | die "Total time: $total_time seconds, approx fps: $fps\n"; | |
208 | } | |
209 | } | |
210 | ||
211 | ### END ### |