auth.c (4134B)
1 /* auth.c - la autoridad: valida, resuelve el azar, aplica y emite movidas. */ 2 #include <string.h> 3 #include "catan.h" 4 5 static void emit(Auth *a, const Move *m) 6 { 7 if (a->emit) a->emit(a->ctx, m); 8 } 9 10 static void apply_emit(Auth *a, const Move *m) 11 { 12 game_apply_u(&a->g, &a->undo, m); 13 emit(a, m); 14 } 15 16 static int random_card(Auth *a, const uint8_t hand[NRES]) 17 { 18 int n = res_total(hand); 19 if (!n) return -1; 20 int k = (int)rng_below(&a->rng, (uint32_t)n); 21 for (int r = 0; r < NRES; r++) { 22 if (k < hand[r]) return r; 23 k -= hand[r]; 24 } 25 return -1; 26 } 27 28 static void neutral_setup(Auth *a) 29 { 30 Game *g = &a->g; 31 const Topo *t = game_topo(g); 32 for (int round = 0; round < g->o.neutral_setup; round++) 33 for (int n = 0; n < g->o.np; n++) { 34 if (!g->p[n].neutral) continue; 35 int cand[NVERT], nc = 0; 36 for (int v = 0; v < t->nvert; v++) 37 if (game_can_settle(g, n, v, true)) cand[nc++] = v; 38 if (!nc) continue; 39 Move m = { .type = M_NEUTRAL, .p = (int8_t)n, .a = (int16_t)n, .b = 1 }; 40 m.c = (int16_t)cand[rng_below(&a->rng, (uint32_t)nc)]; 41 apply_emit(a, &m); 42 int ec[3], ne = 0; 43 for (int k = 0; k < 3; k++) { 44 int e = t->vert_edge[m.c][k]; 45 if (e >= 0 && game_can_road(g, n, e)) ec[ne++] = e; 46 } 47 if (!ne) continue; 48 Move r = { .type = M_NEUTRAL, .p = (int8_t)n, .a = (int16_t)n, .b = 0 }; 49 r.c = (int16_t)ec[rng_below(&a->rng, (uint32_t)ne)]; 50 apply_emit(a, &r); 51 } 52 } 53 54 void board_make(Game *g, const Opts *o, Rng *game_rng) 55 { 56 int board = opts_board(o); 57 Rng br; 58 Rng *rng = game_rng; 59 if (o->bseed) { rng_seed(&br, o->bseed, 0xB0A2D); rng = &br; } /* el tablero que eligio quien crea */ 60 if (o->beginner && board == BOARD_CLASSIC) board_beginner(g); 61 else board_random(g, board, rng); 62 game_init(g, o); 63 } 64 65 void auth_new(Auth *a, const Opts *o, uint64_t seed, EmitFn fn, void *ctx) 66 { 67 memset(a, 0, sizeof *a); 68 a->seed = seed; 69 a->emit = fn; 70 a->ctx = ctx; 71 rng_seed(&a->rng, seed, 0xCA7A); 72 board_make(&a->g, o, &a->rng); 73 74 uint8_t COUNT[NDEV]; 75 int ndeck = dev_counts(o, COUNT); 76 int k = 0; 77 for (int d = 0; d < NDEV; d++) 78 for (int i = 0; i < COUNT[d]; i++) a->deck[k++] = (uint8_t)d; 79 for (int i = ndeck - 1; i > 0; i--) { 80 int j = (int)rng_below(&a->rng, (uint32_t)i + 1); 81 uint8_t tmp = a->deck[i]; a->deck[i] = a->deck[j]; a->deck[j] = tmp; 82 } 83 if (o->variant2p) neutral_setup(a); 84 } 85 86 int auth_submit(Auth *a, Move *m) 87 { 88 Game *g = &a->g; 89 if (m->type == M_WIN || m->type == M_NONE || m->type >= M__COUNT) return E_ARGS; 90 if (m->type == M_NEUTRAL && g->phase == PH_SETUP) return E_PHASE; 91 int e = game_check(g, m); 92 if (e) return e; 93 94 switch (m->type) { 95 case M_ROLL: 96 m->r[0] = (uint8_t)(1 + rng_below(&a->rng, 6)); 97 m->r[1] = (uint8_t)(1 + rng_below(&a->rng, 6)); 98 m->r[2] = m->r[3] = 0; 99 if (g->o.variant2p) 100 do { 101 m->r[2] = (uint8_t)(1 + rng_below(&a->rng, 6)); 102 m->r[3] = (uint8_t)(1 + rng_below(&a->rng, 6)); 103 } while (m->r[2] + m->r[3] == m->r[0] + m->r[1]); 104 m->r[4] = 0; 105 break; 106 case M_ROBBER: 107 m->c = (int16_t)(m->b >= 0 ? random_card(a, g->p[m->b].res) : -1); 108 break; 109 case M_BUYDEV: 110 m->a = a->deck[g->deck_n - 1]; 111 break; 112 case M_TOKTRADE: { 113 int r = game_rival(g, m->p); 114 uint8_t hand[NRES] = { 0 }; 115 if (r >= 0) memcpy(hand, g->p[r].res, NRES); 116 m->a = (int16_t)random_card(a, hand); 117 if (m->a >= 0) hand[m->a]--; 118 m->b = (int16_t)random_card(a, hand); 119 break; 120 } 121 default: 122 break; 123 } 124 apply_emit(a, m); 125 126 int p = g->cur; 127 if (g->winner < 0 && game_vp(g, p) >= g->o.vp_target) { 128 Move w = { .type = M_WIN, .p = (int8_t)p }; 129 w.a = (int16_t)(g->p[p].dev[D_VP] + g->p[p].dev_new[D_VP]); 130 apply_emit(a, &w); 131 } 132 return E_OK; 133 }