WPBDC 2013.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|