|
|
@@ -0,0 +1,936 @@
|
|
|
+#include <stdio.h>
|
|
|
+#include <string.h>
|
|
|
+#include <sqlite3.h>
|
|
|
+
|
|
|
+// Rune set definitions
|
|
|
+#define ENERGY 1
|
|
|
+#define GUARD 2
|
|
|
+#define SWIFT 3
|
|
|
+#define BLADE 4
|
|
|
+#define RAGE 5
|
|
|
+#define FOCUS 6
|
|
|
+#define ENDURE 7
|
|
|
+#define FATAL 8
|
|
|
+#define DESPAIR 10
|
|
|
+#define VAMPIRE 11
|
|
|
+#define VIOLENT 13
|
|
|
+#define NEMESIS 14
|
|
|
+#define WILL 15
|
|
|
+#define SHIELD 16
|
|
|
+#define REVENGE 17
|
|
|
+#define DESTROY 18
|
|
|
+#define FIGHT 19
|
|
|
+#define DETERMINATION 20
|
|
|
+#define ENHANCE 21
|
|
|
+#define ACCURACY 22
|
|
|
+#define TOLERANCE 23
|
|
|
+
|
|
|
+// Rune stat definitions
|
|
|
+#define HP_FLAT 1
|
|
|
+#define HP_PERCENT 2
|
|
|
+#define ATK_FLAT 3
|
|
|
+#define ATK_PERCENT 4
|
|
|
+#define DEF_FLAT 5
|
|
|
+#define DEF_PERCENT 6
|
|
|
+#define SPD 8
|
|
|
+#define CRR 9
|
|
|
+#define CRD 10
|
|
|
+#define RES 11
|
|
|
+#define ACC 12
|
|
|
+
|
|
|
+struct Unit {
|
|
|
+ unsigned char id[12];
|
|
|
+ unsigned char name[50];
|
|
|
+ unsigned short base_hp;
|
|
|
+ unsigned short base_atk;
|
|
|
+ unsigned short base_def;
|
|
|
+ unsigned short base_spd;
|
|
|
+ unsigned short base_crr;
|
|
|
+ unsigned short base_crd;
|
|
|
+ unsigned short base_acc;
|
|
|
+ unsigned short base_res;
|
|
|
+ unsigned short current_hp;
|
|
|
+ unsigned short current_atk;
|
|
|
+ unsigned short current_def;
|
|
|
+ unsigned short current_spd;
|
|
|
+ unsigned short current_crr;
|
|
|
+ unsigned short current_crd;
|
|
|
+ unsigned short current_acc;
|
|
|
+ unsigned short current_res;
|
|
|
+};
|
|
|
+
|
|
|
+struct Rune {
|
|
|
+ unsigned char id[12];
|
|
|
+ unsigned char slot;
|
|
|
+ unsigned char set;
|
|
|
+ unsigned char unit[12];
|
|
|
+ unsigned char hp_percent;
|
|
|
+ unsigned char atk_percent;
|
|
|
+ unsigned char def_percent;
|
|
|
+ unsigned short hp_flat;
|
|
|
+ unsigned char atk_flat;
|
|
|
+ unsigned char def_flat;
|
|
|
+ unsigned char spd;
|
|
|
+ unsigned char crr;
|
|
|
+ unsigned char crd;
|
|
|
+ unsigned char acc;
|
|
|
+ unsigned char res;
|
|
|
+};
|
|
|
+
|
|
|
+struct Stats {
|
|
|
+ unsigned short hp;
|
|
|
+ unsigned short atk;
|
|
|
+ unsigned short def;
|
|
|
+ unsigned short spd;
|
|
|
+ unsigned short crr;
|
|
|
+ unsigned short crd;
|
|
|
+ unsigned short acc;
|
|
|
+ unsigned short res;
|
|
|
+};
|
|
|
+
|
|
|
+struct Rune_Set_Count {
|
|
|
+ unsigned short energy;
|
|
|
+ unsigned short guard;
|
|
|
+ unsigned short swift;
|
|
|
+ unsigned short blade;
|
|
|
+ unsigned short rage;
|
|
|
+ unsigned short focus;
|
|
|
+ unsigned short endure;
|
|
|
+ unsigned short fatal;
|
|
|
+ unsigned short despair;
|
|
|
+ unsigned short vampire;
|
|
|
+ unsigned short violent;
|
|
|
+ unsigned short nemesis;
|
|
|
+ unsigned short will;
|
|
|
+ unsigned short shield;
|
|
|
+ unsigned short revenge;
|
|
|
+ unsigned short destroy;
|
|
|
+ unsigned short fight;
|
|
|
+ unsigned short determination;
|
|
|
+ unsigned short enhance;
|
|
|
+ unsigned short accuracy;
|
|
|
+ unsigned short tolerance;
|
|
|
+};
|
|
|
+typedef struct Result {
|
|
|
+ unsigned char rune_ids[6][12];
|
|
|
+ signed int rating;
|
|
|
+} Result;
|
|
|
+
|
|
|
+void show_help();
|
|
|
+int optimize(int argc, char *argv[]);
|
|
|
+int open_databse();
|
|
|
+int unit_callback(void *, int, char **, char **);
|
|
|
+int db_status;
|
|
|
+sqlite3 *db;
|
|
|
+
|
|
|
+int main(int argc, char *argv[]){
|
|
|
+ // Parse the arguments
|
|
|
+ if (argc < 2){
|
|
|
+ printf("No options specified\n");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ int command = -1;
|
|
|
+ if (strcmp(argv[1], "update") == 0){
|
|
|
+ printf("Updating is still unimplemented\n");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ else if (strcmp(argv[1], "optimize") == 0){
|
|
|
+ //printf("Starting optimization...\n");
|
|
|
+ int result = optimize(argc, argv);
|
|
|
+ if (result != 0){
|
|
|
+ printf("Errors in optimization: %d\n", result);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (strcmp(argv[1], "help") == 0){
|
|
|
+ show_help();
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ printf("Invalid option specified: %s\n", argv[1]);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+int open_database(){
|
|
|
+ int db_status = sqlite3_open("../data.sqlite", &db);
|
|
|
+
|
|
|
+ if (db_status != SQLITE_OK) {
|
|
|
+
|
|
|
+ printf("Cannot open database: %s\n", sqlite3_errmsg(db));
|
|
|
+ sqlite3_close(db);
|
|
|
+
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void show_help(){
|
|
|
+ printf("Sample help text\n");
|
|
|
+}
|
|
|
+
|
|
|
+int optimize(int argc, char *argv[]){
|
|
|
+ if (argc < 3){
|
|
|
+ printf("No unit specified for optimization\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ // Read the unit from the databse
|
|
|
+ open_database();
|
|
|
+
|
|
|
+ sqlite3_stmt *res;
|
|
|
+ char *sql = "SELECT "
|
|
|
+ "id, name, "
|
|
|
+ "base_hp, base_atk, base_def, base_spd, base_crr, base_crd, base_res, base_acc, "
|
|
|
+ "current_hp, current_atk, current_def, current_spd, current_crr, current_crd, current_res, current_acc "
|
|
|
+ "FROM units WHERE id = ? OR name = ?";
|
|
|
+ db_status = sqlite3_prepare_v2(db, sql, -1, &res, 0);
|
|
|
+
|
|
|
+ if (db_status == SQLITE_OK) {
|
|
|
+ sqlite3_bind_text(res, 1, argv[2], strlen(argv[2]), NULL);
|
|
|
+ sqlite3_bind_text(res, 2, argv[2], strlen(argv[2]), NULL);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ printf("Failed to execute statement to select unit: %s\n", sqlite3_errmsg(db));
|
|
|
+ return -2;
|
|
|
+ }
|
|
|
+
|
|
|
+ int step = sqlite3_step(res);
|
|
|
+
|
|
|
+ struct Unit unit;
|
|
|
+
|
|
|
+ if (step == SQLITE_ROW) {
|
|
|
+ strcpy(unit.id, sqlite3_column_text(res, 0));
|
|
|
+ strcpy(unit.name, sqlite3_column_text(res, 1));
|
|
|
+ unit.base_hp = sqlite3_column_int(res, 2);
|
|
|
+ unit.base_atk = sqlite3_column_int(res, 3);
|
|
|
+ unit.base_def = sqlite3_column_int(res, 4);
|
|
|
+ unit.base_spd = sqlite3_column_int(res, 5);
|
|
|
+ unit.base_crr = sqlite3_column_int(res, 6);
|
|
|
+ unit.base_crd = sqlite3_column_int(res, 7);
|
|
|
+ unit.base_res = sqlite3_column_int(res, 8);
|
|
|
+ unit.base_acc = sqlite3_column_int(res, 9);
|
|
|
+ unit.current_hp = sqlite3_column_int(res, 10);
|
|
|
+ unit.current_atk = sqlite3_column_int(res, 11);
|
|
|
+ unit.current_def = sqlite3_column_int(res, 12);
|
|
|
+ unit.current_spd = sqlite3_column_int(res, 13);
|
|
|
+ unit.current_crr = sqlite3_column_int(res, 14);
|
|
|
+ unit.current_crd = sqlite3_column_int(res, 15);
|
|
|
+ unit.current_res = sqlite3_column_int(res, 16);
|
|
|
+ unit.current_acc = sqlite3_column_int(res, 17);
|
|
|
+
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ printf("Unit not found: %s\n", sqlite3_errmsg(db));
|
|
|
+ return -3;
|
|
|
+ }
|
|
|
+
|
|
|
+ printf(" --------------------------\n");
|
|
|
+ printf(" | %*s |\n", -22, unit.name);
|
|
|
+ printf(" | ID: %*s |\n", -18, unit.id);
|
|
|
+ printf(" --------------------------\n");
|
|
|
+ printf(" | STAT | BASE | CURR. |\n");
|
|
|
+ printf(" --------------------------\n");
|
|
|
+ printf(" | HP: | %*d | %*d |\n", 5, unit.base_hp, 5, unit.current_hp);
|
|
|
+ printf(" | ATK: | %*d | %*d |\n", 5, unit.base_atk, 5, unit.current_atk);
|
|
|
+ printf(" | DEF: | %*d | %*d |\n", 5, unit.base_def, 5, unit.current_def);
|
|
|
+ printf(" | SPD: | %*d | %*d |\n", 5, unit.base_spd, 5, unit.current_spd);
|
|
|
+ printf(" | CRR: | %*d\% | %*d\% |\n", 5, unit.base_crr, 5, unit.current_crr);
|
|
|
+ printf(" | CRD: | %*d\% | %*d\% |\n", 5, unit.base_crd, 5, unit.current_crd);
|
|
|
+ printf(" | RES: | %*d\% | %*d\% |\n", 5, unit.base_res, 5, unit.current_res);
|
|
|
+ printf(" | ACC: | %*d\% | %*d\% |\n", 5, unit.base_acc, 5, unit.current_acc);
|
|
|
+ printf(" --------------------------\n");
|
|
|
+
|
|
|
+ struct Stats min_stats;
|
|
|
+ // TODO: DEBUG: Read from parameters
|
|
|
+ min_stats.hp = unit.current_hp *1;
|
|
|
+ min_stats.atk = unit.current_atk *1;
|
|
|
+ min_stats.def = unit.current_def *1;
|
|
|
+ min_stats.spd = unit.current_spd *1;
|
|
|
+ min_stats.crr = unit.current_crr *1;
|
|
|
+ min_stats.crd = unit.current_crd *1;
|
|
|
+ min_stats.res = unit.current_res *1;
|
|
|
+ min_stats.acc = unit.current_acc *1;
|
|
|
+
|
|
|
+ // TODO: DEBUG: Read from parameters
|
|
|
+ int sets[3] = {RAGE, BLADE, 0};
|
|
|
+ // TODO: DEBUG: Read from parameters
|
|
|
+ int requested_stats[3] = {ATK_PERCENT, CRD, ATK_PERCENT};
|
|
|
+
|
|
|
+ // Calculate required rune count
|
|
|
+ struct Rune_Set_Count requested_set_count;
|
|
|
+ requested_set_count.energy = 0;
|
|
|
+ requested_set_count.guard = 0;
|
|
|
+ requested_set_count.swift = 0;
|
|
|
+ requested_set_count.blade = 0;
|
|
|
+ requested_set_count.rage = 0;
|
|
|
+ requested_set_count.focus = 0;
|
|
|
+ requested_set_count.endure = 0;
|
|
|
+ requested_set_count.fatal = 0;
|
|
|
+ requested_set_count.despair = 0;
|
|
|
+ requested_set_count.vampire = 0;
|
|
|
+ requested_set_count.violent = 0;
|
|
|
+ requested_set_count.nemesis = 0;
|
|
|
+ requested_set_count.will = 0;
|
|
|
+ requested_set_count.shield = 0;
|
|
|
+ requested_set_count.revenge = 0;
|
|
|
+ requested_set_count.destroy = 0;
|
|
|
+ requested_set_count.fight = 0;
|
|
|
+ requested_set_count.determination = 0;
|
|
|
+ requested_set_count.enhance = 0;
|
|
|
+ requested_set_count.accuracy = 0;
|
|
|
+ requested_set_count.tolerance = 0;
|
|
|
+ printf("Requested sets:\n");
|
|
|
+ for (int i = 0; i < 2; i ++){
|
|
|
+ switch (sets[i]){
|
|
|
+ case ENERGY:
|
|
|
+ printf(" - ENERGY\n");
|
|
|
+ requested_set_count.energy += 2;
|
|
|
+ break;
|
|
|
+ case GUARD:
|
|
|
+ printf(" - GUARD\n");
|
|
|
+ requested_set_count.guard += 2;
|
|
|
+ break;
|
|
|
+ case SWIFT:
|
|
|
+ printf(" - SWIFT\n");
|
|
|
+ requested_set_count.swift += 4;
|
|
|
+ break;
|
|
|
+ case BLADE:
|
|
|
+ printf(" - BLADE\n");
|
|
|
+ requested_set_count.blade += 2;
|
|
|
+ break;
|
|
|
+ case RAGE:
|
|
|
+ printf(" - RAGE\n");
|
|
|
+ requested_set_count.rage += 4;
|
|
|
+ break;
|
|
|
+ case FOCUS:
|
|
|
+ printf(" - FOCUS\n");
|
|
|
+ requested_set_count.focus += 2;
|
|
|
+ break;
|
|
|
+ case ENDURE:
|
|
|
+ printf(" - ENDURE\n");
|
|
|
+ requested_set_count.endure += 2;
|
|
|
+ break;
|
|
|
+ case FATAL:
|
|
|
+ printf(" - FATAL\n");
|
|
|
+ requested_set_count.fatal += 4;
|
|
|
+ break;
|
|
|
+ case DESPAIR:
|
|
|
+ printf(" - DESPAIR\n");
|
|
|
+ requested_set_count.despair += 2;
|
|
|
+ break;
|
|
|
+ case VAMPIRE:
|
|
|
+ printf(" - VAMPIRE\n");
|
|
|
+ requested_set_count.vampire += 4;
|
|
|
+ break;
|
|
|
+ case VIOLENT:
|
|
|
+ printf(" - VIOLENT\n");
|
|
|
+ requested_set_count.violent += 4;
|
|
|
+ break;
|
|
|
+ case NEMESIS:
|
|
|
+ printf(" - NEMESIS\n");
|
|
|
+ requested_set_count.nemesis += 2;
|
|
|
+ break;
|
|
|
+ case WILL:
|
|
|
+ printf(" - WILL\n");
|
|
|
+ requested_set_count.will += 2;
|
|
|
+ break;
|
|
|
+ case SHIELD:
|
|
|
+ printf(" - SHIELD\n");
|
|
|
+ requested_set_count.shield += 2;
|
|
|
+ break;
|
|
|
+ case REVENGE:
|
|
|
+ printf(" - REVENGE\n");
|
|
|
+ requested_set_count.revenge += 2;
|
|
|
+ break;
|
|
|
+ case DESTROY:
|
|
|
+ printf(" - DESTROY\n");
|
|
|
+ requested_set_count.destroy += 2;
|
|
|
+ break;
|
|
|
+ case FIGHT:
|
|
|
+ printf(" - FIGHT\n");
|
|
|
+ requested_set_count.fight += 2;
|
|
|
+ break;
|
|
|
+ case DETERMINATION:
|
|
|
+ printf(" - DETERMINATION\n");
|
|
|
+ requested_set_count.determination += 2;
|
|
|
+ break;
|
|
|
+ case ENHANCE:
|
|
|
+ printf(" - ENHANCE\n");
|
|
|
+ requested_set_count.enhance += 2;
|
|
|
+ break;
|
|
|
+ case ACCURACY:
|
|
|
+ printf(" - ACCURACY\n");
|
|
|
+ requested_set_count.accuracy += 2;
|
|
|
+ break;
|
|
|
+ case TOLERANCE:
|
|
|
+ printf(" - TOLERANCE\n");
|
|
|
+ requested_set_count.tolerance += 2;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // TODO: Debug: Get this from parameters
|
|
|
+ int requested_level = 15;
|
|
|
+ char requested_level_column[] = "lv15_";
|
|
|
+
|
|
|
+ // Create queries for each slot
|
|
|
+ char query_odd[2500] = "SELECT id, unit, type, ";
|
|
|
+ strcat(query_odd, requested_level_column);
|
|
|
+ strcat(query_odd, "hp_flat, ");
|
|
|
+ strcat(query_odd, requested_level_column);
|
|
|
+ strcat(query_odd, "atk_flat, ");
|
|
|
+ strcat(query_odd, requested_level_column);
|
|
|
+ strcat(query_odd, "def_flat, ");
|
|
|
+ strcat(query_odd, requested_level_column);
|
|
|
+ strcat(query_odd, "hp_percent, ");
|
|
|
+ strcat(query_odd, requested_level_column);
|
|
|
+ strcat(query_odd, "atk_percent, ");
|
|
|
+ strcat(query_odd, requested_level_column);
|
|
|
+ strcat(query_odd, "def_percent, ");
|
|
|
+ strcat(query_odd, requested_level_column);
|
|
|
+ strcat(query_odd, "spd, ");
|
|
|
+ strcat(query_odd, requested_level_column);
|
|
|
+ strcat(query_odd, "crr, ");
|
|
|
+ strcat(query_odd, requested_level_column);
|
|
|
+ strcat(query_odd, "crd, ");
|
|
|
+ strcat(query_odd, requested_level_column);
|
|
|
+ strcat(query_odd, "res, ");
|
|
|
+ strcat(query_odd, requested_level_column);
|
|
|
+ strcat(query_odd, "acc FROM runes WHERE slot = ? AND type IN (");
|
|
|
+ char cur_set[2];
|
|
|
+ char stat_set[2];
|
|
|
+ if (sets[0] != 0){
|
|
|
+ sprintf(cur_set, "%d", sets[0]);
|
|
|
+ strcat(query_odd, cur_set);
|
|
|
+ strcat(query_odd, ", ");
|
|
|
+ }
|
|
|
+ if (sets[1] != 0){
|
|
|
+ sprintf(cur_set, "%d", sets[1]);
|
|
|
+ strcat(query_odd, cur_set);
|
|
|
+ strcat(query_odd, ", ");
|
|
|
+ }
|
|
|
+ if (sets[2] != 0){
|
|
|
+ sprintf(cur_set, "%d", sets[2]);
|
|
|
+ strcat(query_odd, cur_set);
|
|
|
+ strcat(query_odd, ", ");
|
|
|
+ }
|
|
|
+ strcat(query_odd, "-1) ");
|
|
|
+ // TODO: Add team stuff
|
|
|
+
|
|
|
+
|
|
|
+ //printf("- QUERY ODD: %s\n", query_odd);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ char query_even[1500] = "SELECT id, unit, type, ";
|
|
|
+ strcat(query_even, requested_level_column);
|
|
|
+ strcat(query_even, "hp_flat, ");
|
|
|
+ strcat(query_even, requested_level_column);
|
|
|
+ strcat(query_even, "atk_flat, ");
|
|
|
+ strcat(query_even, requested_level_column);
|
|
|
+ strcat(query_even, "def_flat, ");
|
|
|
+ strcat(query_even, requested_level_column);
|
|
|
+ strcat(query_even, "hp_percent, ");
|
|
|
+ strcat(query_even, requested_level_column);
|
|
|
+ strcat(query_even, "atk_percent, ");
|
|
|
+ strcat(query_even, requested_level_column);
|
|
|
+ strcat(query_even, "def_percent, ");
|
|
|
+ strcat(query_even, requested_level_column);
|
|
|
+ strcat(query_even, "spd, ");
|
|
|
+ strcat(query_even, requested_level_column);
|
|
|
+ strcat(query_even, "crr, ");
|
|
|
+ strcat(query_even, requested_level_column);
|
|
|
+ strcat(query_even, "crd, ");
|
|
|
+ strcat(query_even, requested_level_column);
|
|
|
+ strcat(query_even, "res, ");
|
|
|
+ strcat(query_even, requested_level_column);
|
|
|
+ strcat(query_even, "acc FROM runes WHERE slot = ? AND type IN (");
|
|
|
+ if (sets[0] != 0){
|
|
|
+ sprintf(cur_set, "%d", sets[0]);
|
|
|
+ strcat(query_even, cur_set);
|
|
|
+ strcat(query_even, ", ");
|
|
|
+ }
|
|
|
+ if (sets[1] != 0){
|
|
|
+ sprintf(cur_set, "%d", sets[1]);
|
|
|
+ strcat(query_even, cur_set);
|
|
|
+ strcat(query_even, ", ");
|
|
|
+ }
|
|
|
+ if (sets[2] != 0){
|
|
|
+ sprintf(cur_set, "%d", sets[2]);
|
|
|
+ strcat(query_even, cur_set);
|
|
|
+ strcat(query_even, ", ");
|
|
|
+ }
|
|
|
+ strcat(query_even, "-1) AND main_stat IN (");
|
|
|
+
|
|
|
+ if (requested_stats[0] != 0){
|
|
|
+ sprintf(stat_set, "%d", requested_stats[0]);
|
|
|
+ strcat(query_even, stat_set);
|
|
|
+ strcat(query_even, ", ");
|
|
|
+ }
|
|
|
+ if (requested_stats[1] != 0){
|
|
|
+ sprintf(stat_set, "%d", requested_stats[1]);
|
|
|
+ strcat(query_even, stat_set);
|
|
|
+ strcat(query_even, ", ");
|
|
|
+ }
|
|
|
+ if (requested_stats[2] != 0){
|
|
|
+ sprintf(stat_set, "%d", requested_stats[2]);
|
|
|
+ strcat(query_even, stat_set);
|
|
|
+ strcat(query_even, ", ");
|
|
|
+ }
|
|
|
+
|
|
|
+ strcat(query_even, "-1) ");
|
|
|
+ // TODO: Add team stuff
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ int rune_count[7];
|
|
|
+ /*char query_even_count[1500] = "SELECT count(*) AS c FROM(";
|
|
|
+ strcat(query_even_count, query_even);
|
|
|
+ strcat(query_even_count, ")");
|
|
|
+ char query_odd_count[1500] = "SELECT count(*) AS c FROM(";
|
|
|
+ strcat(query_odd_count, query_odd);
|
|
|
+ strcat(query_odd_count, ")");
|
|
|
+
|
|
|
+ sqlite3_stmt *rune_counts[7];
|
|
|
+
|
|
|
+ db_status = sqlite3_prepare_v2(db, query_odd_count, -1, &rune_counts[1], 0);
|
|
|
+ if (db_status != SQLITE_OK) {
|
|
|
+ printf("Error counting runes for slot 1: %s\n", sqlite3_errmsg(db));
|
|
|
+ return -6;
|
|
|
+ }
|
|
|
+ sqlite3_bind_int(rune_counts[1], 1, 1);
|
|
|
+ db_status = sqlite3_prepare_v2(db, query_odd_count, -1, &rune_counts[3], 0);
|
|
|
+ if (db_status != SQLITE_OK) {
|
|
|
+ printf("Error counting runes for slot 3: %s\n", sqlite3_errmsg(db));
|
|
|
+ return -6;
|
|
|
+ }
|
|
|
+ sqlite3_bind_int(rune_counts[3], 1, 3);
|
|
|
+ db_status = sqlite3_prepare_v2(db, query_odd_count, -1, &rune_counts[5], 0);
|
|
|
+ if (db_status != SQLITE_OK) {
|
|
|
+ printf("Error counting runes for slot 5: %s\n", sqlite3_errmsg(db));
|
|
|
+ return -6;
|
|
|
+ }
|
|
|
+ sqlite3_bind_int(rune_counts[5], 1, 5);
|
|
|
+ db_status = sqlite3_prepare_v2(db, query_even_count, 2500, &rune_counts[2], 0);
|
|
|
+ if (db_status != SQLITE_OK) {
|
|
|
+ printf("Error counting runes for slot 2: %s\n", sqlite3_errmsg(db));
|
|
|
+ return -6;
|
|
|
+ }
|
|
|
+ sqlite3_bind_int(rune_counts[2], 1, 2);
|
|
|
+ db_status = sqlite3_prepare_v2(db, query_even_count, 2500, &rune_counts[4], 0);
|
|
|
+ if (db_status != SQLITE_OK) {
|
|
|
+ printf("Error counting runes for slot 4: %s\n", sqlite3_errmsg(db));
|
|
|
+ return -6;
|
|
|
+ }
|
|
|
+ sqlite3_bind_int(rune_counts[4], 1, 4);
|
|
|
+ db_status = sqlite3_prepare_v2(db, query_even_count, -1, &rune_counts[6], 0);
|
|
|
+ if (db_status != SQLITE_OK) {
|
|
|
+ printf("Error counting runes for slot 6: %s\n", sqlite3_errmsg(db));
|
|
|
+ return -6;
|
|
|
+ }
|
|
|
+ sqlite3_bind_int(rune_counts[6], 1, 6);
|
|
|
+
|
|
|
+ int max_rune_count = 0;
|
|
|
+ for (int i = 1; i < 7; i ++){
|
|
|
+ int step = sqlite3_step(rune_counts[i]);
|
|
|
+ if (step == SQLITE_ROW) {
|
|
|
+ printf(" - Available runes in slot %d: %d\n", i, sqlite3_column_int(rune_counts[i], 0));
|
|
|
+ if (sqlite3_column_int(rune_counts[i], 0) == 0){
|
|
|
+ printf(" - No availbale runes for slot %d\n", i);
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ rune_count[i] = sqlite3_column_int(rune_counts[i], 0);
|
|
|
+ if (rune_count[i] > max_rune_count){
|
|
|
+ max_rune_count = rune_count[i];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }*/
|
|
|
+
|
|
|
+ sqlite3_stmt *stmt_runes[7];
|
|
|
+ struct Rune runes[7][600];
|
|
|
+ db_status = sqlite3_prepare_v2(db, query_odd, -1, &stmt_runes[1], 0);
|
|
|
+ if (db_status != SQLITE_OK) {
|
|
|
+ printf("Error getting runes for slot 1: %s\n", sqlite3_errmsg(db));
|
|
|
+ return -7;
|
|
|
+ }
|
|
|
+ sqlite3_bind_int(stmt_runes[1], 1, 1);
|
|
|
+ db_status = sqlite3_prepare_v2(db, query_odd, -1, &stmt_runes[3], 0);
|
|
|
+ if (db_status != SQLITE_OK) {
|
|
|
+ printf("Error getting runes for slot 3: %s\n", sqlite3_errmsg(db));
|
|
|
+ return -7;
|
|
|
+ }
|
|
|
+ sqlite3_bind_int(stmt_runes[3], 1, 3);
|
|
|
+ db_status = sqlite3_prepare_v2(db, query_odd, -1, &stmt_runes[5], 0);
|
|
|
+ if (db_status != SQLITE_OK) {
|
|
|
+ printf("Error getting runes for slot 5: %s\n", sqlite3_errmsg(db));
|
|
|
+ return -7;
|
|
|
+ }
|
|
|
+ sqlite3_bind_int(stmt_runes[5], 1, 5);
|
|
|
+ db_status = sqlite3_prepare_v2(db, query_odd, -1, &stmt_runes[2], 0);
|
|
|
+ if (db_status != SQLITE_OK) {
|
|
|
+ printf("Error getting runes for slot 2: %s\n", sqlite3_errmsg(db));
|
|
|
+ return -7;
|
|
|
+ }
|
|
|
+ sqlite3_bind_int(stmt_runes[2], 1, 2);
|
|
|
+ db_status = sqlite3_prepare_v2(db, query_odd, -1, &stmt_runes[4], 0);
|
|
|
+ if (db_status != SQLITE_OK) {
|
|
|
+ printf("Error getting runes for slot 4: %s\n", sqlite3_errmsg(db));
|
|
|
+ return -7;
|
|
|
+ }
|
|
|
+ sqlite3_bind_int(stmt_runes[4], 1, 4);
|
|
|
+ db_status = sqlite3_prepare_v2(db, query_odd, -1, &stmt_runes[6], 0);
|
|
|
+ if (db_status != SQLITE_OK) {
|
|
|
+ printf("Error getting runes for slot 6: %s\n", sqlite3_errmsg(db));
|
|
|
+ return -7;
|
|
|
+ }
|
|
|
+ sqlite3_bind_int(stmt_runes[6], 1, 6);
|
|
|
+
|
|
|
+
|
|
|
+ // Get and populate all the runes
|
|
|
+ for (int i = 1; i < 7; i ++){
|
|
|
+ int j = 0;
|
|
|
+ //printf("BEGIN SLOT %d\n", i);
|
|
|
+ while (1 == 1){
|
|
|
+ int status = sqlite3_step(stmt_runes[i]);
|
|
|
+ //printf("STATUS: %d ", status);
|
|
|
+ if (status == SQLITE_ROW){
|
|
|
+ //printf(" - (%d) Slot %d, Rune ID %s\n", j, i, sqlite3_column_text(stmt_runes[i], 0));
|
|
|
+ strcpy(runes[i][j].id, sqlite3_column_text(stmt_runes[i], 0));
|
|
|
+ strcpy(runes[i][j].unit, sqlite3_column_text(stmt_runes[i], 1));
|
|
|
+ runes[i][j].set = sqlite3_column_int(stmt_runes[i], 2);
|
|
|
+ runes[i][j].hp_flat = sqlite3_column_int(stmt_runes[i], 3);
|
|
|
+ runes[i][j].atk_flat = sqlite3_column_int(stmt_runes[i], 4);
|
|
|
+ runes[i][j].def_flat = sqlite3_column_int(stmt_runes[i], 5);
|
|
|
+ runes[i][j].hp_percent = sqlite3_column_int(stmt_runes[i], 6);
|
|
|
+ runes[i][j].atk_percent = sqlite3_column_int(stmt_runes[i], 7);
|
|
|
+ runes[i][j].def_percent = sqlite3_column_int(stmt_runes[i], 8);
|
|
|
+ runes[i][j].spd = sqlite3_column_int(stmt_runes[i], 9);
|
|
|
+ runes[i][j].crr = sqlite3_column_int(stmt_runes[i], 10);
|
|
|
+ runes[i][j].crd = sqlite3_column_int(stmt_runes[i], 11);
|
|
|
+ runes[i][j].res = sqlite3_column_int(stmt_runes[i], 12);
|
|
|
+ runes[i][j].acc = sqlite3_column_int(stmt_runes[i], 13);
|
|
|
+ j ++;
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ rune_count[i] = j;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int i = 1; i < 7; i ++){
|
|
|
+ printf(" - Available runes in slot %d: %d\n", i, rune_count[i]);
|
|
|
+ if (rune_count[i] == 0){
|
|
|
+ printf(" - No availbale runes for slot %d\n", i);
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ unsigned long max_combinations =
|
|
|
+ rune_count[1] *
|
|
|
+ rune_count[2] *
|
|
|
+ rune_count[3] *
|
|
|
+ rune_count[4] *
|
|
|
+ rune_count[5] *
|
|
|
+ rune_count[6];
|
|
|
+ printf(" - Combinations to try: %d\n", max_combinations);
|
|
|
+
|
|
|
+ // Now its time to loop all 6 reels of runes and try to match combos
|
|
|
+ int index[7] = {0, 0, 0, 0, 0, 0};
|
|
|
+ unsigned long tested_combinations = 0;
|
|
|
+ unsigned long valid_sets = 0;
|
|
|
+ unsigned long result_count = 0;
|
|
|
+ Result results[1000];
|
|
|
+ while(
|
|
|
+ index[1] < rune_count[1] &&
|
|
|
+ index[2] < rune_count[2] &&
|
|
|
+ index[3] < rune_count[3] &&
|
|
|
+ index[4] < rune_count[4] &&
|
|
|
+ index[5] < rune_count[5] &&
|
|
|
+ index[6] < rune_count[6]
|
|
|
+ ){
|
|
|
+ if (tested_combinations % 10000000 == 0 && tested_combinations != 0){
|
|
|
+ printf("10M loops: TOTAL: %d\n", tested_combinations);
|
|
|
+ }
|
|
|
+ //printf("loop %d\n", tested_combinations);
|
|
|
+ struct Rune_Set_Count set_count;
|
|
|
+ set_count.energy = 0;
|
|
|
+ set_count.guard = 0;
|
|
|
+ set_count.swift = 0;
|
|
|
+ set_count.blade = 0;
|
|
|
+ set_count.rage = 0;
|
|
|
+ set_count.focus = 0;
|
|
|
+ set_count.endure = 0;
|
|
|
+ set_count.fatal = 0;
|
|
|
+ set_count.despair = 0;
|
|
|
+ set_count.vampire = 0;
|
|
|
+ set_count.violent = 0;
|
|
|
+ set_count.nemesis = 0;
|
|
|
+ set_count.will = 0;
|
|
|
+ set_count.shield = 0;
|
|
|
+ set_count.revenge = 0;
|
|
|
+ set_count.destroy = 0;
|
|
|
+ set_count.fight = 0;
|
|
|
+ set_count.determination = 0;
|
|
|
+ set_count.enhance = 0;
|
|
|
+ set_count.accuracy = 0;
|
|
|
+ set_count.tolerance = 0;
|
|
|
+ for (int i = 1; i < 7; i ++){
|
|
|
+ switch (runes[i][index[i]].set){
|
|
|
+ case ENERGY:
|
|
|
+ set_count.energy ++;
|
|
|
+ break;
|
|
|
+ case GUARD:
|
|
|
+ set_count.guard ++;
|
|
|
+ break;
|
|
|
+ case SWIFT:
|
|
|
+ set_count.swift ++;
|
|
|
+ break;
|
|
|
+ case BLADE:
|
|
|
+ set_count.blade ++;
|
|
|
+ break;
|
|
|
+ case RAGE:
|
|
|
+ set_count.rage ++;
|
|
|
+ break;
|
|
|
+ case FOCUS:
|
|
|
+ set_count.focus ++;
|
|
|
+ break;
|
|
|
+ case ENDURE:
|
|
|
+ set_count.endure ++;
|
|
|
+ break;
|
|
|
+ case FATAL:
|
|
|
+ set_count.fatal ++;
|
|
|
+ break;
|
|
|
+ case DESPAIR:
|
|
|
+ set_count.despair ++;
|
|
|
+ break;
|
|
|
+ case VAMPIRE:
|
|
|
+ set_count.vampire ++;
|
|
|
+ break;
|
|
|
+ case VIOLENT:
|
|
|
+ set_count.violent ++;
|
|
|
+ break;
|
|
|
+ case NEMESIS:
|
|
|
+ set_count.nemesis ++;
|
|
|
+ break;
|
|
|
+ case WILL:
|
|
|
+ set_count.will ++;
|
|
|
+ break;
|
|
|
+ case SHIELD:
|
|
|
+ set_count.shield ++;
|
|
|
+ break;
|
|
|
+ case REVENGE:
|
|
|
+ set_count.revenge ++;
|
|
|
+ break;
|
|
|
+ case DESTROY:
|
|
|
+ set_count.destroy ++;
|
|
|
+ break;
|
|
|
+ case FIGHT:
|
|
|
+ set_count.fight ++;
|
|
|
+ break;
|
|
|
+ case DETERMINATION:
|
|
|
+ set_count.determination ++;
|
|
|
+ break;
|
|
|
+ case ENHANCE:
|
|
|
+ set_count.enhance ++;
|
|
|
+ break;
|
|
|
+ case ACCURACY:
|
|
|
+ set_count.accuracy ++;
|
|
|
+ break;
|
|
|
+ case TOLERANCE:
|
|
|
+ set_count.tolerance ++;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // Compare with requested sets
|
|
|
+ if (
|
|
|
+ set_count.energy >= requested_set_count.energy &&
|
|
|
+ set_count.guard >= requested_set_count.guard &&
|
|
|
+ set_count.swift >= requested_set_count.swift &&
|
|
|
+ set_count.blade >= requested_set_count.blade &&
|
|
|
+ set_count.rage >= requested_set_count.rage &&
|
|
|
+ set_count.focus >= requested_set_count.focus &&
|
|
|
+ set_count.endure >= requested_set_count.endure &&
|
|
|
+ set_count.fatal >= requested_set_count.fatal &&
|
|
|
+ set_count.despair >= requested_set_count.despair &&
|
|
|
+ set_count.vampire >= requested_set_count.vampire &&
|
|
|
+ set_count.violent >= requested_set_count.violent &&
|
|
|
+ set_count.nemesis >= requested_set_count.nemesis &&
|
|
|
+ set_count.will >= requested_set_count.will &&
|
|
|
+ set_count.shield >= requested_set_count.shield &&
|
|
|
+ set_count.revenge >= requested_set_count.revenge &&
|
|
|
+ set_count.destroy >= requested_set_count.destroy &&
|
|
|
+ set_count.fight >= requested_set_count.fight &&
|
|
|
+ set_count.determination >= requested_set_count.determination &&
|
|
|
+ set_count.enhance >= requested_set_count.enhance &&
|
|
|
+ set_count.accuracy >= requested_set_count.accuracy &&
|
|
|
+ set_count.tolerance >= requested_set_count.tolerance
|
|
|
+ ){
|
|
|
+ valid_sets ++;
|
|
|
+ //printf("Valid set found: TOTAL: %d\n", valid_sets);
|
|
|
+
|
|
|
+ // Calculate new stats
|
|
|
+ struct Stats stats;
|
|
|
+ stats.hp = unit.base_hp;
|
|
|
+ stats.atk = unit.base_atk;
|
|
|
+ stats.def = unit.base_def;
|
|
|
+ stats.spd = unit.base_spd;
|
|
|
+ stats.crr = unit.base_crr;
|
|
|
+ stats.crd = unit.base_crd;
|
|
|
+ stats.res = unit.base_res;
|
|
|
+ stats.acc = unit.base_acc;
|
|
|
+ for (int i = 1; i < 7; i ++){
|
|
|
+ stats.hp += runes[i][index[i]].hp_flat;
|
|
|
+ stats.atk += runes[i][index[i]].atk_flat;
|
|
|
+ stats.def += runes[i][index[i]].def_flat;
|
|
|
+ stats.hp += unit.base_hp * runes[i][index[i]].hp_percent / 100;
|
|
|
+ stats.atk += unit.base_hp * runes[i][index[i]].atk_percent / 100;
|
|
|
+ stats.def += unit.base_hp * runes[i][index[i]].def_percent / 100;
|
|
|
+ stats.spd += runes[i][index[i]].spd;
|
|
|
+ stats.crr += runes[i][index[i]].crr;
|
|
|
+ stats.crd += runes[i][index[i]].crd;
|
|
|
+ stats.res += runes[i][index[i]].res;
|
|
|
+ stats.acc += runes[i][index[i]].acc;
|
|
|
+ }
|
|
|
+ // Compare with minimum requeriments
|
|
|
+ if (
|
|
|
+ stats.hp >= min_stats.hp &&
|
|
|
+ stats.atk >= min_stats.atk &&
|
|
|
+ stats.def >= min_stats.def &&
|
|
|
+ stats.spd >= min_stats.spd &&
|
|
|
+ stats.crr >= min_stats.crr &&
|
|
|
+ stats.crd >= min_stats.crd &&
|
|
|
+ stats.res >= min_stats.res &&
|
|
|
+ stats.acc >= min_stats.acc
|
|
|
+ ){
|
|
|
+ for (int i = 1; i < 7; i ++)
|
|
|
+ strcpy(results[result_count].rune_ids[i - 1], runes[i][index[i]].id);
|
|
|
+ result_count ++;
|
|
|
+ //printf("Result found: %d\n", results);
|
|
|
+ }
|
|
|
+ results[result_count].rating = 0;
|
|
|
+ results[result_count].rating += ((stats.hp - unit.current_hp) / 15);
|
|
|
+ results[result_count].rating += (stats.atk - unit.current_atk);
|
|
|
+ results[result_count].rating += (stats.def - unit.current_def);
|
|
|
+ results[result_count].rating += (stats.spd - unit.current_spd);
|
|
|
+ results[result_count].rating += (stats.crr - unit.current_crr);
|
|
|
+ results[result_count].rating += (stats.crd - unit.current_crd);
|
|
|
+ results[result_count].rating += (stats.res - unit.current_res);
|
|
|
+ results[result_count].rating += (stats.acc - unit.current_acc);
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ //printf("NO valid set found: TOTAL: %d\n", valid_sets);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ // Loop action
|
|
|
+ // First, form a set and check if mathces the requested;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ // Loop control
|
|
|
+ //printf(" - Looping index 6: %d / %d\n", index[6], rune_count[6]);
|
|
|
+ tested_combinations ++;
|
|
|
+ index[6] ++;
|
|
|
+ if (index[6] == rune_count[6]){
|
|
|
+ //printf(" - Looping index 5: %d / %d\n", index[5], rune_count[5]);
|
|
|
+ index[6] = 0;
|
|
|
+ index[5] ++;
|
|
|
+ }
|
|
|
+ if (index[5] == rune_count[5]){
|
|
|
+ //printf(" - Looping index 4: %d / %d\n", index[4], rune_count[4]);
|
|
|
+ index[5] = 0;
|
|
|
+ index[4] ++;
|
|
|
+ }
|
|
|
+ if (index[4] == rune_count[4]){
|
|
|
+ //printf(" - Looping index 3: %d / %d\n", index[3], rune_count[3]);
|
|
|
+ index[4] = 0;
|
|
|
+ index[3] ++;
|
|
|
+ }
|
|
|
+ if (index[3] == rune_count[3]){
|
|
|
+ //printf(" - Looping index 2: %d / %d\n", index[2], rune_count[2]);
|
|
|
+ index[3] = 0;
|
|
|
+ index[2] ++;
|
|
|
+ }
|
|
|
+ if (index[2] == rune_count[2]){
|
|
|
+ //printf(" - Looping index 1: %d / %d\n", index[1], rune_count[1]);
|
|
|
+ index[2] = 0;
|
|
|
+ index[1] ++;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*printf(" - CHECK index 1: %d / %d\n", index[1], rune_count[1]);
|
|
|
+ printf(" - CHECK index 2: %d / %d\n", index[2], rune_count[2]);
|
|
|
+ printf(" - CHECK index 3: %d / %d\n", index[3], rune_count[3]);
|
|
|
+ printf(" - CHECK index 4: %d / %d\n", index[4], rune_count[4]);
|
|
|
+ printf(" - CHECK index 5: %d / %d\n", index[5], rune_count[5]);
|
|
|
+ printf(" - CHECK index 6: %d / %d\n", index[6], rune_count[6]);*/
|
|
|
+ }
|
|
|
+ printf("Valid sets found: TOTAL: %d\n", valid_sets);
|
|
|
+ printf("Results found: TOTAL: %d\n", result_count);
|
|
|
+
|
|
|
+//"base_hp, base_atk, base_def, base_spd, base_crr, base_crd, base_res, base_acc, "
|
|
|
+// "current_hp, current_atk, current_def, current_spd, current_crr, current_crd, current_res, current_acc "
|
|
|
+// "FROM units WHERE id = ? OR name = ?";
|
|
|
+
|
|
|
+ printf("ENDING\n");
|
|
|
+
|
|
|
+ sqlite3_finalize(res);
|
|
|
+ sqlite3_close(db);
|
|
|
+
|
|
|
+ /*
|
|
|
+
|
|
|
+ rc = sqlite3_exec(db, sql, callback, 0, &err_msg);
|
|
|
+
|
|
|
+ if (rc != SQLITE_OK ) {
|
|
|
+
|
|
|
+ fprintf(stderr, "Failed to select data\n");
|
|
|
+ fprintf(stderr, "SQL error: %s\n", err_msg);
|
|
|
+
|
|
|
+ sqlite3_free(err_msg);
|
|
|
+ sqlite3_close(db);
|
|
|
+
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ sqlite3_close(db);
|
|
|
+
|
|
|
+ */
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+int unit_callback(void *NotUsed, int argc, char **argv, char **azColName) {
|
|
|
+
|
|
|
+ NotUsed = 0;
|
|
|
+
|
|
|
+ for (int i = 0; i < argc; i++) {
|
|
|
+
|
|
|
+ printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
|
|
|
+ }
|
|
|
+
|
|
|
+ printf("\n");
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+int md_comparator(const void *v1, const void *v2){
|
|
|
+ const Result *p1 = (Result *)v1;
|
|
|
+ const Result *p2 = (Result *)v2;
|
|
|
+ if (p1->rating < p2->rating)
|
|
|
+ return -1;
|
|
|
+ else if (p1->rating > p2->rating)
|
|
|
+ return +1;
|
|
|
+ else
|
|
|
+ return 0;
|
|
|
+}
|