summaryrefslogtreecommitdiff
path: root/score/main.cpp
blob: 88536bb510ecd2e9708eee3c3ad1a2b7f769f0a2 (plain) (blame)
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
#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();

  auto w1 = lib94::compile_warrior(source1);
  auto w2 = lib94::compile_warrior(source2);

  if (std::holds_alternative<std::string>(w1)) {
    std::cout << "error compiling " << argv[1] << ": " << std::get<std::string>(w1) << '\n';
    return 1;
  }

  if (std::holds_alternative<std::string>(w2)) {
    std::cout << "error compiling " << argv[2] << ": " << std::get<std::string>(w2) << '\n';
    return 1;
  }

  const lib94::warrior *ws[2];
  ws[0] = std::get<lib94::warrior *>(w1);
  ws[1] = std::get<lib94::warrior *>(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();

      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;
}