Libraryless. Click here for Pure Java version (8794L/60K/204K).
1 | !752 |
2 | |
3 | concepts. |
4 | |
5 | sclass TestCase { |
6 | BufferedImage screen; |
7 | Rect boardRect; |
8 | RGBImage board; |
9 | int boardW, boardH; |
10 | |
11 | *() { |
12 | screen = loadBufferedImage("#1006074"); |
13 | boardRect = pointRect(194, 179, 501, 485); |
14 | board = new RGBImage(screen).clip(boardRect); |
15 | boardW = board.w(); |
16 | boardH = board.h(); |
17 | } |
18 | |
19 | Rect square(int x, int y) { |
20 | ret pointsRect( |
21 | boardW*x/8, boardH*y/8, |
22 | boardW*(x+1)/8, boardH*(y+1)/8); |
23 | } |
24 | |
25 | Square realSquareType(int x, int y) { |
26 | ret odd(x*8/boardW + y*8/boardH) ? Square.dark : Square.light; |
27 | } |
28 | |
29 | void showBoard() { |
30 | new L<RGBImage> imgs; |
31 | for y to 8: { |
32 | new L<Rect> l; |
33 | for x to 8: l.add(square(x, y)); |
34 | imgs.add(mergeImagePartsHorizontally(board, l)); |
35 | } |
36 | showImage(mergeImagesVertically(imgs)); |
37 | } |
38 | |
39 | float testFunction(SquareDetector f) { |
40 | int step = 5; // faster |
41 | int n = 0; |
42 | float points = 0; |
43 | for (int y = 0; y < boardH; y++) |
44 | for (int x = 0; x < boardW; x++) { |
45 | ++n; |
46 | Square s = f.squareType(board, x, y); |
47 | Square real = realSquareType(x, y); |
48 | if (s == real) ++points; |
49 | else if (s == Square.unknown) points += 0.1f; |
50 | } |
51 | float score = points*100f/n; |
52 | ret score; |
53 | } |
54 | } |
55 | |
56 | enum Square { light, dark, none, unknown }; |
57 | |
58 | // import static main.Square.*; << stupid Java doesn't want this |
59 | |
60 | sclass SquareDetector { |
61 | Square squareType(RGBImage img, int x, int y) { ret Square.none; } |
62 | } |
63 | |
64 | // dummy reference detector |
65 | sclass AllUnknown extends SquareDetector { |
66 | Square squareType(RGBImage img, int x, int y) { ret Square.unknown; } |
67 | } |
68 | |
69 | sclass Detector1 extends SquareDetector { |
70 | RGB colLight, colDark; |
71 | |
72 | *() {} |
73 | *(RGB *colLight, RGB *colDark) {} |
74 | *(Color colLight, Color colDark) { |
75 | this.colLight = new RGB(colLight); |
76 | this.colDark = new RGB(colDark); |
77 | } |
78 | |
79 | Square squareType(RGBImage img, int x, int y) { |
80 | RGB rgb = img.getPixel(x, y); |
81 | float distLight = simpleRGBDistance(rgb, colLight); |
82 | float distDark = simpleRGBDistance(rgb, colLight); |
83 | ret distLight < distDark ? Square.light : Square.dark; |
84 | } |
85 | } |
86 | |
87 | sclass Detector2 extends SquareDetector { |
88 | RGB colLight, colDark; |
89 | float range = 0.1f; // area around colors that is accepted |
90 | |
91 | *() {} |
92 | *(RGB *colLight, RGB *colDark) {} |
93 | *(Color colLight, Color colDark) { |
94 | this.colLight = new RGB(colLight); |
95 | this.colDark = new RGB(colDark); |
96 | } |
97 | |
98 | Square squareType(RGBImage img, int x, int y) { |
99 | RGB rgb = img.getPixel(x, y); |
100 | float distLight = simpleRGBDistance(rgb, colLight); |
101 | float distDark = simpleRGBDistance(rgb, colLight); |
102 | if (distLight < range) ret Square.light; |
103 | if (distDark < range) ret Square.dark; |
104 | ret Square.unknown; |
105 | } |
106 | } |
107 | |
108 | // modifies specimen, updates best |
109 | svoid optimizeOneField(O tester, O specimen, S field, O varyField, Best<S> best) { |
110 | O varied = callF(varyField, get(specimen, field)); |
111 | set(specimen, field, varied); |
112 | float score = toFloat(callF(tester, specimen)); |
113 | showStatus("Field varied to: " + varied + ", score: " + score + ", best: " + best.bestScore()); |
114 | if (best.isNewBest(score)) { |
115 | S s = structure(specimen); |
116 | best.put(s, score); |
117 | print("New best! " + score + " - " + shorten(s, 1000)); |
118 | } |
119 | } |
120 | |
121 | static volatile S showStatus_status = ""; |
122 | static JLabel showStatus_label; |
123 | |
124 | svoid showStatus(S status) { |
125 | if (showStatus_label == null) awt { |
126 | if (showStatus_label == null) { |
127 | showStatus_label = jlabel(); |
128 | JFrame frame = showPackedFrame(showStatus_label); |
129 | setFrameWidth(frame, 300); |
130 | moveToTopRightCorner(frame); |
131 | installTimer(showStatus_label, 50, r { |
132 | S s = showStatus_status; |
133 | if (neq(s, showStatus_label.getText())) |
134 | showStatus_label.setText(s); |
135 | }); |
136 | } |
137 | } |
138 | showStatus_status = unnull(status); |
139 | } |
140 | |
141 | static RGB replaceColor(RGB color) { |
142 | ret randomColor(); |
143 | } |
144 | |
145 | concept PersistentBest { |
146 | S bestStructure; |
147 | double score; |
148 | transient new Best<S> best; |
149 | |
150 | *() { _doneLoading(); } |
151 | |
152 | void _doneLoading() { |
153 | best.put(bestStructure, score); |
154 | best.onChange = r { |
155 | cset(PersistentBest.this, bestStructure := best.best, score := best.score); |
156 | }; |
157 | } |
158 | |
159 | S get() { ret best.get(); } |
160 | bool has() { ret best.has(); } |
161 | } |
162 | |
163 | p { |
164 | concepts(); |
165 | |
166 | final new TestCase tc; |
167 | //tc.showBoard(); |
168 | tc.testFunction(new AllUnknown); |
169 | Detector1 detector1 = new Detector1(Color.white, Color.black); |
170 | tc.testFunction(detector1); |
171 | |
172 | O tester = func(SquareDetector d) { tc.testFunction(d) }; |
173 | PersistentBest best = uniq(PersistentBest); |
174 | //optimizeOneField(tester, detector1, "colLight", func replaceColor, best); |
175 | Detector2 detector2 = new Detector2(Color.white, Color.black); |
176 | |
177 | // Main loop: Make new random specimen + vary best |
178 | while licensed { |
179 | for (S field : ll("colLight", "colDark")) { |
180 | optimizeOneField(tester, detector2, field, func replaceColor, best.best); |
181 | if (best.has()) |
182 | optimizeOneField(tester, unstructure(best.get()), field, func varyColor, best.best); |
183 | } |
184 | } |
185 | } |
Began life as a copy of #1006083
download show line numbers debug dex old transpilations
Travelled to 15 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, sawdedvomwva, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1006084 |
Snippet name: | Find Chess Board 2 [v4, try function] |
Eternal ID of this version: | #1006084/1 |
Text MD5: | 6ef455bbd5baf127fb275f4317be1229 |
Transpilation MD5: | 82c0794d04af725d46360dbbe705cd37 |
Author: | stefan |
Category: | javax / ocr |
Type: | JavaX source code |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2016-12-17 15:45:53 |
Source code size: | 5152 bytes / 185 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 625 / 802 |
Referenced in: | [show references] |