Uses 3874K of libraries. Click here for Pure Java version (9132L/64K/224K).
1 | !7 |
2 | |
3 | static int lineWidth = 13; |
4 | static int lines = 2; |
5 | sS font = /*#1004568*/#1004970; |
6 | sbool oldVaryLine = false; |
7 | |
8 | !include #1006931 // AI Game & API |
9 | |
10 | p { |
11 | newImageText = "New Letter!"; |
12 | makeInstruction(); |
13 | pGame(); |
14 | swing { |
15 | setFrameTitle(is, "A. I. Game 5.2"); |
16 | final JSpinner spinner = jSpinner(lines, 1, 100); |
17 | addToWindowPack(is, withMargin(jRightAligned(withLabel("Number of lines to use:", spinner)))); |
18 | onChange(spinner, r { |
19 | lines = intFromSpinner(spinner); |
20 | makeInstruction(); |
21 | restartAIs(); |
22 | }); |
23 | } |
24 | } |
25 | |
26 | svoid makeInstruction { |
27 | setInstruction("Reproduce this image with " + n(lines, "curved line") + ":"); |
28 | } |
29 | |
30 | sclass Curve { |
31 | Pt a, b, c; // b = control point for curve |
32 | |
33 | *() {} |
34 | *(Pt *a, Pt *b, Pt *c) {} |
35 | |
36 | Pt realb() { |
37 | ret un_closerControlPoint(a, b, c); |
38 | } |
39 | } |
40 | |
41 | sclass Submission { |
42 | new L<Curve> lines; |
43 | |
44 | *() {} |
45 | *(Curve... lines) { this.lines = asList(lines); check(); } |
46 | *(L<Curve> *lines) { check(); } |
47 | |
48 | void check { |
49 | assertEquals(main.lines, l(lines)); |
50 | } |
51 | } |
52 | |
53 | ////////////////// |
54 | // PUZZLE MAKER // |
55 | ////////////////// |
56 | |
57 | sS lastLetter; |
58 | |
59 | static RGBImage makeImage() { |
60 | S letter; |
61 | S choice = charRange('A', 'Z') + charRange('0', '9'); |
62 | do { |
63 | letter = "" + oneOf(choice); |
64 | } while (eq(letter, lastLetter)); |
65 | lastLetter = letter; |
66 | aiTitle = letter + "/" + lines; |
67 | ret rgbWhiteBorder(10, rgbAutoCrop(new RGBImage(renderText(font, 100, letter)))); |
68 | } |
69 | |
70 | ////////////////////// |
71 | // FORM MAKER (NONE // |
72 | ////////////////////// |
73 | |
74 | static JComponent makeTheForm(final GameForAI game) { null; } |
75 | |
76 | /////////////// |
77 | // RENDERERS // |
78 | /////////////// |
79 | |
80 | static RGBImage renderImage(Submission s) { |
81 | ret new RGBImage(renderImage1(s)); |
82 | } |
83 | |
84 | static BufferedImage renderImage1(Submission s) { |
85 | BufferedImage bi = newBufferedImage(w, h, Color.white); |
86 | for (Curve l : s.lines) |
87 | drawRoundEdgeCurve(bi, l.a, l.realb(), l.c, Color.black, lineWidth); |
88 | ret bi; |
89 | } |
90 | |
91 | static RGBImage renderWithHints(Submission s) { |
92 | //BufferedImage bi = renderImage1(s); |
93 | BufferedImage bi = newBufferedImage(w, h, Color.white); |
94 | int n = 0; |
95 | for (Curve l : s.lines) |
96 | drawRoundEdgeCurve(bi, l.a, l.realb(), l.c, rainbowColor(n++, l(s.lines)), lineWidth); |
97 | RGBImage img = new RGBImage(bi); |
98 | for (Curve l : s.lines) { |
99 | rgbMarkPoints(img, Color.lightGray, 1, l.a, l.c); |
100 | Pt control = l.b; // closerControlPoint(l.a, l.b, l.c); |
101 | rgbMarkPoints(img, Color.red, 1, control); // control point in red |
102 | } |
103 | ret rgbUncache(img); |
104 | } |
105 | |
106 | ////////////////////////////////////// |
107 | // Test AIs. Just add your own here // |
108 | ////////////////////////////////////// |
109 | |
110 | AI > AI_Random { |
111 | new Best<Submission> best; |
112 | |
113 | Curve randomLine() { |
114 | ret new Curve(randomPoint(), randomPoint(), randomPoint()); |
115 | } |
116 | |
117 | Pt randomPoint() { ret main.randomPoint(image()); } |
118 | |
119 | void go { |
120 | //print("Round: " + round()); |
121 | if (round() == 1 && best.has()) |
122 | submit(best.get()); |
123 | else { |
124 | Submission guess = guess(); |
125 | updateBest(guess, submit(guess)); |
126 | } |
127 | } |
128 | |
129 | bool updateBest(Submission guess, double score) { |
130 | ret best.put(guess, score); |
131 | } |
132 | |
133 | Submission guess() { |
134 | ret new Submission(produceN(func { randomLine() }, lines)); |
135 | } |
136 | } |
137 | |
138 | AI_Random > AI_RandomWithVariation { |
139 | int n; |
140 | |
141 | Submission guess() { |
142 | if (odd(n++) && best.has()) |
143 | ret vary(best.get()); |
144 | else |
145 | ret super.guess(); |
146 | } |
147 | |
148 | Submission vary(Submission s) { |
149 | s = cloneThroughStructure(s); |
150 | varyLine(random(s.lines)); |
151 | ret s; |
152 | } |
153 | |
154 | void varyLine(Curve l) { |
155 | if (oldVaryLine) |
156 | switch (random(3)) { |
157 | case 0: l.a = varyPoint(l.a); |
158 | case 1: l.b = varyPoint(l.b); |
159 | case 2: l.c = varyPoint(l.c); |
160 | } |
161 | else if (oneIn(3)) |
162 | switch (random(3)) { |
163 | case 0: l.a = randomPoint(); |
164 | case 1: l.b = randomPoint(); |
165 | case 2: l.c = randomPoint(); |
166 | } |
167 | else { |
168 | l.a = varyPoint2(l.a); |
169 | l.b = varyPoint2(l.b); |
170 | l.c = varyPoint2(l.c); |
171 | } |
172 | } |
173 | |
174 | Pt varyPoint(Pt p) { |
175 | ret tossACoin() ? randomPoint() : varyPoint(p, 10); |
176 | } |
177 | |
178 | Pt varyPoint2(Pt p) { |
179 | ret varyPoint(p, 10); |
180 | } |
181 | |
182 | Pt varyPoint(Pt p, int range) { |
183 | range = max(range, 1); |
184 | ret new Pt( |
185 | random(p.x-range, p.x+range+1), |
186 | random(p.y-range, p.y+range+1)); |
187 | } |
188 | } |
189 | |
190 | AI > AI_Racer { |
191 | AI_RandomWithVariation leader, overtaker; |
192 | new Best<Submission> leadersBest; |
193 | int discardEvery = 2500; |
194 | int roundsSinceChange; |
195 | static ImageSurface is; |
196 | |
197 | AI_RandomWithVariation newAI() { ret new AI_RandomWithVariation; } |
198 | |
199 | void go { |
200 | if (round() == 1 && leadersBest.has()) |
201 | submit(leadersBest.get()); |
202 | else if (tossACoin()) { |
203 | if (leader == null) leader = newAI(); |
204 | initSubAI(leader); |
205 | Submission guess = leader.guess(); |
206 | double score = submit(guess); |
207 | leader.updateBest(guess, score); |
208 | leadersBest.put(guess, score); |
209 | } else { |
210 | if (overtaker == null) overtaker = newAI(); |
211 | initSubAI(overtaker); |
212 | Submission guess = overtaker.guess(); |
213 | double score = submit(guess); |
214 | if (overtaker.updateBest(guess, score)) { |
215 | int percent = toIntPercent(score/leader.best.score()); |
216 | S title = percent + "% Challenger"; |
217 | bool first = is == null; |
218 | is = showZoomedImage_centered(is, title, renderWithHints(guess)); |
219 | if (first) { |
220 | setFrameWidth(is, 250); |
221 | moveToTopRightCorner(is); |
222 | moveFrameDown(is, 300); |
223 | } |
224 | } |
225 | if (score > leadersBest.score()) { |
226 | // displace leader! |
227 | print("Overtake at " + formatScore(overtaker.best.score()) + " vs " + formatScore(leadersBest.score())); |
228 | leader = overtaker; |
229 | overtaker = null; |
230 | roundsSinceChange = 0; |
231 | } else if (roundsSinceChange++ >= discardEvery) { |
232 | // make new overtaker |
233 | print("Discarding overtaker at " + formatScore(overtaker.best.score()) + " vs " + formatScore(leadersBest.score())); |
234 | overtaker = null; |
235 | roundsSinceChange = 0; |
236 | } |
237 | } |
238 | } |
239 | } |
Began life as a copy of #1006945
download show line numbers debug dex old transpilations
Travelled to 14 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt, wtqryiryparv
No comments. add comment
Snippet ID: | #1006960 |
Snippet name: | A. I. Game 5.2 / Curved Letters [works] |
Eternal ID of this version: | #1006960/37 |
Text MD5: | c607e9356d5051c93b1872de95dc154e |
Transpilation MD5: | 6dbf5735f8e546b08e226913b81d5821 |
Author: | stefan |
Category: | javax / gui / a.i. |
Type: | JavaX source code |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2017-02-23 10:15:25 |
Source code size: | 6197 bytes / 239 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 502 / 757 |
Version history: | 36 change(s) |
Referenced in: | [show references] |