git @ Cat's Eye Technologies yoob / 5193109
Incorporate Ypsilax and noit o' mnain worb into this repo. Chris Pressey 10 years ago
4 changed file(s) with 921 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
7676 $(CDIR)/snusp/SNUSPState.class \
7777 $(CDIR)/twoill/TwoIllState.class \
7878 $(CDIR)/twol/TwoLState.class \
79 $(CDIR)/wunnel/WunnelState.class
79 $(CDIR)/worb/WorbState.class \
80 $(CDIR)/wunnel/WunnelState.class \
81 $(CDIR)/ypsilax/YpsilaxState.class
8082
8183 all: yoob langs
8284
234236 tc.catseye.yoob.snusp.SNUSPState/SNUSP \
235237 tc.catseye.yoob.twoill.TwoIllState/2-ill \
236238 tc.catseye.yoob.twol.TwoLState/2L \
237 tc.catseye.yoob.wunnel.WunnelState/Wunnel
239 tc.catseye.yoob.worb.WorbState/noit-o-mnain-worb \
240 tc.catseye.yoob.wunnel.WunnelState/Wunnel \
241 tc.catseye.yoob.ypsilax.YpsilaxState/Ypsilax
238242
239243 $(CDIR)/ale/AleState.class: src/lang/AleState.java
240244 $(JAVAC) $(JFLAGS) -cp "$(CLASSPATH)" -d bin src/lang/AleState.java
290294 $(CDIR)/twol/TwoLState.class: src/lang/TwoLState.java
291295 $(JAVAC) $(JFLAGS) -cp "$(CLASSPATH)" -d bin src/lang/TwoLState.java
292296
297 $(CDIR)/worb/WorbState.class: src/lang/WorbState.java
298 $(JAVAC) $(JFLAGS) -cp "$(CLASSPATH)" -d bin src/lang/WorbState.java
299
293300 $(CDIR)/wunnel/WunnelState.class: src/lang/WunnelState.java
294301 $(JAVAC) $(JFLAGS) -cp "$(CLASSPATH)" -d bin src/lang/WunnelState.java
302
303 $(CDIR)/ypsilax/YpsilaxState.class: src/lang/YpsilaxState.java
304 $(JAVAC) $(JFLAGS) -cp "$(CLASSPATH)" -d bin src/lang/YpsilaxState.java
295305
296306 clean:
297307 rm -rf $(CDIR)/*.class
2727 tc.catseye.yoob.snusp.SNUSPState/SNUSP
2828 tc.catseye.yoob.twoill.TwoIllState/2-ill
2929 tc.catseye.yoob.twol.TwoLState/2L
30 tc.catseye.worb.WorbState/noit-o-mnain-worb
30 tc.catseye.yoob.worb.WorbState/noit-o-mnain-worb
3131 tc.catseye.yoob.wunnel.WunnelState/Wunnel
32 tc.catseye.ypsilax.YpsilaxState/Ypsilax">
32 tc.catseye.yoob.ypsilax.YpsilaxState/Ypsilax">
3333 Your browser is ignoring the <applet> tag.
3434 Please consult your browser documentation for how to enable Java applets.
3535 </applet>
0 /*
1 * tc.catseye.worb.WorbState -- noit o'mnain worb for yoob
2 * The source code in this file has been placed into the public domain.
3 */
4
5 /*
6 * A tc.catseye.worb.WorbState implements the semantics of the
7 * noit o'mnain worb automaton under the yoob framework.
8 */
9
10 package tc.catseye.yoob.worb;
11
12 import tc.catseye.yoob.Error;
13 import tc.catseye.yoob.*;
14
15 import java.util.List;
16 import java.util.ArrayList;
17 import java.util.Set;
18 import java.util.HashSet;
19 import java.util.Map;
20 import java.util.HashMap;
21 import java.util.Random;
22 import java.util.Iterator;
23
24
25 class Worb implements Language {
26 public String getName() {
27 return "noit o' mnain worb";
28 }
29
30 public int numPlayfields() {
31 return 1;
32 }
33
34 public int numTapes() {
35 return 0;
36 }
37
38 public boolean hasProgramText() {
39 return false;
40 }
41
42 public boolean hasInput() {
43 return false;
44 }
45
46 public boolean hasOutput() {
47 return false;
48 }
49
50 public List<String> exampleProgramNames() {
51 ArrayList<String> names = new ArrayList<String>();
52 names.add("freefill");
53 names.add("magnetic field");
54 names.add("theory of time");
55 names.add("pressure");
56 names.add("slow loop");
57 names.add("fast loop");
58 names.add("transistor");
59 names.add("or gate");
60 names.add("subtraction");
61 names.add("division");
62 return names;
63 }
64
65 public WorbState loadExampleProgram(int index) {
66 String[][] program = {
67 {
68 /* eg/freefill.worb */
69 "######################",
70 "# #",
71 "# #",
72 "# #",
73 "# #",
74 "# #",
75 "# + #",
76 "# #",
77 "# #",
78 "# #",
79 "# #",
80 "######################",
81 },
82 {
83 /* eg/magnetic-field.worb */
84 "######################",
85 "# #",
86 "# #",
87 "# #",
88 "# #",
89 "# - #",
90 "# + #",
91 "# #",
92 "# #",
93 "# #",
94 "# #",
95 "######################",
96 },
97 {
98 /* eg/theory-of-time.worb */
99 "######################",
100 "#.......... #",
101 "#.......... #",
102 "#.......... #",
103 "#.......... #",
104 "#.......... #",
105 "#.......... #",
106 "#.......... #",
107 "#.......... #",
108 "#.......... #",
109 "#.......... #",
110 "######################",
111 },
112 {
113 /* eg/pressure.worb */
114 "#######################",
115 "#..........> #",
116 "#######################",
117 },
118 {
119 /* eg/slow-loop.worb */
120 "#####################",
121 "# < #",
122 "# ################# #",
123 "# # # #",
124 "# # #.#",
125 "# # # #",
126 "# ################# #",
127 "# > #",
128 "#####################",
129 },
130 {
131 /* eg/fast-loop.worb */
132 "#######",
133 "# < < #",
134 "# ### #",
135 "# >.> #",
136 "#######",
137 },
138 {
139 /* eg/transistor.worb */
140 " ###",
141 "### #+#",
142 "#+# # #",
143 "# ###v#",
144 "# < #",
145 "### < #",
146 " # < #",
147 " ###v#",
148 " # #",
149 " #!#",
150 " #-#",
151 " ###",
152 "",
153 },
154 {
155 /* eg/or-gate.worb */
156 "##### #####",
157 "# ########### #",
158 "# . > < . #",
159 "# #####v##### #",
160 "##### # ########",
161 " # >!#",
162 " #v#########",
163 " # #",
164 " ###",
165 },
166 {
167 /* eg/subtraction.worb */
168 "###############",
169 "#.............#",
170 "#######v#######",
171 " # #",
172 " #########",
173 "",
174 },
175 {
176 /* eg/division.worb */
177 "############",
178 "#..........#",
179 "#######v####",
180 " # #",
181 " #v####",
182 " # #",
183 " #v####",
184 " # #",
185 " #v####",
186 " # #",
187 " ######",
188 },
189 };
190 WorbState s = new WorbState();
191 s.playfield.load(program[index]);
192 return s;
193 }
194
195 public List<String> getAvailableOptionNames() {
196 ArrayList<String> names = new ArrayList<String>();
197 return names;
198 }
199
200 public WorbState importFromText(String text) {
201 WorbState s = new WorbState();
202 s.playfield.load(text.split("\\r?\\n"));
203 return s;
204 }
205
206 private static final String[][] properties = {
207 {"Author", "Chris Pressey"},
208 {"Implementer", "Chris Pressey"},
209 {"Implementation notes",
210 "None yet."}
211 };
212
213 public String[][] getProperties() {
214 return properties;
215 }
216 }
217
218 class Bobule implements Element {
219 int pressure;
220
221 public Bobule() {
222 pressure = 1;
223 }
224
225 public String getName() {
226 if (pressure == 1)
227 return ".";
228 if (pressure >= 2 && pressure <= 3)
229 return "o";
230 if (pressure >= 4 && pressure <= 6)
231 return "O";
232 return "@";
233 }
234
235 public boolean equals(Element e) {
236 return e instanceof Bobule; // a bobule is a bobule is a bobule!
237 }
238
239 public Bobule fromChar(char c) {
240 return new Bobule();
241 }
242 }
243
244 class WorbPlayfield extends BasicPlayfield<Element> {
245 protected HashMap<Position, Bobule> bobuleMap;
246 private Random rand;
247
248 public WorbPlayfield() {
249 super(new CharacterElement(' '));
250 bobuleMap = new HashMap<Position, Bobule>();
251 rand = new Random();
252 }
253
254 public WorbPlayfield clone() {
255 WorbPlayfield c = new WorbPlayfield();
256 c.copyBackingStoreFrom(this);
257 c.bobuleMap = new HashMap<Position, Bobule>(
258 (Map<Position, Bobule>)this.bobuleMap
259 );
260 return c;
261 }
262
263 public Element get(IntegerElement x, IntegerElement y) {
264 Bobule bobule = bobuleMap.get(new Position(x, y));
265 return (bobule == null) ? getBackground(x, y) : bobule;
266 }
267
268 public CharacterElement getBackground(IntegerElement x, IntegerElement y) {
269 return (CharacterElement)super.get(x, y);
270 }
271
272 public void step() {
273 Set<Position> bobulePositions = new HashSet<Position>(bobuleMap.keySet());
274 Iterator<Position> it = bobulePositions.iterator();
275
276 while (it.hasNext()) {
277 Position p = it.next();
278 Bobule b = bobuleMap.get(p);
279
280 b.pressure++;
281 IntegerElement new_x = p.getX().add(new IntegerElement(rand.nextInt(3) - 1));
282 IntegerElement new_y = p.getY().add(new IntegerElement(rand.nextInt(3) - 1));
283 Element e = get(new_x, new_y);
284 if (e instanceof Bobule) {
285 continue;
286 } else if (e instanceof CharacterElement) {
287 char c = ((CharacterElement)e).getChar();
288 if (c == '#')
289 continue;
290 if (c == '<' && p.getX().compareTo(new_x) < 0)
291 continue;
292 if (c == '>' && p.getX().compareTo(new_x) > 0)
293 continue;
294 if (c == '^' && p.getY().compareTo(new_y) < 0)
295 continue;
296 if (c == 'v' && p.getY().compareTo(new_y) > 0)
297 continue;
298 // print chr(7) if $playfield[$new_x][$new_y] eq '!';
299 } else {
300 // No other possibilities
301 }
302 bobuleMap.remove(p);
303 b.pressure = 1;
304 bobuleMap.put(new Position(new_x, new_y), b);
305 }
306
307 Iterator<Map.Entry<Position, Element>> cit = store.entrySet().iterator();
308 while (cit.hasNext()) {
309 Map.Entry<Position, Element> entry = cit.next();
310 Position p = entry.getKey();
311 char c = ((CharacterElement)entry.getValue()).getChar();
312
313 if (c == '+') {
314 Bobule b = bobuleMap.get(p);
315 if (b == null && rand.nextInt(10) == 0) {
316 b = new Bobule();
317 bobuleMap.put(p, b);
318 }
319 } else if (c == '-') {
320 Bobule b = bobuleMap.get(p);
321 if (b != null && rand.nextInt(10) == 0) {
322 bobuleMap.remove(p);
323 }
324 }
325 }
326 }
327
328 public void loadChar(int x, int y, char c) {
329 if (c == '.') {
330 bobuleMap.put(new Position(x, y), new Bobule());
331 } else {
332 set(x, y, new CharacterElement(c));
333 }
334 }
335
336 }
337
338 public class WorbState implements tc.catseye.yoob.State {
339 protected WorbPlayfield playfield;
340 protected BasicPlayfieldView view;
341 private static final Worb language = new Worb();
342
343 public WorbState() {
344 playfield = new WorbPlayfield();
345 view = new BasicPlayfieldView();
346 }
347
348 public WorbState clone() {
349 WorbState c = new WorbState();
350 c.playfield = this.playfield.clone();
351 return c;
352 }
353
354 public Language getLanguage() {
355 return language;
356 }
357
358 public List<Error> step(World world) {
359 ArrayList<Error> errors = new ArrayList<Error>();
360 playfield.step();
361 return errors;
362 }
363
364 public Playfield getPlayfield(int index) {
365 return playfield;
366 }
367
368 public Tape getTape(int index) {
369 return null;
370 }
371
372 public String getProgramText() {
373 return "";
374 }
375
376 public int getProgramPosition() {
377 return 0;
378 }
379
380 public List<Error> setProgramText(String text) {
381 ArrayList<Error> errors = new ArrayList<Error>();
382 return errors;
383 }
384
385 public View getPlayfieldView(int index) {
386 return view;
387 }
388
389 public View getTapeView(int index) {
390 return null;
391 }
392
393 public String exportToText() {
394 return playfield.dump();
395 }
396
397 public void setOption(String name, boolean value) {
398 }
399
400 public boolean needsInput() {
401 return false;
402 }
403
404 public boolean hasHalted() {
405 return false;
406 }
407 }
0 /*
1 * tc.catseye.worb.YpsilaxState -- Ypsilax for yoob
2 * The source code in this file has been placed into the public domain.
3 */
4
5 /*
6 * A tc.catseye.worb.YpsilaxState tries to implement the semantics of the
7 * Ypsilax grid-rewriter, for running under the yoob framework.
8 */
9
10 package tc.catseye.yoob.ypsilax;
11
12 import tc.catseye.yoob.Error;
13 import tc.catseye.yoob.*;
14
15 import java.util.List;
16 import java.util.ArrayList;
17 import java.util.Set;
18 import java.util.HashSet;
19 import java.util.Map;
20 import java.util.HashMap;
21 import java.util.Random;
22 import java.util.Iterator;
23
24
25 class Ypsilax implements Language {
26 public String getName() {
27 return "Ypsilax";
28 }
29
30 public int numPlayfields() {
31 return 1;
32 }
33
34 public int numTapes() {
35 return 0;
36 }
37
38 public boolean hasProgramText() {
39 return false;
40 }
41
42 public boolean hasInput() {
43 return false;
44 }
45
46 public boolean hasOutput() {
47 return false;
48 }
49
50 public List<String> exampleProgramNames() {
51 ArrayList<String> names = new ArrayList<String>();
52 names.add("transform it");
53 names.add("classic example");
54 names.add("abracadabra");
55 names.add("escaped");
56 names.add("multisymbol pattern");
57 names.add("grow tape");
58 names.add("wildcard");
59 //names.add("higher-order");
60 names.add("self-modifying");
61 return names;
62 }
63
64 public YpsilaxState loadExampleProgram(int index) {
65 String[][] program = {
66 {
67 "DDDD",
68 "",
69 "( )",
70 " D* ",
71 "",
72 "DDDD",
73 },
74 {
75 "( ) ( )",
76 " # #",
77 " # ### ### #",
78 " # #",
79 "",
80 " ### ###",
81 "",
82 " # #",
83 " # #",
84 " # ###",
85 },
86 {
87 "( ) ( )",
88 " AB BA",
89 "ABRACADABRA",
90 },
91 {
92 "* ",
93 "( ) ( )",
94 " AB BA",
95 "ABRACADABRA",
96 },
97 {
98 "( )",
99 " ABBA",
100 " ^^ ",
101 "ABRACADABRA",
102 "^^^^^^^^^^^",
103 },
104 {
105 "( )",
106 " > -> ",
107 " > -> ",
108 " > -> ",
109 "",
110 "---->",
111 "---->",
112 "---->",
113 },
114 {
115 "( ?)",
116 " A?AX",
117 "",
118 "ABRACADABRA",
119 "",
120 "...........",
121 },/*
122 {
123 "( ?) ",
124 "",
125 "",
126 " ? ?",
127 " ----( )",
128 "",
129 "",
130 "",
131 " -------------",
132 " ABRACADABRA",
133 "",
134 "",
135 " ABRACADABRA",
136 },*/
137 {
138 "(X X ) (X X )",
139 " ( )( ) ( )( )",
140 " AB BA BA AB",
141 "",
142 "",
143 " ( )",
144 " AB",
145 "",
146 "",
147 " ABRACADABRA",
148 },
149 };
150 YpsilaxState s = new YpsilaxState();
151 s.playfield.load(program[index]);
152 return s;
153 }
154
155 public YpsilaxState importFromText(String text) {
156 YpsilaxState s = new YpsilaxState();
157 s.playfield.load(text.split("\\r?\\n"));
158 return s;
159 }
160
161 public List<String> getAvailableOptionNames() {
162 ArrayList<String> names = new ArrayList<String>();
163 return names;
164 }
165
166 private static final String[][] properties = {
167 {"Author", "Chris Pressey"},
168 {"Implementer", "Chris Pressey"},
169 {"Implementation notes",
170 "In this version, patterns detected in the playfield are always within the " +
171 "current bounds of the playfield; in other words, even if the pattern contains " +
172 "spaces or wildcards, it will not match the assumed-empty space surrounding " +
173 "the defined part of the playfield."},
174 };
175
176 public String[][] getProperties() {
177 return properties;
178 }
179
180 }
181
182 class Rule extends OverlayPlayfield<CharacterElement> {
183 private IntegerElement width, height;
184 private CharacterElement wildcard;
185 private static final IntegerElement TWO = new IntegerElement(2);
186
187 public Rule(Playfield<CharacterElement> p, IntegerElement x, IntegerElement y,
188 IntegerElement width, CharacterElement wildcard) {
189 super(p, x, y, width, width.divide(TWO));
190 this.width = width;
191 this.height = width.divide(TWO);
192 this.wildcard = wildcard;
193 }
194
195 public Rule(Playfield<CharacterElement> p, IntegerElement x, IntegerElement y,
196 IntegerElement width, IntegerElement height, CharacterElement wildcard) {
197 super(p, x, y, width, height);
198 this.width = width;
199 this.height = height;
200 this.wildcard = wildcard;
201 }
202
203 public Rule createMatchSubject() {
204 return new Rule(getPlayfield(), getOffsetX(), getOffsetY(),
205 getHeight(), getHeight(), getWildcard());
206 }
207
208 public IntegerElement getWidth() {
209 return width;
210 }
211
212 public IntegerElement getHeight() {
213 return height;
214 }
215
216 public CharacterElement getWildcard() {
217 return wildcard;
218 }
219
220 // This should be a method on a Dumper object which takes a Codec.
221 public String dump() {
222 IntegerElement min_x = getMinX();
223 IntegerElement min_y = getMinY();
224 IntegerElement max_x = getMaxX();
225 IntegerElement max_y = getMaxY();
226 IntegerElement x = min_x;
227 IntegerElement y = min_y;
228 StringBuffer buf = new StringBuffer();
229
230 //System.out.println("(" + getOffsetX() + "," + getOffsetY() + ")_(" + width + "x" + height + ")");
231 while (y.compareTo(max_y) <= 0) {
232 x = min_x;
233 while (x.compareTo(max_x) <= 0) {
234 CharacterElement e = get(x, y);
235 buf.append(dumpElement(e));
236 x = x.succ();
237 }
238 y = y.succ();
239 buf.append("\n");
240 }
241
242 return buf.toString();
243 }
244
245 public String dumpElement(CharacterElement e) {
246 return e.getName();
247 }
248 }
249
250 class WildcardMatcher implements Matcher<CharacterElement,CharacterElement> {
251 private CharacterElement wildcard;
252
253 public WildcardMatcher(CharacterElement wildcard) {
254 this.wildcard = wildcard;
255 }
256
257 public boolean match(CharacterElement sought, CharacterElement candidate) {
258 if (wildcard != null && sought.getChar() == wildcard.getChar()) {
259 return true;
260 }
261 return candidate.equals(sought);
262 }
263 }
264
265 class PlayfieldMatcher<E extends Element> {
266 public boolean isMatchAt(Playfield<E> haystack, Playfield<E> needle, Matcher<E,E> m, IntegerElement x, IntegerElement y) {
267 IntegerElement width = needle.getMaxX().subtract(needle.getMinX()).succ();
268 IntegerElement height = needle.getMaxY().subtract(needle.getMinY()).succ();
269
270 if (x.pred().add(width).compareTo(haystack.getMaxX()) > 0 ||
271 y.pred().add(height).compareTo(haystack.getMaxY()) > 0) {
272 // exceeds the right or bottom edge, so, no
273 return false;
274 }
275 IntegerElement cx, cy, dx, dy;
276 for (cx = x, dx = needle.getMinX();
277 dx.compareTo(needle.getMaxX()) <= 0;
278 cx = cx.succ(), dx = dx.succ()) {
279 for (cy = y, dy = needle.getMinY();
280 dy.compareTo(needle.getMinY()) <= 0;
281 cy = cy.succ(), dy = dy.succ()) {
282 E soughtElem = needle.get(dx, dy);
283 E foundElem = haystack.get(cx, cy);
284 //System.out.printf("sought (%s,%s): '%s', found (%s,%s): '%s'\n",
285 // dx, dy, soughtElem.getName(),
286 // cx, cy, foundElem.getName());
287 if (m.match(soughtElem, foundElem)) {
288 // add something to the result-list
289 } else {
290 return false;
291 }
292 }
293 }
294 return true;
295 }
296
297 public Set<Position> getAllMatches(Playfield<E> haystack, Playfield<E> needle, Matcher<E,E> matcher) {
298 Set<Position> results = new HashSet<Position>();
299
300 IntegerElement haystackWidth = haystack.getMaxX().subtract(haystack.getMinX()).succ();
301 IntegerElement haystackHeight = haystack.getMaxY().subtract(haystack.getMinY()).succ();
302 IntegerElement needleWidth = needle.getMaxX().subtract(needle.getMinX()).succ();
303 IntegerElement needleHeight = needle.getMaxY().subtract(needle.getMinY()).succ();
304
305 if (needleWidth.compareTo(haystackWidth) > 0 || needleHeight.compareTo(haystackHeight) > 0) {
306 // thing being sought is larger than the thing seeking in, so, no
307 return results;
308 }
309
310 IntegerElement xSpan = haystackWidth.subtract(needleWidth).succ();
311 IntegerElement ySpan = haystackHeight.subtract(needleHeight).succ();
312
313 IntegerElement x, y;
314 for (x = IntegerElement.ZERO; x.compareTo(xSpan) < 0; x = x.succ()) {
315 for (y = IntegerElement.ZERO; y.compareTo(ySpan) < 0; y = y.succ()) {
316 if (isMatchAt(haystack, needle, matcher, x, y)) {
317 results.add(new Position(x, y));
318 } else {
319 }
320 }
321 }
322 return results;
323 }
324 }
325
326 class YpsilaxPlayfield extends BasicPlayfield<CharacterElement> {
327 public YpsilaxPlayfield() {
328 super(new CharacterElement(' '));
329 }
330
331 public YpsilaxPlayfield clone() {
332 YpsilaxPlayfield c = new YpsilaxPlayfield();
333 c.copyBackingStoreFrom(this);
334 return c;
335 }
336
337 public List<Position> match(YpsilaxPlayfield pattern) {
338 return null;
339 }
340
341 public List<Rule> findAllRules() {
342 IntegerElement x, y;
343 ArrayList<Rule> rules = new ArrayList<Rule>();
344
345 for (x = (IntegerElement)getMinX(); x.compareTo(getMaxX()) <= 0; x = x.succ()) {
346 for (y = (IntegerElement)getMinY(); y.compareTo(getMaxY()) <= 0; y = y.succ()) {
347 boolean escaped = (!y.isZero() && get(x, y.pred()).getChar() != ' ');
348 if (escaped) continue;
349 if (get(x, y).getChar() == '(') {
350 //System.out.println("Found a rule start at " + x + ", " + y);
351 IntegerElement x2 = x;
352 CharacterElement g = get(x2, y);
353 while (g.getChar() != ')' && x2.compareTo(getMaxX()) <= 0) {
354 x2 = x2.succ();
355 g = get(x2, y);
356 }
357 if (g.getChar() != ')') continue;
358 //System.out.println("Found a rule from " + x + "," + y + " to " + x2);
359 CharacterElement w = get(x2.pred(), y);
360 if (w.getChar() == ' ') w = null;
361 Rule r = new Rule(this, x.succ(), y.succ(), (x2.subtract(x)).pred(), w);
362 rules.add(r);
363 }
364 }
365 }
366
367 return rules;
368 }
369
370 public List<Position> findAllRuleMatches(Rule r) {
371 //System.out.printf("%s", r.dump());
372 WildcardMatcher matcher = new WildcardMatcher(r.getWildcard());
373 PlayfieldMatcher<CharacterElement> pm = new PlayfieldMatcher<CharacterElement>();
374 List<Position> positions = new ArrayList<Position>();
375 // We only want to match the LEFT side of the rule, so we do this:
376 Rule matchSubject = r.createMatchSubject();
377 for (Position p : pm.getAllMatches(this, matchSubject, matcher)) {
378 // System.out.println("CONSIDERING (" + p.getX() + "," + p.getY() + ")");
379 // Discard all the ones that are at or above the rule
380 if (p.getY().compareTo(r.getOffsetY().add(r.getHeight())) >= 0) {
381 //System.out.println("(" + p.getX() + "," + p.getY() + ")..." + r.getOffsetY());
382 positions.add(p);
383 }
384 }
385 //System.out.println("---");
386 return positions;
387 }
388
389 /*
390 * We assume a match was made at the given position.
391 */
392 public void applyRule(Rule r, Position p) {
393 IntegerElement i, j;
394
395 CharacterElement wildcard = r.getWildcard();
396 //System.out.printf("applying at %s: %s", p.toString(), r.dump());
397 /* Note that r.getHeight() == width/2 ... */
398 for(i = IntegerElement.ZERO; i.compareTo(r.getHeight()) < 0; i = i.succ()) {
399 for(j = IntegerElement.ZERO; j.compareTo(r.getHeight()) < 0; j = j.succ()) {
400 CharacterElement replacement = r.get(i.add(r.getHeight()), j);
401 IntegerElement destX = p.getX().add(i);
402 IntegerElement destY = p.getY().add(j);
403 //System.out.printf("(%s,%s): [%s] '%s' -> (%s,%s)\n", i, j, wildcard, replacement.getChar(), destX, destY);
404 if (wildcard == null || wildcard.getChar() != replacement.getChar()) {
405 set(destX, destY, replacement);
406 }
407 }
408 }
409 }
410 }
411
412 public class YpsilaxState implements tc.catseye.yoob.State {
413 protected YpsilaxPlayfield playfield;
414 protected BasicPlayfieldView view;
415 private Random rand;
416 private static final Ypsilax language = new Ypsilax();
417 private boolean halted = false;
418
419 public YpsilaxState() {
420 playfield = new YpsilaxPlayfield();
421 view = new BasicPlayfieldView();
422 rand = new Random();
423 }
424
425 public YpsilaxState clone() {
426 YpsilaxState c = new YpsilaxState();
427 c.playfield = this.playfield.clone();
428 return c;
429 }
430
431 public Language getLanguage() {
432 return language;
433 }
434
435 public List<Error> step(World world) {
436 ArrayList<Error> errors = new ArrayList<Error>();
437 List<Rule> rules = playfield.findAllRules();
438 if (rules.size() == 0) {
439 // no sense continuing. halt.
440 halted = true;
441 return errors;
442 }
443 //System.out.println("rules: " + rules.size());
444 Rule r = rules.get(rand.nextInt(rules.size()));
445 List<Position> positions = playfield.findAllRuleMatches(r);
446 //System.out.println("matches: " + positions.size());
447 if (positions.size() > 0) {
448 Position p = positions.get(rand.nextInt(positions.size()));
449 playfield.applyRule(r, p);
450 }
451 return errors;
452 }
453
454 public Playfield getPlayfield(int index) {
455 return playfield;
456 }
457
458 public Tape getTape(int index) {
459 return null;
460 }
461
462 public String getProgramText() {
463 return "";
464 }
465
466 public int getProgramPosition() {
467 return 0;
468 }
469
470 public List<Error> setProgramText(String text) {
471 ArrayList<Error> errors = new ArrayList<Error>();
472 return errors;
473 }
474
475 public View getPlayfieldView(int index) {
476 return view;
477 }
478
479 public View getTapeView(int index) {
480 return null;
481 }
482
483 public void setOption(String name, boolean value) {
484 }
485
486 public String exportToText() {
487 return playfield.dump();
488 }
489
490 public boolean needsInput() {
491 return false;
492 }
493
494 public boolean hasHalted() {
495 return halted;
496 }
497 }
498