/* Copyright (C) 2007 target0 (target0@geeknode.org) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* ogame command-line development simulator. Please, don't ask me how it works :) */ #include #include #include #include #include #define prod_metal ((30 * level_metal * pow(1.1,level_metal) * (pc_metal/100) * facteur_prod) + 20) #define conso_metal (10 * level_metal * pow(1.1,level_metal) * (pc_metal/100)) #define cout_metal_1 (60 * pow(1.5, level_metal)) #define cout_metal_2 (15 * pow(1.5,level_metal)) #define temps_metal (((cout_metal_1+cout_metal_2)/5000) * (2/(1+level_robot))*(pow(0.5,level_nanite))*3600) #define prod_cristal ((20 * level_cristal * pow(1.1,level_cristal) * (pc_cristal/100) * facteur_prod) + 10) #define conso_cristal (10 * level_cristal * pow(1.1,level_cristal) * (pc_cristal/100)) #define cout_cristal_1 (48 * pow(1.6,level_cristal)) #define cout_cristal_2 (24 * pow(1.6,level_cristal)) #define temps_cristal (((cout_cristal_1+cout_cristal_2)/5000) * (2/(1+level_robot))*(pow(0.5,level_nanite))*3600) #define prod_deut (10 * level_deut * pow(1.1,level_deut) * ((-0.002) * t_max + 1.28) * (pc_deut/100) * facteur_prod) #define conso_deut (20 * level_deut * pow(1.1,level_deut) * (pc_deut/100)) #define cout_deut_1 (225 * pow(1.5,level_deut)) #define cout_deut_2 (75 * pow(1.5,level_deut)) #define temps_deut (((cout_deut_1+cout_deut_2)/5000) * (2/(1+level_robot)) * (pow(0.5,level_nanite))*3600) #define prod_ces (20*level_ces*pow(1.1,level_ces) * (pc_ces/100)) #define cout_ces_1 (75*pow(1.5,level_ces)) #define cout_ces_2 (30*pow(1.5,level_ces)) #define temps_ces (((cout_ces_1+cout_ces_2)/5000) * (2/(1+level_robot)) * (pow(0.5,level_nanite)) * 3600) #define conso_elec (conso_metal + conso_cristal + conso_deut) #define elec_remain (prod_ces - conso_elec) //#define facteur_prod ((elec_remain < 0 && prod_ces > 0) ? ((prod_ces*100/(conso_metal+conso_cristal+conso_deut))/100) : 1) #define facteur_prod get_prod() #define cout_robot_1 (400*pow(2,level_robot)) #define cout_robot_2 (120*pow(2,level_robot)) #define cout_robot_3 (200*pow(2,level_robot)) #define temps_robot (((cout_robot_1+cout_robot_2)/5000) * (2/(1+level_robot))*(pow(0.5,level_nanite))*3600) #define cout_chantier_1 (400*pow(2,level_chantier)) #define cout_chantier_2 (200*pow(2,level_chantier)) #define cout_chantier_3 (100*pow(2,level_chantier)) #define temps_chantier (((cout_chantier_1+cout_chantier_2)/5000) * (2/(1+level_robot))*(pow(0.5,level_nanite))*3600) #define cout_labo_1 (200*pow(2,level_labo)) #define cout_labo_2 (400*pow(2,level_labo)) #define cout_labo_3 (200*pow(2,level_labo)) #define temps_labo (((cout_labo_1+cout_labo_2) / 5000) * (2/(1+level_robot)) * (pow(0.5,level_nanite)) * 3600) #define cout_energie_2 (800*pow(2,level_energie)) #define cout_energie_3 (400*pow(2,level_energie)) #define temps_energie ((cout_energie_2)/(1000*(1+level_labo))*3600) #define cout_combu_1 (400*pow(2,level_combu)) #define cout_combu_3 (600*pow(2,level_combu)) #define temps_combu ((cout_combu_1)/(1000*(1+level_labo))*3600) #define temps_pt (((2000+2000)/5000)*(2/(1+level_chantier))*pow(0.5,level_nanite)*3600) #define max(x, y) (x > y ? x : y) #define Strcmp strcasecmp #define list2_insert_tail(x, y) { \ (y)->prev = (y)->next = NULL; \ if ((x).size > 0) { \ (x).tail->next = (y); \ (y)->prev = (x).tail; \ } else \ (x).head = (y); \ (x).tail = (y); \ (x).size++; \ } #define list2_remove(x, y) { \ if ((x).size == 1) { \ (x).head = NULL; \ (x).tail = NULL; \ } else if ((x).head == (y)) { \ (x).head = (y)->next; \ (x).head->prev = NULL; \ } else if ((x).tail == (y)) { \ (x).tail = (y)->prev; \ (x).tail->next = NULL; \ } else { \ (y)->next->prev = (y)->prev; \ (y)->prev->next = (y)->next; \ } \ (x).size--; \ } #define list2_foreach(x, y) for ((y) = (x).head; (y); (y) = (y)->next) #define ID_METAL 'M' #define ID_CRISTAL 'C' #define ID_DEUT 'D' #define ID_CES 'S' #define ID_ROBOT 'U' #define ID_NANITE 'N' #define ID_CHANTIER 'H' #define ID_LABO 'L' #define ID_ENERGIE 'E' #define ID_COMBU 'B' #define ID_PT 'T' void nexttask(); typedef struct task { int bat; int temps; struct task *next, *prev; } Task; typedef struct { int size; Task *head, *tail; } tasklist; tasklist task_list; int level_metal, level_cristal, level_deut, level_ces; int level_robot, level_nanite, level_chantier; int level_labo, level_energie, level_combu; int metal, cristal, deut; int ts; int t_max; int pc_metal, pc_cristal, pc_deut, pc_ces; int pt; char seq[512]; char *StripBlanks (char *); float get_prod() { if (elec_remain >= 0) return 1; if (elec_remain < 0 && prod_ces > 0) return ((prod_ces*100/(conso_metal+conso_cristal+conso_deut))/100); if (prod_ces == 0) return 0; return 0; } Task *add_task (int bat, int temps) { Task *task = (Task *)malloc(sizeof(Task)); task->bat = bat; task->temps = ts + temps; list2_insert_tail(task_list, task); return task; } void delete_task (Task *task) { list2_remove(task_list, task); free(task); } char *SeperateWord(char *sentence) { if (sentence == NULL) return NULL; while (*sentence != ' ' && *sentence != '\0' && *sentence != '\n') sentence++; if (*sentence == '\0' || *sentence == '\n') { *sentence = '\0'; return (NULL); } if (*sentence == ' ') { *sentence = '\0'; sentence++; } return (StripBlanks(sentence)); } char *StripBlanks(char *paddedstring) { if (paddedstring == NULL) return NULL; while (*paddedstring == ' ') paddedstring++; return paddedstring; } void simu_init() { level_metal = level_cristal = level_deut = level_ces = 0; level_robot = level_nanite = level_chantier = 0; level_labo = level_energie = level_combu = 0; metal = 700; cristal = 500; deut = 0; ts = 0; t_max = 13; pc_metal = pc_cristal = pc_deut = pc_ces = 100; pt = 0; memset(&task_list, 0, sizeof(task_list)); bzero(seq, 512); } void time_forward (int tts) { ts += tts; metal += prod_metal / 3600 * tts; cristal += prod_cristal / 3600 * tts; if (prod_deut > 0) deut += prod_deut / 3600 * tts; } void construct (char *arg) { float tts1, tts2, tts3, tts; int lack_m, lack_c, lack_d; if (!Strcmp(arg, "metal")) { if (metal >= cout_metal_1 && cristal >= cout_metal_2) { printf("Task enqueued now\n"); } else { lack_m = cout_metal_1 - metal; lack_c = cout_metal_2 - cristal; tts1 = (lack_m / prod_metal) * 3600; tts2 = (lack_c / prod_cristal) * 3600; tts = max(tts1, tts2); time_forward(tts); printf("Jumped %f seconds and task enqueued\n", tts); } metal -= cout_metal_1; cristal -= cout_metal_2; add_task(ID_METAL, temps_metal); strcat(seq, "M "); } else if (!Strcmp(arg, "cristal")) { if (metal >= cout_cristal_1 && cristal >= cout_cristal_2) { printf("Task enqueued now\n"); } else { lack_m = cout_cristal_1 - metal; lack_c = cout_cristal_2 - cristal; tts1 = (lack_m / prod_metal) * 3600; tts2 = (lack_c / prod_cristal) * 3600; tts = max(tts1, tts2); time_forward(tts); printf("Jumped %f seconds and task enqueued\n", tts); } metal -= cout_cristal_1; cristal -= cout_cristal_2; add_task(ID_CRISTAL, temps_cristal); strcat(seq, "C "); } else if (!Strcmp(arg, "deut")) { if (metal >= cout_deut_1 && cristal >= cout_deut_2) { printf("Task enqueued now\n"); } else { lack_m = cout_deut_1 - metal; lack_c = cout_deut_2 - cristal; tts1 = (lack_m / prod_metal) * 3600; tts2 = (lack_c / prod_cristal) * 3600; tts = max(tts1, tts2); time_forward(tts); printf("Jumped %f seconds and task enqueued\n", tts); } metal -= cout_deut_1; cristal -= cout_deut_2; add_task(ID_DEUT, temps_deut); strcat(seq, "D "); } else if (!Strcmp(arg, "ces")) { if (metal >= cout_ces_1 && cristal >= cout_ces_2) { printf("Task enqueued now\n"); } else { lack_m = cout_ces_1 - metal; lack_c = cout_ces_2 - cristal; tts1 = (lack_m / prod_metal) * 3600; tts2 = (lack_c / prod_cristal) * 3600; tts = max(tts1, tts2); time_forward(tts); printf("Jumped %f seconds and task enqueued\n", tts); } metal -= cout_ces_1; cristal -= cout_ces_2; add_task(ID_CES, temps_ces); strcat(seq, "S "); } else if (!Strcmp(arg, "robot")) { if (metal >= cout_robot_1 && cristal >= cout_robot_2 && deut >= cout_robot_3) { printf("Task enqueued now\n"); } else { lack_m = cout_robot_1 - metal; lack_c = cout_robot_2 - cristal; lack_d = cout_robot_3 - deut; tts1 = (lack_m / prod_metal) * 3600; tts2 = (lack_c / prod_cristal) * 3600; tts3 = (lack_d / prod_deut) * 3600; tts = max(tts1, tts2); tts = max(tts, tts3); time_forward(tts); printf("Jumped %f seconds and task enqueued\n", tts); } metal -= cout_robot_1; cristal -= cout_robot_2; deut -= cout_robot_3; add_task(ID_ROBOT, temps_robot); strcat(seq, "U "); } else if (!Strcmp(arg, "chantier")) { if (metal >= cout_chantier_1 && cristal >= cout_chantier_2 && deut >= cout_chantier_3) { printf("Task enqueued now\n"); } else { lack_m = cout_chantier_1 - metal; lack_c = cout_chantier_2 - cristal; lack_d = cout_chantier_3 - deut; tts1 = (lack_m / prod_metal) * 3600; tts2 = (lack_c / prod_cristal) * 3600; tts3 = (lack_d / prod_deut) * 3600; tts = max(tts1, tts2); tts = max(tts, tts3); time_forward(tts); printf("Jumped %f seconds and task enqueud\n", tts); } metal -= cout_chantier_1; cristal -= cout_chantier_2; deut -= cout_chantier_3; add_task(ID_CHANTIER, temps_chantier); strcat(seq, "H "); } else if (!Strcmp(arg, "labo")) { if (metal >= cout_labo_1 && cristal >= cout_labo_2 && deut >= cout_labo_3) { printf("Task enqueued now\n"); } else { lack_m = cout_labo_1 - metal; lack_c = cout_labo_2 - cristal; lack_d = cout_labo_3 - deut; printf("lack_m: %d, lack_c: %d, lack_d: %d\n", lack_m, lack_c, lack_d); tts1 = (lack_m / prod_metal) * 3600; tts2 = (lack_c / prod_cristal) * 3600; tts3 = (lack_d / prod_deut) * 3600; tts = max(tts1, tts2); tts = max(tts, tts3); time_forward(tts); printf("Jumped %f seconds and task enqueued\n", tts); } metal -= cout_labo_1; cristal -= cout_labo_2; deut -= cout_labo_3; add_task(ID_LABO, temps_labo); strcat(seq, "L "); } else if (!Strcmp(arg, "energie")) { if (cristal >= cout_energie_2 && deut >= cout_energie_3) { printf("Task enqueued now\n"); } else { lack_c = cout_energie_2 - cristal; lack_d = cout_energie_3 - deut; tts2 = (lack_c / prod_cristal) * 3600; tts3 = (lack_d / prod_deut) * 3600; tts = max(tts2, tts3); time_forward(tts); printf("Jumped %f seconds and task enqueued\n", tts); } cristal -= cout_energie_2; deut -= cout_energie_3; add_task(ID_ENERGIE, temps_energie); strcat(seq, "E "); } else if (!Strcmp(arg, "combu")) { if (metal >= cout_combu_1 && deut >= cout_combu_3) { printf("Task enqueued now\n"); } else { lack_m = cout_combu_1 - metal; lack_d = cout_combu_3 - deut; tts1 = (lack_m / prod_metal) * 3600; tts3 = (lack_d / prod_deut) * 3600; tts = max(tts1, tts3); time_forward(tts); printf("Jumped %f seconds and task enqueued\n", tts); } metal -= cout_combu_1; deut -= cout_combu_3; add_task(ID_COMBU, temps_combu); strcat(seq, "B "); } else if (!Strcmp(arg, "pt")) { if (metal >= 2000 && cristal >= 2000) { printf("Task enqueued now\n"); } else { lack_m = 2000 - metal; lack_c = 2000 - cristal; tts1 = (lack_m / prod_metal) * 3600; tts2 = (lack_c / prod_cristal) * 3600; tts = max(tts1,tts2); time_forward(tts); printf("Jumped %f seconds and task enqueued\n", tts); } metal -= 2000; cristal -= 2000; add_task(ID_PT, temps_pt); strcat(seq, "T "); } else { fprintf(stderr, "Unknown argument `%s'\n", arg); return; } nexttask(); } void setprod (char *arg) { char mine = *arg; arg++; switch(mine) { case 'M': pc_metal = atoi(arg); break; case 'C': pc_cristal = atoi(arg); break; case 'D': pc_deut = atoi(arg); break; default: fprintf(stderr, "Unknown mine ID `%c'\n", mine); return; } printf("Production for %c adjusted to %d\n", mine, atoi(arg)); } void showtime() { printf("Elapsed time: %d seconds\n", ts); } void showres() { printf("Available resources:\n"); printf("\tMetal: %d\n", metal); printf("\tCristal: %d\n", cristal); printf("\tDeut: %d\n", deut); } void lstask() { Task *task; printf("Waiting tasks :\n"); list2_foreach(task_list, task) { printf("\tID: %c, until %d secs\n", task->bat, task->temps); } } void nexttask() { Task *task = task_list.tail; if (task == NULL) { printf("No task\n"); return; } time_forward(task->temps - ts); switch(task->bat) { case ID_METAL: level_metal++; break; case ID_CRISTAL: level_cristal++; break; case ID_DEUT: level_deut++; break; case ID_CES: level_ces++; break; case ID_ROBOT: level_robot++; break; case ID_CHANTIER: level_chantier++; break; case ID_LABO: level_labo++; break; case ID_ENERGIE: level_energie++; break; case ID_COMBU: level_combu++; break; case ID_PT: pt++; break; } delete_task(task); // printf("Next task applied\n"); } void printseq() { printf("Sequence: %s\n", seq); } void showinfo() { printf("Batiments :\n"); printf("\tMetal: %d (prod %f)\n", level_metal, prod_metal); printf("\tCristal: %d (prod %f)\n", level_cristal, prod_cristal); printf("\tDeut: %d (prod %f)\n", level_deut, prod_deut); printf("\tCES: %d\n", level_ces); printf("\tRobot: %d\n", level_robot); printf("\tChantier: %d\n", level_chantier); printf("\tLabo: %d\n", level_labo); printf("\tEnergie: %d\n", level_energie); printf("\tCombustion: %d\n", level_combu); printf("\tPT: %d\n", pt); printf("Facteur de prod: %f\n", facteur_prod); } void convert_token (char token) { switch(token) { case ID_METAL: construct("metal"); break; case ID_CRISTAL: construct("cristal"); break; case ID_DEUT: construct("deut"); break; case ID_CES: construct("ces"); break; case ID_ROBOT: construct("robot"); break; case ID_CHANTIER: construct("chantier"); break; case ID_LABO: construct("labo"); break; case ID_ENERGIE: construct("energie"); break; case ID_COMBU: construct("combu"); break; case ID_PT: construct("pt"); } } void loadseq(char *arg, char *data) { if (!arg || *arg == '\0') { printf("Please enter a sequence\n"); return; } convert_token(*arg); if (!data || *data == '\0') return; for (; *data; data += 2) convert_token(*data); printf("Sequence loaded\n"); } int main() { simu_init(); char str[1024]; bzero(str, 1024); char *cmd, *arg, *data; printf(">> "); while(fgets(str, 1023, stdin)) { cmd = str; arg = SeperateWord(cmd); data = SeperateWord(arg); if (!Strcmp(cmd, "c")) { construct(arg); } else if (!Strcmp(cmd, "prod")) { setprod(arg); } else if (!Strcmp(cmd, "time")) { showtime(); } else if (!Strcmp(cmd, "res")) { showres(); } else if (!Strcmp(cmd, "lstask")) { lstask(); } else if (!Strcmp(cmd, "n")) { nexttask(); } else if (!Strcmp(cmd, "printseq")) { printseq(); } else if (!Strcmp(cmd, "loadseq")) { loadseq(arg, data); } else if (!Strcmp(cmd, "info")) { showinfo(); } else { fprintf(stderr, "Unknown command\n"); } printf(">> "); } return 0; }