Use more general playfield growth detector and limiter.
Chris Pressey
2 months ago
54 | 54 | subPanel.style.opacity = "0.5"; |
55 | 55 | }, |
56 | 56 | onUpdate: function(text) { |
57 | c.setResetState(text); | |
57 | 58 | c.clickReset(text); |
58 | 59 | subPanel.style.pointerEvents = "inherit"; |
59 | 60 | subPanel.style.opacity = "inherit"; |
72 | 73 | panelContainer: subPanel, |
73 | 74 | view: v |
74 | 75 | }); |
76 | ||
77 | function convertControllerToLimiting(controller, getPlayfield) { | |
78 | var originalStep = controller.step; | |
79 | var consecutiveGrowthSteps = 0; | |
80 | var lastPlayfieldSize = null; | |
81 | ||
82 | var originalPerformStart = controller.performStart; | |
83 | controller.performStart = function() { | |
84 | consecutiveGrowthSteps = 0; | |
85 | lastPlayfieldSize = null; | |
86 | originalPerformStart.call(this); | |
87 | }; | |
88 | ||
89 | controller.step = function() { | |
90 | var pf = getPlayfield(this); | |
91 | if (pf) { | |
92 | var currentSize = pf.getCursoredExtentX() * pf.getCursoredExtentY(); | |
93 | if (lastPlayfieldSize !== null) { | |
94 | if (currentSize > lastPlayfieldSize) { | |
95 | consecutiveGrowthSteps++; | |
96 | if (consecutiveGrowthSteps >= 100) { | |
97 | return 'stop'; | |
98 | } | |
99 | } else { | |
100 | consecutiveGrowthSteps = 0; | |
101 | } | |
102 | } | |
103 | lastPlayfieldSize = currentSize; | |
104 | } | |
105 | return originalStep.call(this); | |
106 | }; | |
107 | } | |
108 | ||
109 | convertControllerToLimiting(c, function() { return c.getPlayfield(); }) | |
110 | ||
75 | 111 | c.clickStop(); |
76 | 112 | |
77 | 113 | c.performReset(examplePrograms[0][1]); |
32 | 32 | } |
33 | 33 | this.put(x, y, data); |
34 | 34 | }; |
35 | ||
36 | this.hasActionableSymbolsAhead = function(x, y, dx, dy) { | |
37 | while (true) { | |
38 | var value = this.get(x, y); | |
39 | if (value === '@' || value === '#') { | |
40 | return true; | |
41 | } | |
42 | if (this.minX === undefined || x < this.minX) return false; | |
43 | if (this.maxX === undefined || x > this.maxX) return false; | |
44 | if (this.minY === undefined || y < this.minY) return false; | |
45 | if (this.maxY === undefined || y > this.maxY) return false; | |
46 | x += dx; | |
47 | y += dy; | |
48 | } | |
49 | }; | |
50 | 35 | }; |
51 | 36 | GemooyPlayfield.prototype = new yoob.Playfield(); |
52 | 37 | |
77 | 62 | ctx.fillStyle = cursor.fillStyle || "#50ff50"; |
78 | 63 | ctx.fillRect(canvasX, canvasY, cellWidth, cellHeight); |
79 | 64 | }; |
80 | ||
81 | this.runawayIpCounter = 0; | |
82 | 65 | |
83 | 66 | return this; |
84 | 67 | }; |
115 | 98 | |
116 | 99 | ip.advance(); |
117 | 100 | this.view.draw(); |
118 | ||
119 | if (!p.hasActionableSymbolsAhead(ip.x, ip.y, ip.dx, ip.dy)) { | |
120 | this.runawayIpCounter++; | |
121 | if (this.runawayIpCounter === 10) { | |
122 | return 'stop'; | |
123 | } | |
124 | } else { | |
125 | this.runawayIpCounter = 0; | |
126 | } | |
127 | 101 | }; |
128 | 102 | |
129 | 103 | this.reset = function(text) { |
144 | 118 | ip.dy = 1; |
145 | 119 | this.view.draw(); |
146 | 120 | }; |
121 | ||
122 | this.getPlayfield = function() { | |
123 | return p; | |
124 | }; | |
147 | 125 | }; |
148 | 126 | GemooyController.prototype = proto; |