#include #include #include #include #include #include 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 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(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; }