summaryrefslogtreecommitdiff
path: root/tabulator/tabulator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tabulator/tabulator.cpp')
-rw-r--r--tabulator/tabulator.cpp159
1 files changed, 159 insertions, 0 deletions
diff --git a/tabulator/tabulator.cpp b/tabulator/tabulator.cpp
new file mode 100644
index 0000000..60cd680
--- /dev/null
+++ b/tabulator/tabulator.cpp
@@ -0,0 +1,159 @@
+#include <lib94/lib94.hpp>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <cstdio>
+#include <vector>
+
+const int steps_to_tie = 1000000;
+
+int error(std::string msg, int rank) {
+ if (rank == 0) {
+ std::cerr << msg << std::endl;
+ return 1;
+ }
+ return 0;
+}
+
+constexpr lib94::instruction background_instruction = {
+ .op = lib94::DAT, .mod = lib94::F,
+ .amode = lib94::DIRECT, .bmode = lib94::DIRECT,
+ .anumber = 0, .bnumber = 0
+};
+
+int main(int argc, char **argv) {
+
+ MPI_Init(&argc, &argv);
+
+ int rank;
+ int size;
+
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &size);
+
+ lib94::seed_prng(time(0) + rank);
+
+ std::vector<std::string> filenames = {};
+
+ for (int i = 1; i < argc; ++i)
+ filenames.push_back(argv[i]);
+
+ if (filenames.size() == 0)
+ return error("no files specified.", rank);
+ if (filenames.size() == 1)
+ return error("only one file specified.", rank);
+
+ int count = filenames.size();
+ lib94::warrior **warriors = new lib94::warrior *[count];
+ for (int i = 0; i < count; ++i) {
+ try {
+ warriors[i] = lib94::compile_warrior_from_file(filenames[i]);
+ }
+ catch (const lib94::compiler_exception &ex) {
+ return error("could not compile " + filenames[i] + ": " + ex.message + " on line " + std::to_string(ex.source_line_number) + ".", rank);
+ }
+ if (!warriors[i])
+ return error("could not open " + filenames[i] + ".", rank);
+ }
+
+ int **wins_against = new int *[count];
+ for (int i = 0; i < count; ++i)
+ wins_against[i] = new int[count];
+
+ int **rounds_against = new int *[count];
+ for (int i = 0; i < count; ++i)
+ rounds_against[i] = new int[count];
+
+ for (int i = 0; i < count; ++i)
+ for (int j = i + 1; j < count; ++j) {
+
+ const lib94::warrior *w1 = warriors[i];
+ const lib94::warrior *w2 = warriors[j];
+
+ if (rank == 0)
+ std::cout << "running " << w1->name << " vs " << w2->name << "..." << std::endl;
+
+ int w1_wins, w2_wins, rounds;
+ lib94::tabulate_mpi<true>(background_instruction, w1, w2, steps_to_tie, w1_wins, w2_wins, rounds, MPI_COMM_WORLD);
+
+ if (rank == 0)
+ std::cout
+ << "results:\n " << w1->name << ": " << w1_wins << "\n "
+ << w2->name << ": " << w2_wins << "\n ties: "
+ << (rounds - w1_wins - w2_wins) << "\n\n";
+
+ wins_against[i][j] = w1_wins;
+ wins_against[j][i] = w2_wins;
+
+ rounds_against[i][j] = rounds;
+ rounds_against[j][i] = rounds;
+
+ }
+
+ if (rank == 0) {
+
+ unsigned column_width = 0;
+ unsigned name_width = 0;
+ for (int i = 0; i < count; ++i)
+ if (warriors[i]->name.size() > name_width) {
+ name_width = warriors[i]->name.size();
+ column_width = name_width;
+ }
+
+ unsigned number_width = 0;
+ for (int i = 0; i < count; ++i)
+ for (int j = 0; j < count; ++j)
+ if (i != j) {
+ unsigned width = std::to_string(rounds_against[i][j]).size();
+ if (width > number_width)
+ number_width = width;
+ if (width * 2 + 3 > column_width)
+ column_width = width * 2 + 3;
+ }
+
+ for (int i = 0; i < count; ++i)
+ warriors[i]->name.insert(0, column_width - warriors[i]->name.size(), ' ');
+
+ std::string spaces, dashes;
+ spaces.resize(column_width, ' ');
+ dashes.resize(column_width, '-');
+
+ std::string first_spaces;
+ first_spaces.resize(name_width, ' ');
+ std::cout << ' ' << first_spaces;
+ for (int i = 0; i < count; ++i) {
+ std::cout << " | " << warriors[i]->name;
+ }
+
+ std::string first_dashes;
+ first_dashes.resize(name_width, '-');
+ std::cout << "\n-" << first_dashes;
+ for (int i = 0; i < count; ++i)
+ std::cout << "-+-" << dashes;
+ std::cout << "-\n";
+
+ for (int i = 0; i < count; ++i) {
+ std::string name = warriors[i]->name;
+ name.erase(0, column_width - name_width);
+ std::cout << ' ' << name;
+ for (int j = 0; j < count; ++j)
+ if (i == j)
+ std::cout << " | " << spaces;
+ else {
+ std::string num = std::to_string(wins_against[j][i]);
+ std::string den = std::to_string(rounds_against[j][i]);
+ num.insert(0, number_width - num.size(), ' ');
+ den.insert(0, number_width - den.size(), ' ');
+ std::string content = num + " / " + den;
+ content.insert(0, column_width - content.size(), ' ');
+ std::cout << " | " << content;
+ }
+ std::cout << '\n';
+ }
+
+ }
+
+ MPI_Finalize();
+ return 0;
+
+}