WPBDC 2013.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ext/WPBDC/WPBDC.c +237 -0
- data/ext/WPBDC/analysis.c +672 -0
- data/ext/WPBDC/bridge.c +288 -0
- data/ext/WPBDC/bridge_cost.c +60 -0
- data/ext/WPBDC/bridge_hash.c +126 -0
- data/ext/WPBDC/bridge_parser.c +1119 -0
- data/ext/WPBDC/bridge_random.c +292 -0
- data/ext/WPBDC/bridge_sketch.c +125 -0
- data/ext/WPBDC/extconf.rb +5 -0
- data/ext/WPBDC/geometry.c +46 -0
- data/ext/WPBDC/internal.h +518 -0
- data/ext/WPBDC/judge.c +563 -0
- data/ext/WPBDC/judge.h +142 -0
- data/ext/WPBDC/loading.c +128 -0
- data/ext/WPBDC/params.c +166 -0
- data/ext/WPBDC/proto.h +98 -0
- data/ext/WPBDC/rc4.c +62 -0
- data/ext/WPBDC/rc4.h +19 -0
- data/ext/WPBDC/rc4_key.c +2 -0
- data/ext/WPBDC/rubydefs.h +75 -0
- data/ext/WPBDC/scenario.c +671 -0
- data/ext/WPBDC/sketch.c +496 -0
- data/ext/WPBDC/sketch.h +51 -0
- data/ext/WPBDC/stdafx.h +11 -0
- data/lib/WPBDC.rb +9 -0
- metadata +71 -0
data/ext/WPBDC/judge.c
ADDED
@@ -0,0 +1,563 @@
|
|
1
|
+
/*
|
2
|
+
*
|
3
|
+
* judge.c -- Ruby Extension WPBDC. Support for the West Point
|
4
|
+
* Bridge Design Contest web site. Ruby-visible constants
|
5
|
+
* and functions.
|
6
|
+
*
|
7
|
+
* Hashing code assumes unsigned int is 32 bits, but should otherwise be portable.
|
8
|
+
*
|
9
|
+
* This compiles judges for V3, V4 and V4 (contest) of the WPBD
|
10
|
+
* according to compile time constants.
|
11
|
+
* The corresponding values of BD_VERSION are:
|
12
|
+
* V3 => 0x300
|
13
|
+
* V4 => 0x400
|
14
|
+
* V4 (2002 contest) => 0x402c
|
15
|
+
* V4 (2003 contest) => 0x403c
|
16
|
+
* V4 (2004 contest) => 0x404c
|
17
|
+
* etc.
|
18
|
+
*/
|
19
|
+
|
20
|
+
#include "stdafx.h"
|
21
|
+
|
22
|
+
// Constants and data structures Ruby does not need to know about.
|
23
|
+
#include "internal.h"
|
24
|
+
|
25
|
+
// External interface.
|
26
|
+
#include "judge.h"
|
27
|
+
|
28
|
+
#if BD_VERSION != 0x412c
|
29
|
+
#error Wrong BD_VERSION. Should be 0x412c.
|
30
|
+
#endif
|
31
|
+
|
32
|
+
// Extension stubs --------------------------------------------------------------
|
33
|
+
|
34
|
+
// These are the routines called by the Ruby interface code.
|
35
|
+
|
36
|
+
void endecrypt(STRING *bridge_as_string)
|
37
|
+
{
|
38
|
+
endecrypt_in_place(bridge_as_string->ptr, bridge_as_string->size);
|
39
|
+
}
|
40
|
+
|
41
|
+
// Parse bridge as string.
|
42
|
+
// Return a result struct that describes what happened.
|
43
|
+
void analyze(STRING *bridge_as_string, struct analysis_result_t *result)
|
44
|
+
{
|
45
|
+
do_analyze(bridge_as_string, 0, 0, 0, 0, 0, result);
|
46
|
+
}
|
47
|
+
|
48
|
+
int compare(STRING *bridge_as_string_a, STRING *bridge_as_string_b)
|
49
|
+
{
|
50
|
+
TBridge a[1], canonical_a[1], b[1], canonical_b[1];
|
51
|
+
int rtn;
|
52
|
+
|
53
|
+
init_bridge(a);
|
54
|
+
init_bridge(canonical_a);
|
55
|
+
init_bridge(b);
|
56
|
+
init_bridge(canonical_b);
|
57
|
+
|
58
|
+
parse_bridge(a, bridge_as_string_a);
|
59
|
+
if (a->error != BridgeNoError)
|
60
|
+
return -1;
|
61
|
+
parse_bridge(b, bridge_as_string_b);
|
62
|
+
if (b->error != BridgeNoError)
|
63
|
+
return -1;
|
64
|
+
canonicalize(canonical_a, a);
|
65
|
+
if (canonical_a->error != BridgeNoError)
|
66
|
+
return -1;
|
67
|
+
canonicalize(canonical_b, b);
|
68
|
+
if (canonical_b->error != BridgeNoError)
|
69
|
+
return -1;
|
70
|
+
rtn = bridges_indentical(canonical_a, canonical_b);
|
71
|
+
|
72
|
+
clear_bridge(a);
|
73
|
+
clear_bridge(canonical_a);
|
74
|
+
clear_bridge(b);
|
75
|
+
clear_bridge(canonical_b);
|
76
|
+
|
77
|
+
return rtn;
|
78
|
+
}
|
79
|
+
|
80
|
+
char *variant(STRING *bridge_as_string, int seed)
|
81
|
+
{
|
82
|
+
char *rtn;
|
83
|
+
TBridge bridge[1], variant_bridge[1];
|
84
|
+
|
85
|
+
init_bridge(bridge);
|
86
|
+
init_bridge(variant_bridge);
|
87
|
+
|
88
|
+
parse_bridge(bridge, bridge_as_string);
|
89
|
+
|
90
|
+
if (bridge->error == BridgeNoError) {
|
91
|
+
vary(variant_bridge, bridge, seed);
|
92
|
+
rtn = unparse_bridge(variant_bridge);
|
93
|
+
}
|
94
|
+
else {
|
95
|
+
rtn = 0;
|
96
|
+
}
|
97
|
+
clear_bridge(bridge);
|
98
|
+
clear_bridge(variant_bridge);
|
99
|
+
|
100
|
+
return rtn;
|
101
|
+
}
|
102
|
+
|
103
|
+
char *failed_variant(STRING *bridge_as_string, int seed)
|
104
|
+
{
|
105
|
+
char *rtn;
|
106
|
+
TBridge bridge[1], variant_bridge[1];
|
107
|
+
|
108
|
+
init_bridge(bridge);
|
109
|
+
init_bridge(variant_bridge);
|
110
|
+
|
111
|
+
parse_bridge(bridge, bridge_as_string);
|
112
|
+
|
113
|
+
if (bridge->error == BridgeNoError) {
|
114
|
+
induce_failure(variant_bridge, bridge, seed);
|
115
|
+
rtn = unparse_bridge(variant_bridge);
|
116
|
+
}
|
117
|
+
else {
|
118
|
+
rtn = 0;
|
119
|
+
}
|
120
|
+
clear_bridge(bridge);
|
121
|
+
clear_bridge(variant_bridge);
|
122
|
+
|
123
|
+
return rtn;
|
124
|
+
}
|
125
|
+
|
126
|
+
char *perturbation(STRING *bridge_as_string, int seed,
|
127
|
+
int n_joints, int n_members)
|
128
|
+
{
|
129
|
+
char *rtn;
|
130
|
+
TBridge bridge[1], perturbed_bridge[1];
|
131
|
+
|
132
|
+
init_bridge(bridge);
|
133
|
+
init_bridge(perturbed_bridge);
|
134
|
+
|
135
|
+
parse_bridge(bridge, bridge_as_string);
|
136
|
+
|
137
|
+
if (bridge->error == BridgeNoError) {
|
138
|
+
perturb(perturbed_bridge, bridge, seed, n_joints, n_members);
|
139
|
+
rtn = unparse_bridge(perturbed_bridge);
|
140
|
+
}
|
141
|
+
else {
|
142
|
+
rtn = 0;
|
143
|
+
}
|
144
|
+
clear_bridge(bridge);
|
145
|
+
clear_bridge(perturbed_bridge);
|
146
|
+
|
147
|
+
return rtn;
|
148
|
+
}
|
149
|
+
|
150
|
+
|
151
|
+
void sketch(STRING *bridge_as_string,
|
152
|
+
int width, int height,
|
153
|
+
COMPRESSED_IMAGE *compressed_image,
|
154
|
+
struct analysis_result_t *result)
|
155
|
+
{
|
156
|
+
TBridge bridge[1];
|
157
|
+
TAnalysis analysis[1];
|
158
|
+
struct analysis_result_t local_result[1];
|
159
|
+
|
160
|
+
if (!result)
|
161
|
+
result = local_result;
|
162
|
+
|
163
|
+
do_analyze(bridge_as_string, analysis, bridge, 0, 0, 0, result);
|
164
|
+
|
165
|
+
if (result->status == BRIDGE_OK)
|
166
|
+
do_sketch(bridge, analysis, width, height, compressed_image);
|
167
|
+
|
168
|
+
clear_bridge(bridge);
|
169
|
+
clear_analysis(analysis);
|
170
|
+
}
|
171
|
+
|
172
|
+
char *get_local_contest_number(STRING *number_as_string)
|
173
|
+
{
|
174
|
+
char *rtn;
|
175
|
+
|
176
|
+
if (number_as_string->size != SCENARIO_NUMBER_SIZE)
|
177
|
+
return NULL;
|
178
|
+
return local_contest_number_to_id(number_as_string->ptr);
|
179
|
+
}
|
180
|
+
|
181
|
+
char *analysis_table(STRING *bridge_as_string)
|
182
|
+
{
|
183
|
+
TBridge bridge[1];
|
184
|
+
TParams params[1];
|
185
|
+
TGeometry geometry[1];
|
186
|
+
TLoading loading[1];
|
187
|
+
TAnalysis analysis[1];
|
188
|
+
struct analysis_result_t result[1];
|
189
|
+
char *rtn = 0;
|
190
|
+
|
191
|
+
do_analyze(bridge_as_string, analysis, bridge, geometry, loading, params, result);
|
192
|
+
if (!bridge->error)
|
193
|
+
rtn = analysis_to_html(analysis, bridge, geometry, loading, params, result);
|
194
|
+
|
195
|
+
clear_analysis(analysis);
|
196
|
+
clear_bridge(bridge);
|
197
|
+
clear_geometry(geometry);
|
198
|
+
clear_loading(loading);
|
199
|
+
clear_params(params);
|
200
|
+
|
201
|
+
return rtn;
|
202
|
+
}
|
203
|
+
|
204
|
+
#if defined(NATIVE_TEST) && !defined(CPROTO)
|
205
|
+
|
206
|
+
//#define WRITE_EXAMPLES
|
207
|
+
|
208
|
+
#ifdef WRITE_EXAMPLES
|
209
|
+
#define EG_DIR "../Eg/2011"
|
210
|
+
#define NEW_EG_DIR "../Eg/2012"
|
211
|
+
#else
|
212
|
+
#define EG_DIR "../Eg/2012"
|
213
|
+
#endif
|
214
|
+
|
215
|
+
#include <io.h>
|
216
|
+
#include <crtdbg.h>
|
217
|
+
#include <sys/types.h>
|
218
|
+
#include <sys/stat.h>
|
219
|
+
|
220
|
+
void split_fn(char *fn, char *path, char *name, char *ext)
|
221
|
+
{
|
222
|
+
char buf[256];
|
223
|
+
char *p, *pdot, *pslash;
|
224
|
+
|
225
|
+
strcpy(buf, fn);
|
226
|
+
|
227
|
+
pdot = strrchr(buf, '.');
|
228
|
+
if (pdot) {
|
229
|
+
strcpy(ext, pdot);
|
230
|
+
*pdot = '\0';
|
231
|
+
}
|
232
|
+
else
|
233
|
+
ext[0] = '\0';
|
234
|
+
|
235
|
+
pslash = strrchr(buf, '/');
|
236
|
+
if ((p = strrchr(buf, '\\')) != NULL && (!pslash || p > pslash))
|
237
|
+
pslash = p;
|
238
|
+
if (pslash) {
|
239
|
+
strcpy(name, pslash + 1);
|
240
|
+
*(pslash + 1) = '\0';
|
241
|
+
strcpy(path, buf);
|
242
|
+
}
|
243
|
+
else {
|
244
|
+
strcpy(name, buf);
|
245
|
+
path[0] = '\0';
|
246
|
+
}
|
247
|
+
}
|
248
|
+
|
249
|
+
int main(int argc, char* argv[])
|
250
|
+
{
|
251
|
+
extern unsigned contest_year; // ugly hack go read other years' bridge files
|
252
|
+
|
253
|
+
FILE *f;
|
254
|
+
char fname[256];
|
255
|
+
char raw[4*1024];
|
256
|
+
STRING bridge_str[1], copy_str[1];
|
257
|
+
char raw_hash[HASH_SIZE];
|
258
|
+
char variant_hash[HASH_SIZE];
|
259
|
+
char buf[256], path[256], name[256], ext[256];
|
260
|
+
char *text;
|
261
|
+
struct analysis_result_t result[1];
|
262
|
+
|
263
|
+
TBridge bridge[1];
|
264
|
+
TBridge copy[1];
|
265
|
+
TGeometry geometry[1];
|
266
|
+
TParams params[1];
|
267
|
+
TLoading loading[1];
|
268
|
+
TAnalysis anal[1];
|
269
|
+
int i, n, test_case;
|
270
|
+
long h;
|
271
|
+
struct _finddata_t file_data[1];
|
272
|
+
COMPRESSED_IMAGE compressed_image[1];
|
273
|
+
|
274
|
+
#ifdef WRITE_EXAMPLES
|
275
|
+
int n_examples_read = 0;
|
276
|
+
int n_examples_written = 0;
|
277
|
+
#endif
|
278
|
+
|
279
|
+
#ifdef _CRTDBG_MAP_ALLOC
|
280
|
+
{
|
281
|
+
int mem_debug_flags;
|
282
|
+
|
283
|
+
mem_debug_flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
|
284
|
+
mem_debug_flags |= _CRTDBG_LEAK_CHECK_DF;
|
285
|
+
_CrtSetDbgFlag(mem_debug_flags);
|
286
|
+
// Leak memory to show we're running.
|
287
|
+
malloc(1);
|
288
|
+
}
|
289
|
+
#endif
|
290
|
+
|
291
|
+
init_bridge(bridge);
|
292
|
+
init_bridge(copy);
|
293
|
+
init_geometry(geometry);
|
294
|
+
init_params(params);
|
295
|
+
init_loading(loading);
|
296
|
+
init_analysis(anal);
|
297
|
+
init_compressed_image(compressed_image);
|
298
|
+
|
299
|
+
setup_params(params);
|
300
|
+
|
301
|
+
if (test_scenario_table() != 0)
|
302
|
+
return 1;
|
303
|
+
|
304
|
+
for (test_case = 1;;test_case++) {
|
305
|
+
|
306
|
+
if (test_case == 1) {
|
307
|
+
h = _findfirst( EG_DIR "/*.bdc", file_data );
|
308
|
+
if (h == -1) {
|
309
|
+
printf( "No bridge files!\n" );
|
310
|
+
return 17;
|
311
|
+
}
|
312
|
+
}
|
313
|
+
else {
|
314
|
+
if (_findnext(h, file_data) != 0) {
|
315
|
+
_findclose(h);
|
316
|
+
test_case--;
|
317
|
+
break;
|
318
|
+
}
|
319
|
+
}
|
320
|
+
if (strcmp(file_data->name, "A-arch-10-4-1.bdc") != 0)
|
321
|
+
continue;
|
322
|
+
|
323
|
+
printf("Test case %d (%s):\n", test_case, file_data->name);
|
324
|
+
sprintf(fname, EG_DIR "/%s", file_data->name);
|
325
|
+
f = fopen(fname, "rb");
|
326
|
+
if (!f) {
|
327
|
+
printf("can't open bridge file\n");
|
328
|
+
return 1;
|
329
|
+
}
|
330
|
+
n = fread(raw, 1, sizeof raw, f);
|
331
|
+
raw[n] = '\0';
|
332
|
+
fclose(f);
|
333
|
+
|
334
|
+
bridge_str->size = n;
|
335
|
+
bridge_str->ptr = raw;
|
336
|
+
endecrypt(bridge_str);
|
337
|
+
|
338
|
+
printf("decrypted bridge:\n");
|
339
|
+
for (i = 0; i < n; i++)
|
340
|
+
putchar(bridge_str->ptr[i]);
|
341
|
+
printf("\n");
|
342
|
+
|
343
|
+
#ifdef WRITE_EXAMPLES
|
344
|
+
|
345
|
+
// Set the parser to look for last year's bridges.
|
346
|
+
contest_year = CONTEST_YEAR - 1;
|
347
|
+
#endif
|
348
|
+
|
349
|
+
// Try a parse.
|
350
|
+
parse_bridge(bridge, bridge_str);
|
351
|
+
|
352
|
+
|
353
|
+
// Back to this year.
|
354
|
+
contest_year = CONTEST_YEAR;
|
355
|
+
|
356
|
+
if (bridge->error != BridgeNoError) {
|
357
|
+
printf("parse error %d, line %d in %s; skipping...\n", bridge->error, bridge->error_line, fname);
|
358
|
+
continue;
|
359
|
+
}
|
360
|
+
printf("scenario id %s\n", bridge->scenario_descriptor.id);
|
361
|
+
|
362
|
+
#ifdef WRITE_EXAMPLES
|
363
|
+
|
364
|
+
if (!strstr(file_data->name, "failed")) {
|
365
|
+
|
366
|
+
struct _stat stat_buf[1];
|
367
|
+
|
368
|
+
n_examples_read++;
|
369
|
+
|
370
|
+
split_fn(file_data->name, path, name, ext);
|
371
|
+
|
372
|
+
n = fix_failure(copy, bridge, params);
|
373
|
+
|
374
|
+
if (n >= 0) {
|
375
|
+
printf("writing fixed version\n");
|
376
|
+
sprintf(fname, NEW_EG_DIR "/" "%s.bdc", name);
|
377
|
+
text = unparse_bridge(copy);
|
378
|
+
copy_str->ptr = text;
|
379
|
+
copy_str->size = strlen(text);
|
380
|
+
endecrypt(copy_str); // really encrypt
|
381
|
+
f = fopen(fname, "wb");
|
382
|
+
if (!f) {
|
383
|
+
printf("can't open fixed bridge file %s for writing\n", fname);
|
384
|
+
return 1;
|
385
|
+
}
|
386
|
+
fwrite(text, copy_str->size, 1, f);
|
387
|
+
fclose(f);
|
388
|
+
n_examples_written++;
|
389
|
+
}
|
390
|
+
else {
|
391
|
+
printf("attempt to fix bridge %s failed\n", fname);
|
392
|
+
}
|
393
|
+
|
394
|
+
// Write a failed version of this bridge for future testing.
|
395
|
+
printf("writing failed version\n");
|
396
|
+
sprintf(fname, NEW_EG_DIR "/" "%s-failed%s", name, ext);
|
397
|
+
if (_stat(fname, stat_buf) != 0 && induce_failure(copy, bridge, 0) == 0) {
|
398
|
+
text = unparse_bridge(copy);
|
399
|
+
copy_str->ptr = text;
|
400
|
+
copy_str->size = strlen(text);
|
401
|
+
endecrypt(copy_str); // really encrypt
|
402
|
+
f = fopen(fname, "wb");
|
403
|
+
if (!f) {
|
404
|
+
printf("can't open failed bridge file for writing\n");
|
405
|
+
return 1;
|
406
|
+
}
|
407
|
+
fwrite(text, copy_str->size, 1, f);
|
408
|
+
fclose(f);
|
409
|
+
clear_bridge(copy);
|
410
|
+
n_examples_written++;
|
411
|
+
}
|
412
|
+
}
|
413
|
+
continue;
|
414
|
+
#endif
|
415
|
+
|
416
|
+
// Check for idempotency.
|
417
|
+
n = compare(bridge_str, bridge_str);
|
418
|
+
if (n == -1) {
|
419
|
+
printf("idempotency test failed\n");
|
420
|
+
exit(1);
|
421
|
+
}
|
422
|
+
printf("compare is idempotent\n");
|
423
|
+
|
424
|
+
// Check for inverse.
|
425
|
+
text = unparse_bridge(bridge);
|
426
|
+
if (strncmp(text, raw, strlen(raw) - 10) != 0) {
|
427
|
+
printf("inverse test failed:\n%s\n", text);
|
428
|
+
exit(1);
|
429
|
+
}
|
430
|
+
Safefree(text);
|
431
|
+
printf("parse and unparse are inverses\n");
|
432
|
+
|
433
|
+
// Hash the bridge.
|
434
|
+
hash_bridge(bridge, raw_hash);
|
435
|
+
printf("hash=%s\n", hex_str(raw_hash, HASH_SIZE, buf));
|
436
|
+
|
437
|
+
// Check that a bunch of randomized versions of the same bridge
|
438
|
+
// compare equal to the original.
|
439
|
+
printf("permuting...");
|
440
|
+
#define N_PERMS 200
|
441
|
+
for (i = 0; i < N_PERMS; i++) {
|
442
|
+
|
443
|
+
vary(copy, bridge, i*13+1);
|
444
|
+
|
445
|
+
copy_str->ptr = unparse_bridge(copy);
|
446
|
+
copy_str->size = strlen(copy_str->ptr);
|
447
|
+
|
448
|
+
// printf("Permutation %d:\n%s\n", i+1, text);
|
449
|
+
n = compare(copy_str, bridge_str);
|
450
|
+
if (n == -1) {
|
451
|
+
printf("comparison with permutation failed at i=%d.\n", i);
|
452
|
+
exit(1);
|
453
|
+
}
|
454
|
+
else if ( !n ) {
|
455
|
+
printf("are_same test failed at i=%d\n", i);
|
456
|
+
exit(1);
|
457
|
+
}
|
458
|
+
Safefree(copy_str->ptr);
|
459
|
+
|
460
|
+
// Hash the variant.
|
461
|
+
hash_bridge(copy, variant_hash);
|
462
|
+
if (memcmp(raw_hash, variant_hash, HASH_SIZE) != 0) {
|
463
|
+
printf("hash test failed at i=%d.\n", i);
|
464
|
+
exit(1);
|
465
|
+
}
|
466
|
+
|
467
|
+
if (i % 1000 == 999)
|
468
|
+
printf(" %d", i+1);
|
469
|
+
}
|
470
|
+
printf("\n");
|
471
|
+
|
472
|
+
// Check that randomly perturbed versions of the bridge compare
|
473
|
+
// unequal.
|
474
|
+
|
475
|
+
printf("perturbing...");
|
476
|
+
#undef N_PERMS
|
477
|
+
#define N_PERMS 200
|
478
|
+
for (i = 0; i < N_PERMS; i++) {
|
479
|
+
perturb(copy, bridge, i*13+1, 1, 0);
|
480
|
+
|
481
|
+
copy_str->ptr = unparse_bridge(copy);
|
482
|
+
copy_str->size = strlen(copy_str->ptr);
|
483
|
+
|
484
|
+
// printf("Permutation %d:\n%s\n", i+1, text);
|
485
|
+
n = compare(copy_str, bridge_str);
|
486
|
+
if (n == -1) {
|
487
|
+
printf("comparison with perturbation failed at i=%d.\n", i);
|
488
|
+
exit(1);
|
489
|
+
}
|
490
|
+
else if ( n ) {
|
491
|
+
printf("are_same test failed to detect difference at i=%d\n", i);
|
492
|
+
exit(1);
|
493
|
+
}
|
494
|
+
Safefree(copy_str->ptr);
|
495
|
+
|
496
|
+
// Hash the variant.
|
497
|
+
hash_bridge(copy, variant_hash);
|
498
|
+
if (memcmp(raw_hash, variant_hash, HASH_SIZE) == 0) {
|
499
|
+
printf("warning: hash miss at i=%d.\n", i);
|
500
|
+
}
|
501
|
+
|
502
|
+
if (i % 1000 == 999)
|
503
|
+
printf(" %d", i+1);
|
504
|
+
}
|
505
|
+
printf("\n");
|
506
|
+
|
507
|
+
// Do an analysis table.
|
508
|
+
text = analysis_table(bridge_str);
|
509
|
+
|
510
|
+
if (text) {
|
511
|
+
printf("writing analysis...");
|
512
|
+
_splitpath(file_data->name, 0, path, name, ext);
|
513
|
+
sprintf(buf, "Debug/html/%s.htm", name);
|
514
|
+
f = fopen(buf, "w");
|
515
|
+
if (!f) {
|
516
|
+
fprintf(stderr, "can't open %s for output", buf);
|
517
|
+
return 4;
|
518
|
+
}
|
519
|
+
fputs("<html><head><title>Load Test Results Report</title>\n"
|
520
|
+
"<style>\n"
|
521
|
+
" table { font-size : 8pt; font-family: arial, helvetica, sans-serif }\n"
|
522
|
+
" th { font-weight : bold }\n"
|
523
|
+
"</style></head><body>\n", f);
|
524
|
+
fputs(text, f);
|
525
|
+
fputs("</body></html>", f);
|
526
|
+
fclose(f);
|
527
|
+
|
528
|
+
Safefree(text);
|
529
|
+
}
|
530
|
+
|
531
|
+
//print_analysis(stdout, anal, bridge, geometry, loading, params);
|
532
|
+
//printf("Cost = $%.2lf\n", (double)bridge_cost(bridge, geometry, params));
|
533
|
+
|
534
|
+
clear_bridge(bridge);
|
535
|
+
clear_bridge(copy);
|
536
|
+
clear_geometry(geometry);
|
537
|
+
clear_params(params);
|
538
|
+
clear_loading(loading);
|
539
|
+
clear_analysis(anal);
|
540
|
+
|
541
|
+
// Do a sketch
|
542
|
+
sketch(bridge_str, 300, 300, compressed_image, result);
|
543
|
+
_splitpath(file_data->name, 0, path, name, ext);
|
544
|
+
sprintf(buf, "Debug/sketch/%s.png", name);
|
545
|
+
f = fopen(buf, "wb");
|
546
|
+
if (!f) {
|
547
|
+
fprintf(stderr, "can't open %s for output", buf);
|
548
|
+
return 3;
|
549
|
+
}
|
550
|
+
fwrite(compressed_image->data, compressed_image->filled, 1, f);
|
551
|
+
fclose(f);
|
552
|
+
}
|
553
|
+
clear_compressed_image(compressed_image);
|
554
|
+
|
555
|
+
#ifdef WRITE_EXAMPLES
|
556
|
+
printf("%d examples read, %d written\n", n_examples_read, n_examples_written);
|
557
|
+
#endif
|
558
|
+
|
559
|
+
|
560
|
+
return 0;
|
561
|
+
}
|
562
|
+
|
563
|
+
#endif
|
data/ext/WPBDC/judge.h
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
#ifndef _JUDGE_H
|
2
|
+
#define _JUDGE_H
|
3
|
+
|
4
|
+
/*
|
5
|
+
*
|
6
|
+
* judge.h -- Ruby Extension WPBDC. Support for the West Point
|
7
|
+
* Bicentennial Design Contest web site. Ruby-visible constants
|
8
|
+
* and functions.
|
9
|
+
*/
|
10
|
+
|
11
|
+
#include "rubydefs.h"
|
12
|
+
#include "sketch.h"
|
13
|
+
|
14
|
+
#define CONTEST_YEAR 2012
|
15
|
+
#define YEAR_TO_VERSION(Y) (((((Y) % 100) / 10) << 8) | (((Y) % 10) << 4) | 0x400c)
|
16
|
+
#define BD_VERSION YEAR_TO_VERSION(CONTEST_YEAR)
|
17
|
+
|
18
|
+
// Status returns from analyze().
|
19
|
+
#define BRIDGE_OK 0
|
20
|
+
#define BRIDGE_MALFORMED 1
|
21
|
+
#define BRIDGE_WRONGVERSION 2
|
22
|
+
#define BRIDGE_FAILEDTEST 3
|
23
|
+
|
24
|
+
// Maximum element counts. Increased for 2012.
|
25
|
+
// #define MAX_JOINTS 50
|
26
|
+
// #define MAX_MEMBERS 120
|
27
|
+
#define MAX_JOINTS 100
|
28
|
+
#define MAX_MEMBERS 200
|
29
|
+
|
30
|
+
// Size of hash value in bytes.
|
31
|
+
#define HASH_SIZE 20
|
32
|
+
|
33
|
+
// Possible errors during bridge parsing.
|
34
|
+
typedef enum bridge_err_t {
|
35
|
+
BridgeNoError,
|
36
|
+
BridgeMissingData,
|
37
|
+
BridgeSyntax,
|
38
|
+
BridgeMissingHeader,
|
39
|
+
BridgeBadHeader,
|
40
|
+
BridgeMissingTestStatus,
|
41
|
+
BridgeBadTestStatus,
|
42
|
+
BridgeBadScenario,
|
43
|
+
BridgeBadNDesignIterations,
|
44
|
+
BridgeTooManyElements,
|
45
|
+
BridgeBadJointBanner,
|
46
|
+
BridgeTooFewJoints,
|
47
|
+
BridgeWrongPrescribedJoints,
|
48
|
+
BridgeBadMemberBanner,
|
49
|
+
BridgeTooFewMembers,
|
50
|
+
BridgeBadLabelPos,
|
51
|
+
BridgeExtraJunk,
|
52
|
+
BridgeDupJoints,
|
53
|
+
BridgeDupMembers,
|
54
|
+
BridgeJointOnMember,
|
55
|
+
BridgeBadLoadScenario,
|
56
|
+
BridgeBadChar,
|
57
|
+
} TBridgeError;
|
58
|
+
|
59
|
+
// Test status flag values read from bridge file.
|
60
|
+
typedef enum test_status_t {
|
61
|
+
NullTestStatus = -1,
|
62
|
+
Unrecorded,
|
63
|
+
Untested,
|
64
|
+
Failed,
|
65
|
+
Passed,
|
66
|
+
} TTestStatus;
|
67
|
+
|
68
|
+
#define SCENARIO_ID_SIZE 10
|
69
|
+
#define SCENARIO_NUMBER_SIZE 3
|
70
|
+
|
71
|
+
// WPBD version number.
|
72
|
+
typedef unsigned short TVersion; // 2 bytes
|
73
|
+
|
74
|
+
// Struct that describes what happened in analysis.
|
75
|
+
// We don't typedef it as a cue that it isn't covered
|
76
|
+
// by the standard init-setup-clear management protocol.
|
77
|
+
struct analysis_result_t {
|
78
|
+
TVersion version; // WPBDC version of parsed bridge.
|
79
|
+
char scenario_id[SCENARIO_ID_SIZE]; // WPBDC scenario ID.
|
80
|
+
char scenario_number[SCENARIO_NUMBER_SIZE]; // WPBDC scenario number.
|
81
|
+
TTestStatus test_status; // Load test flag from uploaded file.
|
82
|
+
int status; // Summary status
|
83
|
+
TBridgeError error; // Bridge error condition.
|
84
|
+
double cost; // Cost in dollars.
|
85
|
+
char hash[HASH_SIZE]; // Bridge hash value.
|
86
|
+
};
|
87
|
+
|
88
|
+
// This must match ruby string length type.
|
89
|
+
typedef long STRLEN;
|
90
|
+
|
91
|
+
// Representation for a string of arbitrary length, which may possibly
|
92
|
+
// contain NULLs. We'll convert RSTRINGs to and from this type.
|
93
|
+
typedef struct t_string {
|
94
|
+
char *ptr;
|
95
|
+
STRLEN size;
|
96
|
+
} STRING;
|
97
|
+
|
98
|
+
// Encrypt/decrypt a bridge by modifying string in place.
|
99
|
+
void endecrypt(STRING *bridge_as_string);
|
100
|
+
|
101
|
+
// Parse bridge as string.
|
102
|
+
// Return a result struct that describes what happened.
|
103
|
+
void analyze(STRING *bridge_as_string, struct analysis_result_t *result);
|
104
|
+
|
105
|
+
// Compare two bridges for functional equality, that is geometry
|
106
|
+
// identical up to joint and member numbers.
|
107
|
+
// Returns -1 if one or both bridges were malformed.
|
108
|
+
// Else returns a boolean indicating equality.
|
109
|
+
#define BRIDGE_COMPARISON_ERROR -1
|
110
|
+
#define BRIDGES_EQUAL 1
|
111
|
+
#define BRIDGES_NOT_EQUAL 0
|
112
|
+
int compare(STRING *bridge_as_string_a, STRING *bridge_as_string_b);
|
113
|
+
|
114
|
+
// Return a variant of a bridge with permuted joints, members, and joint references
|
115
|
+
// with members. This is for testing comparison and hashing functions.
|
116
|
+
char *variant(STRING *bridge_as_string, int seed);
|
117
|
+
|
118
|
+
// Return a variant of a bridge where one member chosen at random has been reduced
|
119
|
+
// in size until the bridge fails. This is for testing member force computations.
|
120
|
+
char *failed_variant(STRING *bridge_as_string, int seed);
|
121
|
+
|
122
|
+
// Return a perturbation of a bridge with the given number of joints moved by
|
123
|
+
// one grid and/or the given number of members thickened (or sometimes thinned).
|
124
|
+
// The resulting bridge has _no_ guarantee of correctness, let alone that it will
|
125
|
+
// carry any kind of load.
|
126
|
+
char *perturbation(STRING *bridge_as_string, int seed,
|
127
|
+
int n_joints, int n_members);
|
128
|
+
|
129
|
+
// Do an analysis and also return a PNG image sketch of the bridge.
|
130
|
+
void sketch(STRING *bridge_as_string,
|
131
|
+
int width, int height,
|
132
|
+
COMPRESSED_IMAGE *compressed_image,
|
133
|
+
struct analysis_result_t *result);
|
134
|
+
|
135
|
+
// Return HTML for a table of analysis data.
|
136
|
+
char *analysis_table(STRING *bridge_as_string);
|
137
|
+
|
138
|
+
// Accept a string containing a scenario number.
|
139
|
+
// Return a pointer to the 3-character local contest code or null if no match.
|
140
|
+
char *get_local_contest_number(STRING *number_as_string);
|
141
|
+
|
142
|
+
#endif
|