#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <vector>

#include "Player.hpp"
#include "RandomPlayer.hpp"
#include "Doomer.hpp"
#include "Roomer.hpp"
#include "Profiteer.hpp"
#include "Segv.hpp"
#include "Anon.hpp"
#include "Anon2.hpp"

using namespace std;

vector<Player *> players;
const int ROUND_COUNT = 200;

inline
void print_round(reaction_t r1, reaction_t r2) {
    const char * const color_table[] = {
        [COOPERATE] = "\033[32m",
        [CONFLICT]  = "\033[31m",
    };

    printf("  %sO\033[0m %sO\033[0m\n", color_table[r1], color_table[r2]);
}

inline
void play_round(Player * const p1, Player * const p2) {
    reaction_t p1_play = p1->play();
    reaction_t p2_play = p2->play();

    print_round(p1_play, p2_play);

    if (p1_play == COOPERATE && p2_play == COOPERATE) {
        p1->points += 3;
        p2->points += 3;
    } else if (p1_play == CONFLICT && p2_play == CONFLICT) {
        p1->points += 1;
        p2->points += 1;
    } else {
        Player * const pw = (p1_play == CONFLICT) ? p1 : p2;
        pw->points += 5;
    }

    p1->push_result(p2_play);
    p2->push_result(p1_play);
}

signed main() {
    /* we seed, rand for you, in case you wish to use it,
     * please do not re seed it
     */
    srand(time(NULL));

    // YYY: Every player is added here
    players.push_back(new RandomPlayer());
    players.push_back(new Doomer());
    players.push_back(new Roomer());
    players.push_back(new Profiteer());
    players.push_back(new Segv());
    players.push_back(new Anon2());
    // --

    /* Every players playes with every player exactly once
     */
    for (int i = 0; i < players.size() - 1; i++) {
        for (int h = i + 1; h < players.size(); h++) {
            printf("%s VS %s\n", players[i]->name, players[h]->name);
            players[i]->new_game();
            players[h]->new_game();
            /* Each game takes some number of turns
             */
            for (int c = 0; c < ROUND_COUNT; c++) {
                play_round(players[i], players[h]);
            }
        }
    }

    // Results
    for (const auto &p : players) {
        printf("%s: %ld\n", p->name, p->points);
    }
}
