1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
#include <lib94/lib94.hpp>
#include <iostream>
#include <fstream>
[[noreturn]] void usage(const char *argv0) {
std::cout << "usage: " << argv0 << " <first warrior> <second warrior> <number of rounds> <steps until tie>\n";
exit(1);
}
void print_warrior(const lib94::warrior *w) {
std::cerr << ";name " << w->name << '\n';
std::cerr << ";author " << w->author << '\n';
if (w->org != 0)
std::cerr << "org " << w->org << '\n';
for (const auto &i : w->instructions)
std::cerr << lib94::instruction_to_string(i) << '\n';
std::cerr << '\n';
}
int main(int argc, const char **argv) {
if (argc != 5)
usage(argv[0]);
unsigned round_count, steps_until_tie;
try {
round_count = std::stoul(argv[3]);
steps_until_tie = std::stoul(argv[4]);
}
catch (const std::exception &e) {
usage(argv[0]);
}
std::ifstream file1(argv[1]);
std::ifstream file2(argv[2]);
if (!file1 || !file2)
usage(argv[0]);
std::string source1(std::istreambuf_iterator<char>(file1), {});
std::string source2(std::istreambuf_iterator<char>(file2), {});
file1.close();
file2.close();
lib94::warrior *w1, *w2;
try {
w1 = lib94::compile_warrior(source1);
}
catch (const lib94::compiler_exception &ex) {
std::cout << "error in " << argv[1] << " on line " << ex.line_number << ": " << ex.message << '\n';
return 1;
}
try {
w2 = lib94::compile_warrior(source2);
}
catch (const lib94::compiler_exception &ex) {
std::cout << "error in " << argv[2] << " on line " << ex.line_number << ": " << ex.message << '\n';
return 1;
}
const lib94::warrior *ws[2] = {w1, w2};
print_warrior(ws[0]);
print_warrior(ws[1]);
unsigned w1_wins = 0;
unsigned w2_wins = 0;
lib94::seed_prng(time(NULL));
for (unsigned round_number = 0; round_number < round_count; ++round_number) {
std::cerr << "round " << round_number + 1 << "\x1b[0G";
lib94::clear_core({
.op = lib94::DAT, .mod = lib94::F,
.amode = lib94::DIRECT, .bmode = lib94::DIRECT,
.anumber = 0, .bnumber = 0
});
lib94::init_round(ws, 2);
for (unsigned step_number = 0; step_number < steps_until_tie; ++step_number) {
const lib94::warrior *w = lib94::single_step<false>();
if (w == ws[0]) {
++w2_wins;
break;
}
if (w == ws[1]) {
++w1_wins;
break;
}
}
}
std::cout << round_count << " rounds completed\n";
std::cout << w1_wins << " wins, " << w2_wins << " losses\n";
std::cout << "score " << (int)w1_wins - (int)w2_wins << '\n';
return 0;
}
|