This commit is contained in:
parent
22e3eceb5d
commit
cd0b5a8b4b
1 changed files with 94 additions and 45 deletions
137
tennis.c
137
tennis.c
|
@ -29,21 +29,61 @@ const char *lut[] = {
|
||||||
|
|
||||||
enum {lutlen = LEN(lut)}; // should be 28.
|
enum {lutlen = LEN(lut)}; // should be 28.
|
||||||
|
|
||||||
const u32 c0 = 64;
|
const u32 bases[] = {
|
||||||
const u32 c1 = 11;
|
64,
|
||||||
const u32 c2 = 21;
|
11,
|
||||||
const u32 c3 = 2;
|
21,
|
||||||
const u32 c4 = 21;
|
2,
|
||||||
const u32 c5 = 8;
|
21,
|
||||||
|
8,
|
||||||
|
6, // dummy value.
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MT_CHOICE = -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MT_YOSHI,
|
||||||
|
MT_PEACH,
|
||||||
|
MT_MARIO,
|
||||||
|
MT_BOWSER,
|
||||||
|
MT_BOO,
|
||||||
|
MT_DK,
|
||||||
|
MT_BABY_MARIO,
|
||||||
|
MT_TOAD,
|
||||||
|
MT_WALUIGI,
|
||||||
|
MT_WARIO,
|
||||||
|
MT_LUIGI,
|
||||||
|
MT_DAISY,
|
||||||
|
MT_BIRDO,
|
||||||
|
MT_SHYGUY,
|
||||||
|
MT_DK_JR,
|
||||||
|
MT_PARATROOPA,
|
||||||
|
} character_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MT_SINGLES_GAME,
|
||||||
|
MT_SINGLES_TIME_3,
|
||||||
|
MT_SINGLES_TIME_5,
|
||||||
|
MT_SINGLES_BALL_1,
|
||||||
|
MT_SINGLES_BALL_3,
|
||||||
|
MT_SINGLES_POINT_3,
|
||||||
|
MT_SINGLES_POINT_5,
|
||||||
|
MT_DOUBLES_GAME_1,
|
||||||
|
MT_DOUBLES_TIME_3,
|
||||||
|
MT_DOUBLES_BALL_1,
|
||||||
|
MT_DOUBLES_POINT_3,
|
||||||
|
} gamemode_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char code[9];
|
char code[9];
|
||||||
// data[0]: cup name
|
// data[0]: cup name
|
||||||
// data[1]: ?
|
// data[1]: gamemode
|
||||||
// data[2]: player character (-1 for player's choice)
|
// data[2]: player character (-1 for player's choice)
|
||||||
// data[3]: game mode? (boolean)
|
// data[3]: unknown (boolean)
|
||||||
// data[4]: opponent character (-1 for player's choice)
|
// data[4]: opponent character (-1 for player's choice)
|
||||||
// data[5]: ?
|
// data[5]: unknown
|
||||||
// data[6]: court (-1 for player's choice)
|
// data[6]: court (-1 for player's choice)
|
||||||
u32 data[7];
|
u32 data[7];
|
||||||
} code_t;
|
} code_t;
|
||||||
|
@ -69,16 +109,20 @@ code_t translate(const char *entry) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
int check_ranges(code_t *code) {
|
int check_ranges(const code_t *code) {
|
||||||
int within_range = 1;
|
const u32 neg1 = (u32)-1;
|
||||||
within_range &= code->data[0] < c0;
|
const u32 *data = code->data;
|
||||||
within_range &= code->data[1] < c1;
|
|
||||||
within_range &= code->data[2] + 1 < c2 - 4;
|
return
|
||||||
within_range &= code->data[3] < c3;
|
(data[0] < bases[0]) &&
|
||||||
within_range &= code->data[4] + 1 < c2 - 4;
|
(data[1] < bases[1]) &&
|
||||||
within_range &= code->data[5] < c5;
|
(data[2] + 1 < bases[2] - 4) &&
|
||||||
within_range &= code->data[6] + 1 < 6;
|
(data[3] < bases[3]) &&
|
||||||
return within_range;
|
(data[4] + 1 < bases[4] - 4) &&
|
||||||
|
(data[5] < bases[5]) &&
|
||||||
|
(data[6] + 1 < bases[6]) &&
|
||||||
|
(data[2] == neg1 || data[2] != data[4]) &&
|
||||||
|
(data[1] < 7 || (data[2] != neg1 && data[4] != neg1));
|
||||||
}
|
}
|
||||||
|
|
||||||
int decode_data(code_t *code) {
|
int decode_data(code_t *code) {
|
||||||
|
@ -95,12 +139,12 @@ int decode_data(code_t *code) {
|
||||||
|
|
||||||
u32 leftover = part0 ^ 0x02AAAAAA;
|
u32 leftover = part0 ^ 0x02AAAAAA;
|
||||||
|
|
||||||
code->data[0] = leftover % c0; leftover /= c0;
|
code->data[0] = leftover % bases[0]; leftover /= bases[0];
|
||||||
code->data[1] = leftover % c1; leftover /= c1;
|
code->data[1] = leftover % bases[1]; leftover /= bases[1];
|
||||||
code->data[2] = leftover % c2; leftover /= c2;
|
code->data[2] = leftover % bases[2]; leftover /= bases[2];
|
||||||
code->data[3] = leftover % c3; leftover /= c3;
|
code->data[3] = leftover % bases[3]; leftover /= bases[3];
|
||||||
code->data[4] = leftover % c4; leftover /= c4;
|
code->data[4] = leftover % bases[4]; leftover /= bases[4];
|
||||||
code->data[5] = leftover % c5; leftover /= c5;
|
code->data[5] = leftover % bases[5]; leftover /= bases[5];
|
||||||
code->data[6] = leftover;
|
code->data[6] = leftover;
|
||||||
|
|
||||||
code->data[2]--;
|
code->data[2]--;
|
||||||
|
@ -117,29 +161,20 @@ int decode_data(code_t *code) {
|
||||||
|
|
||||||
if (!check_ranges(code)) return 0;
|
if (!check_ranges(code)) return 0;
|
||||||
|
|
||||||
// TODO: refactor so this isn't repeated in encode_data.
|
|
||||||
const u32 neg1 = (u32)-1;
|
|
||||||
if (code->data[2] == neg1 || code->data[2] != code->data[4]); else return 0;
|
|
||||||
if (code->data[1] < 7 || (code->data[2] != neg1 && code->data[4] != neg1)); else return 0;
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int encode_data(code_t *code) {
|
int encode_data(code_t *code) {
|
||||||
const u32 neg1 = (u32)-1;
|
|
||||||
if (code->data[2] == neg1 || code->data[2] != code->data[4]); else return 0;
|
|
||||||
if (code->data[1] < 7 || (code->data[2] != neg1 && code->data[4] != neg1)); else return 0;
|
|
||||||
|
|
||||||
if (!check_ranges(code)) return 0;
|
if (!check_ranges(code)) return 0;
|
||||||
|
|
||||||
u32 combined = 0;
|
u32 combined = 0;
|
||||||
combined = code->data[6] + 1;
|
combined = code->data[6] + 1;
|
||||||
combined = combined * c5 + code->data[5];
|
combined = combined * bases[5] + code->data[5];
|
||||||
combined = combined * c4 + code->data[4] + 1;
|
combined = combined * bases[4] + code->data[4] + 1;
|
||||||
combined = combined * c3 + code->data[3];
|
combined = combined * bases[3] + code->data[3];
|
||||||
combined = combined * c2 + code->data[2] + 1;
|
combined = combined * bases[2] + code->data[2] + 1;
|
||||||
combined = combined * c1 + code->data[1];
|
combined = combined * bases[1] + code->data[1];
|
||||||
combined = combined * c0 + code->data[0];
|
combined = combined * bases[0] + code->data[0];
|
||||||
combined = combined ^ 0x02AAAAAA;
|
combined = combined ^ 0x02AAAAAA;
|
||||||
|
|
||||||
u32 checksum = (combined + 0x2AE0) % (lutlen * lutlen * lutlen);
|
u32 checksum = (combined + 0x2AE0) % (lutlen * lutlen * lutlen);
|
||||||
|
@ -174,7 +209,7 @@ int validate_entry(const char *entry) {
|
||||||
return decode_data(&code);
|
return decode_data(&code);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_code(code_t *code) {
|
static void print_code(const code_t *code) {
|
||||||
for (int j = 0; j < 9; j++) {
|
for (int j = 0; j < 9; j++) {
|
||||||
int index = code->code[j];
|
int index = code->code[j];
|
||||||
printf("%c", lut[index][0]);
|
printf("%c", lut[index][0]);
|
||||||
|
@ -188,10 +223,24 @@ static u32 prng() {
|
||||||
return prng_state ^ (prng_state >> 32);
|
return prng_state ^ (prng_state >> 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
int bruteforce() { // with a fixed seed, this is useful for testing.
|
int bruteforce(int count) {
|
||||||
|
/* with a fixed seed, this is useful for testing.
|
||||||
|
the first 10 results should be:
|
||||||
|
8RPEHR8R4
|
||||||
|
MNXKWQMNE
|
||||||
|
CE922RCER
|
||||||
|
MQ1KMQMQG
|
||||||
|
2N9GGR2NR
|
||||||
|
25L53R250
|
||||||
|
15R09R159
|
||||||
|
9R9LMQ9RR
|
||||||
|
L312MQL3G
|
||||||
|
P93M6QP9N
|
||||||
|
*/
|
||||||
|
|
||||||
int found = 0;
|
int found = 0;
|
||||||
code_t code = {0};
|
code_t code = {0};
|
||||||
while (found < 10) {
|
while (found < count) {
|
||||||
for (int j = 0; j < 9; j++) {
|
for (int j = 0; j < 9; j++) {
|
||||||
code.code[j] = prng() % lutlen;
|
code.code[j] = prng() % lutlen;
|
||||||
}
|
}
|
||||||
|
@ -250,7 +299,7 @@ int main(int argc, char **argv) {
|
||||||
//if (validate_entry(arg)) printf("%s\n", arg);
|
//if (validate_entry(arg)) printf("%s\n", arg);
|
||||||
invalid_count += !validate_entry(arg);
|
invalid_count += !validate_entry(arg);
|
||||||
} else if (!strcmp(arg, "bruteforce")) {
|
} else if (!strcmp(arg, "bruteforce")) {
|
||||||
invalid_count += !bruteforce();
|
invalid_count += !bruteforce(10);
|
||||||
} else {
|
} else {
|
||||||
u32 datum = strtoul(arg, NULL, 0);
|
u32 datum = strtoul(arg, NULL, 0);
|
||||||
code.data[code_i] = datum;
|
code.data[code_i] = datum;
|
||||||
|
|
Loading…
Add table
Reference in a new issue