main.c (6615B)
1 /* main.c - punto de entrada del cliente Linux. */ 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> 5 #include "version.h" 6 #include "app.h" 7 8 static void usage(void) 9 { 10 puts("catan - Catan para la terminal\n" 11 "\n" 12 " catan menu principal\n" 13 " catan hotseat [-n 2..6] [--bots N] [--2p] [--mar|--islas|--archi] [--mapa 1..5]\n" 14 " (Navegantes, 3-4: Nuevas costas, Cuatro islas, Archipielago)\n" 15 " catan resume [archivo] retomar (sin archivo: la ultima)\n" 16 " catan online [host[:puerto]] mis partidas en el servidor\n" 17 " catan host [puerto] crear partida en red local\n" 18 " catan join <host> [puerto] unirse a partida en red local\n" 19 "\n" 20 " --gui [--layout wide|compact] [--scale N] interfaz grafica (SDL)\n" 21 " --lang es|en idioma\n" 22 " --selftest pruebas del nucleo\n" 23 " --sim N [jugadores] [2p|mar|islas|archi|-] [mapa] N partidas bot contra bot\n"); 24 } 25 26 /* escenario por nombre en --sim/--duel: mar (Nuevas costas), islas, archi */ 27 static int scen_arg(const char *a) 28 { 29 if (!strcmp(a, "mar")) return SCEN_SEA1; 30 if (!strcmp(a, "islas")) return SCEN_SEA2; 31 if (!strcmp(a, "archi")) return SCEN_SEA3; 32 return SCEN_NONE; 33 } 34 35 int main(int argc, char **argv) 36 { 37 Settings st; 38 settings_load(&st); 39 settings_apply_colors(&st); 40 g_lang = st.lang; 41 42 bool gui = false; 43 const char *cmd = 0; 44 char *args[8]; 45 int nargs = 0, players = 4, bots = -1; 46 bool v2p = false; 47 int sea = 0, map = 0; 48 for (int i = 1; i < argc; i++) { 49 const char *a = argv[i]; 50 if (!strcmp(a, "--selftest")) return app_selftest(); 51 if (!strcmp(a, "--sim")) { 52 int n = i + 1 < argc ? atoi(argv[i + 1]) : 100; 53 int p = i + 2 < argc ? atoi(argv[i + 2]) : 4; 54 bool v = i + 3 < argc && !strcmp(argv[i + 3], "2p"); 55 if (i + 3 < argc) g_sim_scenario = scen_arg(argv[i + 3]); 56 if (i + 4 < argc) g_sim_map = atoi(argv[i + 4]); 57 return app_sim(n, 1, p < 2 ? 4 : p, v); 58 } 59 if (!strcmp(a, "--duel")) { 60 /* --duel N jugadores iter horizonte [2p] [semilla] [c] */ 61 int n = i + 1 < argc ? atoi(argv[i + 1]) : 20; 62 int p = i + 2 < argc ? atoi(argv[i + 2]) : 4; 63 SearchCfg c = { .iters = i + 3 < argc ? atoi(argv[i + 3]) : 500, 64 .horizon = i + 4 < argc ? atoi(argv[i + 4]) : 0, .c_ucb = 0.7f }; 65 bool v = i + 5 < argc && !strcmp(argv[i + 5], "2p"); 66 if (i + 5 < argc) g_sim_scenario = scen_arg(argv[i + 5]); 67 if (getenv("CATAN_MAP")) g_sim_map = atoi(getenv("CATAN_MAP")); 68 uint64_t seed = i + 6 < argc ? strtoull(argv[i + 6], 0, 10) : 1; 69 if (i + 7 < argc) c.c_ucb = (float)atof(argv[i + 7]); 70 return app_duel(n, seed, p < 2 ? 4 : p, v, &c); 71 } 72 if (!strcmp(a, "--help") || !strcmp(a, "-h")) { usage(); return 0; } 73 if (!strcmp(a, "--version") || !strcmp(a, "-v")) { printf("catan %s\n", APP_VERSION); return 0; } 74 if (!strcmp(a, "--gui")) gui = true; 75 else if (!strcmp(a, "--layout") && i + 1 < argc) st.layout = !strcmp(argv[++i], "compact") ? LAYOUT_COMPACT : LAYOUT_WIDE; 76 else if (!strcmp(a, "--scale") && i + 1 < argc) st.scale = atoi(argv[++i]); 77 else if (!strcmp(a, "--lang") && i + 1 < argc) { g_lang = !strcmp(argv[++i], "en"); st.lang = g_lang; } 78 else if (!strcmp(a, "-n") && i + 1 < argc) players = atoi(argv[++i]); 79 else if (!strcmp(a, "--bots") && i + 1 < argc) bots = atoi(argv[++i]); 80 else if (!strcmp(a, "--2p")) v2p = true; 81 else if (!strcmp(a, "--mar")) sea = SCEN_SEA1; 82 else if (!strcmp(a, "--islas")) sea = SCEN_SEA2; 83 else if (!strcmp(a, "--archi")) sea = SCEN_SEA3; 84 else if (!strcmp(a, "--mapa") && i + 1 < argc) map = atoi(argv[++i]); 85 else if (!cmd) cmd = a; 86 else if (nargs < 8) args[nargs++] = argv[i]; 87 } 88 if (st.scale < 1) st.scale = 1; 89 90 #if defined(_WIN32) || defined(__EMSCRIPTEN__) 91 (void)gui; /* en Windows y en la web no hay TUI (ncurses): siempre ventana */ 92 Frontend *fe = gui_open(st.layout, st.scale); 93 #else 94 Frontend *fe = gui ? gui_open(st.layout, st.scale) : tui_open(); 95 #endif 96 if (!fe) { fprintf(stderr, "no se pudo abrir la interfaz%s\n", gui ? " grafica" : ""); return 1; } 97 98 static Session s; 99 if (!cmd) { 100 app_menu(fe, &st); 101 } else if (!strcmp(cmd, "hotseat")) { 102 if (players < 2 || players > MAXP) players = 4; 103 if (bots < 0) bots = 0; 104 Opts o; 105 opts_default(&o, players, v2p); 106 if (sea && players >= 3 && players <= 4 && !v2p) opts_scenario(&o, sea); 107 if (map > 0 && map <= NMAPS) o.map = (uint8_t)(map - 1); 108 uint8_t kinds[MAXP] = { 0 }; 109 char names[MAXP][20]; 110 memset(names, 0, sizeof names); 111 for (int i = 0; i < players; i++) { 112 bool bot = i >= players - bots; 113 kinds[i] = bot ? SEAT_BOT : SEAT_LOCAL; 114 if (bot) snprintf(names[i], sizeof names[i], "Bot %d", i + 1); 115 else if (i == 0) snprintf(names[i], sizeof names[i], "%s", st.name); 116 } 117 o.first = OPTS_FIRST_RANDOM; 118 sess_new_local(&s, &o, fresh_seed(), kinds, names); 119 sess_set_bots(&s, st.bot_level); 120 s.handoff = st.handoff; 121 while (app_play(fe, &s, &st) == 1) app_play_again(&s, &st); 122 sess_close(&s); 123 } else if (!strcmp(cmd, "resume")) { 124 char path[512], err[160] = ""; 125 if (nargs) snprintf(path, sizeof path, "%s", args[0]); 126 else if (!latest_save(path, sizeof path)) { fe->close(fe); fprintf(stderr, "no hay partidas guardadas\n"); return 1; } 127 if (!sess_resume(&s, path, err, sizeof err)) { fe->close(fe); fprintf(stderr, "%s: %s\n", path, err); return 1; } 128 sess_set_bots(&s, st.bot_level); 129 s.handoff = st.handoff; 130 while (app_play(fe, &s, &st) == 1) app_play_again(&s, &st); 131 sess_close(&s); 132 } else if (!strcmp(cmd, "online")) { 133 online_menu(fe, &st, nargs ? args[0] : st.server); 134 } else if (!strcmp(cmd, "host")) { 135 lan_host(fe, &st, nargs ? atoi(args[0]) : 7373); 136 } else if (!strcmp(cmd, "join") && nargs) { 137 lan_join(fe, &st, args[0], nargs > 1 ? atoi(args[1]) : 7373); 138 } else { 139 fe->close(fe); 140 usage(); 141 return 1; 142 } 143 fe->close(fe); 144 return 0; 145 }