static void test_set_insert(CuTest * tc) { struct quicklist *ql = NULL; int a, qi; a = ql_set_insert(&ql, (void *)data); CuAssertIntEquals(tc, 1, ql_length(ql)); CuAssertIntEquals(tc, ql_true, a); a = ql_set_insert(&ql, (void *)(data + 1)); CuAssertIntEquals(tc, 2, ql_length(ql)); CuAssertIntEquals(tc, ql_true, a); a = ql_set_insert(&ql, (void *)data); CuAssertIntEquals(tc, 2, ql_length(ql)); CuAssertIntEquals(tc, ql_false, a); a = ql_set_insert(&ql, (void *)(data + 2)); CuAssertIntEquals(tc, ql_true, a); CuAssertIntEquals(tc, 3, ql_length(ql)); CuAssertPtrEquals(tc, (void *)data, ql_get(ql, 0)); CuAssertPtrEquals(tc, (void *)(data + 1), ql_get(ql, 1)); CuAssertPtrEquals(tc, (void *)(data + 2), ql_get(ql, 2)); a = ql_set_find(&ql, &qi, (void *)(data + 3)); CuAssertIntEquals(tc, 0, a); a = ql_set_find(&ql, &qi, (void *)data); CuAssertIntEquals(tc, 1, a); CuAssertPtrEquals(tc, (void *)data, ql_get(ql, qi)); ql_free(ql); }
static void test_set_remove(CuTest * tc) { struct quicklist *ql = NULL, *q2; int a; ql_set_insert(&ql, (void *)data); ql_set_insert(&ql, (void *)(data + 1)); ql_set_insert(&ql, (void *)(data + 2)); q2 = ql; a = ql_set_remove(&ql, (void *)(data + 1)); CuAssertIntEquals(tc, ql_true, a); CuAssertPtrEquals(tc, q2, ql); CuAssertPtrEquals(tc, (void *)data, ql_get(ql, 0)); CuAssertPtrEquals(tc, (void *)(data + 2), ql_get(ql, 1)); CuAssertIntEquals(tc, 2, ql_length(ql)); a = ql_set_remove(&ql, (void *)(data + 1)); CuAssertIntEquals(tc, ql_false, a); CuAssertPtrEquals(tc, q2, ql); a = ql_set_remove(&ql, (void *)data); CuAssertIntEquals(tc, ql_true, a); a = ql_set_remove(&ql, (void *)(data + 2)); CuAssertIntEquals(tc, ql_true, a); CuAssertPtrEquals(tc, 0, ql); ql_free(ql); }
static quicklist * get_island(region * root) { quicklist * ql, *result = 0; int qi = 0; fset(root, RF_MARK); ql_push(&result, root); for (ql = result, qi = 0; ql; ql_advance(&ql, &qi, 1)) { int dir; region *r = (region *)ql_get(ql, qi); region * next[MAXDIRECTIONS]; get_neighbours(r, next); for (dir = 0; dir != MAXDIRECTIONS; ++dir) { region *rn = next[dir]; if (rn != NULL && rn->land && !fval(rn, RF_MARK)) { fset(rn, RF_MARK); ql_push(&result, rn); } } } for (ql = result, qi = 0; ql; ql_advance(&ql, &qi, 1)) { region *r = (region *)ql_get(ql, qi); freset(r, RF_MARK); } return result; }
const ship_type *findshiptype(const char *name, const struct locale *lang) { local_names *sn = snames; variant var; while (sn) { if (sn->lang == lang) break; sn = sn->next; } if (!sn) { quicklist *ql; int qi; sn = (local_names *)calloc(sizeof(local_names), 1); sn->next = snames; sn->lang = lang; for (qi = 0, ql = shiptypes; ql; ql_advance(&ql, &qi, 1)) { ship_type *stype = (ship_type *)ql_get(ql, qi); variant var2; const char *n = LOC(lang, stype->_name); var2.v = (void *)stype; addtoken(&sn->names, n, var2); } snames = sn; } if (findtoken(sn->names, name, &var) == E_TOK_NOMATCH) return NULL; return (const ship_type *)var.v; }
static attrib *set_new_dragon_target(unit * u, region * r, int range) { int max_affinity = 0; region *max_region = NULL; quicklist *ql, *rlist = regions_in_range(r, range, allowed_dragon); int qi; for (qi = 0, ql = rlist; ql; ql_advance(&ql, &qi, 1)) { region *r2 = (region *)ql_get(ql, qi); int affinity = dragon_affinity_value(r2, u); if (affinity > max_affinity) { max_affinity = affinity; max_region = r2; } } ql_free(rlist); if (max_region && max_region != r) { attrib *a = a_find(u->attribs, &at_targetregion); if (!a) { a = a_add(&u->attribs, make_targetregion(max_region)); } else { a->data.v = max_region; } return a; } return NULL; }
static void test_set_find(CuTest * tc) { struct quicklist *ql = 0, *q2; int a, qi; q2 = ql; a = ql_set_find(&q2, 0, (void *)data); CuAssertIntEquals(tc, ql_false, a); CuAssertPtrEquals(tc, ql, q2); for (a = 0; a != 32; ++a) { ql_set_insert(&ql, (void *)(data + a)); } q2 = ql; a = ql_set_find(&q2, 0, (void *)(data + 31)); CuAssertIntEquals(tc, ql_true, a); CuAssertPtrEquals(tc, ql, q2); q2 = ql; a = ql_set_find(&ql, &qi, (void *)data); CuAssertIntEquals(tc, ql_true, a); CuAssertIntEquals(tc, 0, qi); CuAssertPtrEquals(tc, ql, q2); q2 = ql; a = ql_set_find(&ql, &qi, (void *)(data + 31)); CuAssertIntEquals(tc, ql_true, a); CuAssertPtrEquals(tc, (void *)(data + 31), ql_get(ql, qi)); CuAssertTrue(tc, ql != q2); ql_free(ql); }
/* Find the building type for a given localized name (as seen by the user). Useful for parsing * orders. The inverse of locale_string(lang, btype->_name), sort of. */ const building_type *findbuildingtype(const char *name, const struct locale *lang) { variant type; local_names *bn = bnames; while (bn) { if (bn->lang == lang) break; bn = bn->next; } if (!bn) { quicklist *ql = buildingtypes; int qi; bn = (local_names *)calloc(sizeof(local_names), 1); bn->next = bnames; bn->lang = lang; for (qi = 0, ql = buildingtypes; ql; ql_advance(&ql, &qi, 1)) { building_type *btype = (building_type *)ql_get(ql, qi); const char *n = LOC(lang, btype->_name); type.v = (void *)btype; addtoken(&bn->names, n, type); } bnames = bn; } if (findtoken(bn->names, name, &type) == E_TOK_NOMATCH) return NULL; return (const building_type *)type.v; }
static void test_insert_many(CuTest * tc) { struct quicklist *ql = NULL; int i; for (i = 0; i != 32; ++i) { ql_push(&ql, (void *)(data + i)); } for (i = 0; i != 32; ++i) { CuAssertIntEquals(tc, 32 - i, ql_length(ql)); CuAssertPtrEquals(tc, (void *)(data + i), ql_get(ql, 0)); CuAssertPtrEquals(tc, (void *)(data + 31), ql_get(ql, ql_length(ql) - 1)); ql_delete(&ql, 0); } CuAssertPtrEquals(tc, 0, ql); ql_free(ql); }
static void test_set_insert_ex(CuTest * tc) { const char * strings[] = { "aaa", "bbb", "ccc", "ddd" }; struct quicklist *ql = NULL; int qi; /* insert a string: */ CuAssertIntEquals(tc, ql_true, ql_set_insert_ex(&ql, (void *)strings[0], cmp_str)); CuAssertIntEquals(tc, 1, ql_length(ql)); /* insert a second string: */ CuAssertIntEquals(tc, ql_true, ql_set_insert_ex(&ql, (void *)strings[1], cmp_str)); CuAssertIntEquals(tc, 2, ql_length(ql)); /* same string again, no change: */ CuAssertIntEquals(tc, ql_false, ql_set_insert_ex(&ql, (void *)strings[1], cmp_str)); CuAssertIntEquals(tc, 2, ql_length(ql)); /* a third string */ CuAssertIntEquals(tc, ql_true, ql_set_insert_ex(&ql, (void *)strings[2], cmp_str)); CuAssertIntEquals(tc, 3, ql_length(ql)); /* check that they are alphabetically ordered: */ for (qi = 0; qi != 3; ++qi) { CuAssertPtrEquals(tc, (void *)strings[qi], ql_get(ql, qi)); } CuAssertIntEquals(tc, 1, ql_set_find_ex(&ql, &qi, (void *)strings[2], cmp_str)); CuAssertIntEquals(tc, 2, qi); ql_free(ql); }
static void test_seen_faction(CuTest *tc) { faction *f1, *f2; race *rc = test_create_race("human"); f1 = test_create_faction(rc); f2 = test_create_faction(rc); add_seen_faction(f1, f2); CuAssertPtrEquals(tc, f2, ql_get(f1->seen_factions, 0)); CuAssertIntEquals(tc, 1, ql_length(f1->seen_factions)); add_seen_faction(f1, f2); CuAssertIntEquals(tc, 1, ql_length(f1->seen_factions)); add_seen_faction(f1, f1); CuAssertIntEquals(tc, 2, ql_length(f1->seen_factions)); f2 = (faction *)ql_get(f1->seen_factions, 1); f1 = (faction *)ql_get(f1->seen_factions, 0); CuAssertTrue(tc, f1->no < f2->no); }
void sort_wormhole_regions(quicklist *rlist, region **match, int count) { quicklist *ql; int qi, i = 0; for (ql = rlist, qi = 0; i != count; ql_advance(&ql, &qi, 1)) { match[i++] = (region *)ql_get(ql, qi); } qsort(match, count, sizeof(region *), cmp_age); }
static void test_replace(CuTest * tc) { struct quicklist *ql = NULL; void * a; ql_push(&ql, (void *)data); a = ql_replace(ql, 0, (void *)(data + 1)); CuAssertPtrEquals(tc, (void *)data, a); CuAssertPtrEquals(tc, (void *)(data + 1), ql_get(ql, 0)); ql_free(ql); }
static void get_island_info(region * root, int *size_p, int *inhabited_p, int *maxage_p) { int qi, size = 0, maxage = 0, inhabited = 0; quicklist *ql, *island = NULL; ql_push(&island, root); fset(root, RF_MARK); for (ql = island, qi = 0; ql; ql_advance(&ql, &qi, 1)) { int d; region *r = (region *)ql_get(ql, qi); if (r->units) { unit *u; for (u = r->units; u; u = u->next) { if (!fval(u->faction, FFL_NOIDLEOUT) && u->faction->age > maxage) { maxage = u->faction->age; } } ++inhabited; } ++size; for (d = 0; d != MAXDIRECTIONS; ++d) { region *rn = rconnect(r, d); if (rn && !fval(rn, RF_MARK) && rn->land) { ql_push(&island, rn); fset(rn, RF_MARK); } } } for (ql = island, qi = 0; ql; ql_advance(&ql, &qi, 1)) { region *r = (region *)ql_get(ql, qi); freset(r, RF_MARK); } ql_free(island); if (size_p) *size_p = size; if (inhabited_p) *inhabited_p = inhabited; if (maxage_p) *maxage_p = maxage; }
static void test_push(CuTest * tc) { struct quicklist *result, *ql = NULL; CuAssertIntEquals(tc, 0, ql_length(ql)); result = ql_push(&ql, (void *)data); CuAssertPtrEquals(tc, result, ql); CuAssertIntEquals(tc, 1, ql_length(ql)); CuAssertPtrEquals(tc, (void *)data, ql_get(ql, 0)); ql_delete(&ql, 0); CuAssertPtrEquals(tc, 0, ql); }
/** randomly shuffle an array * for correctness, see Donald E. Knuth, The Art of Computer Programming */ static void scramble_fighters(quicklist * ql) { int qi, qlen = ql_length(ql); for (qi = 0; qi != qlen; ++qi) { int qj = qi + (rng_int() % (qlen - qi)); void *a = ql_get(ql, qi); void *b = ql_replace(ql, qj, a); ql_replace(ql, qi, b); } }
/* Feuersturm: Betrifft sehr viele Gegner (in der Regel alle), * macht nur vergleichsweise geringen Schaden */ int sp_immolation(struct castorder * co) { fighter * fi = co->magician.fig; int level = co->level; const spell * sp = co->sp; battle *b = fi->side->battle; troop at; int force, qi, killed = 0; const char *damage; quicklist *fgs, *ql; message *m; /* 2d4 HP */ damage = spell_damage(5); /* Betrifft alle Gegner */ force = 99999; if (!count_enemies(b, fi, FIGHT_ROW, AVOID_ROW, SELECT_ADVANCE | SELECT_FIND)) { message *m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); message_all(b, m); msg_release(m); return 0; } at.fighter = fi; at.index = 0; fgs = fighters(b, fi->side, FIGHT_ROW, AVOID_ROW, FS_ENEMY); for (qi = 0, ql = fgs; ql; ql_advance(&ql, &qi, 1)) { fighter *df = (fighter *)ql_get(ql, qi); int n = df->alive - df->removed; troop dt; dt.fighter = df; while (n != 0) { dt.index = --n; killed += terminate(dt, at, AT_COMBATSPELL, damage, false); if (--force == 0) break; } if (force == 0) break; } ql_free(fgs); m = msg_message("battle::combatspell", "mage spell killed", fi->unit, sp, killed); message_all(b, m); msg_release(m); return level; }
void spellbook_clear(spellbook *sb) { quicklist *ql; int qi; assert(sb); for (qi = 0, ql = sb->spells; ql; ql_advance(&ql, &qi, 1)) { spellbook_entry *sbe = (spellbook_entry *) ql_get(ql, qi); free(sbe); } ql_free(sb->spells); }
static ship_type *st_find_i(const char *name) { quicklist *ql; int qi; for (qi = 0, ql = shiptypes; ql; ql_advance(&ql, &qi, 1)) { ship_type *stype = (ship_type *)ql_get(ql, qi); if (strcmp(stype->_name, name) == 0) { return stype; } } return NULL; }
static void test_insert(CuTest * tc) { struct quicklist *ql = NULL; int i; for (i = 0; i != 32; ++i) { CuAssertIntEquals(tc, i, ql_length(ql)); ql_insert(&ql, 0, (void *)(data + 31 - i)); } for (i = 0; i != 32; ++i) { CuAssertPtrEquals(tc, (void *)(data + i), ql_get(ql, i)); } ql_free(ql); }
static void test_advance(CuTest * tc) { struct quicklist *ql = NULL, *qli; int i, n = 31; for (i = 0; i != 32; ++i) { ql_insert(&ql, 0, (void *)(data + i)); } for (i = 0, qli = ql; qli; ql_advance(&qli, &i, 1), n--) { void * g = ql_get(qli, i); CuAssertPtrEquals(tc, (void *)(data + n), g); } ql_free(ql); }
int spellbook_foreach(spellbook *sb, int (*callback)(spellbook_entry *, void *), void * data) { quicklist *ql; int qi; for (qi = 0, ql = sb->spells; ql; ql_advance(&ql, &qi, 1)) { spellbook_entry *sbe = (spellbook_entry *) ql_get(ql, qi); int result = callback(sbe, data); if (result) { return result; } } return 0; }
const message_type *mt_find(const char *name) { unsigned int hash = hashstring(name) % MT_MAXHASH; quicklist *ql = messagetypes[hash]; int qi; for (qi = 0; ql; ql_advance(&ql, &qi, 1)) { message_type *data = (message_type *)ql_get(ql, qi); if (strcmp(data->name, name) == 0) { return data; } } return 0; }
/* Returns a building type for the (internal) name */ static building_type *bt_find_i(const char *name) { quicklist *ql; int qi; assert(name); for (qi = 0, ql = buildingtypes; ql; ql_advance(&ql, &qi, 1)) { building_type *btype = (building_type *)ql_get(ql, qi); if (strcmp(btype->_name, name) == 0) return btype; } return NULL; }
spellbook_entry * spellbook_get(spellbook *sb, const struct spell * sp) { if (sb) { quicklist *ql; int qi; for (qi = 0, ql = sb->spells; ql; ql_advance(&ql, &qi, 1)) { spellbook_entry *sbe = (spellbook_entry *) ql_get(ql, qi); if (sp==sbe->sp) { return sbe; } } } return 0; }
static void test_delete_rand(CuTest * tc) { struct quicklist *ql = NULL; int i; for (i = 0; i != 32; ++i) { ql_push(&ql, (void *)(data + i)); } CuAssertIntEquals(tc, 32, ql_length(ql)); ql_delete(&ql, 0); CuAssertPtrEquals(tc, (void *)(data + 1), ql_get(ql, 0)); CuAssertIntEquals(tc, 31, ql_length(ql)); ql_delete(&ql, 30); CuAssertIntEquals(tc, 30, ql_length(ql)); ql_free(ql); }
static void test_push_doesnt_invalidate_iterator(CuTest * tc) { struct quicklist *list = NULL, *ql = NULL; int i, qi = 0; ql_push(&list, (void*)data); ql = list; for (i = 0; i != 42; ++i) { void * n; n = ql_get(ql, qi); CuAssertPtrEquals(tc, (void *)(data + i), n); ql_push(&list, (void *)(data + (i * 2 + 1))); ql_advance(&ql, &qi, 1); ql_push(&list, (void *)(data + (i * 2 + 2))); } ql_free(ql); }
void add_donation(faction * f1, faction * f2, int amount, region * r) { transfer tr, *tf; quicklist *ql = transfers; int qi = 0; tr.r = r; tr.f1 = f1; tr.f2 = f2; tr.amount = amount; if (ql_set_find_ex(&ql, &qi, &tr, cmp_transfer)) { tf = (transfer *)ql_get(ql, qi); tf->amount += amount; } else { tf = malloc(sizeof(transfer)); memcpy(tf, &tr, sizeof(transfer)); } ql_set_insert_ex(&transfers, tf, cmp_transfer); }
const curse_type *ct_find(const char *c) { unsigned int hash = tolower(c[0]); quicklist *ctl = cursetypes[hash]; int qi; for (qi = 0; ctl; ql_advance(&ctl, &qi, 1)) { curse_type *type = (curse_type *) ql_get(ctl, qi); if (strcmp(c, type->cname) == 0) { return type; } else { size_t k = _min(strlen(c), strlen(type->cname)); if (!_memicmp(c, type->cname, k)) { return type; } } } return NULL; }
static int heal_fighters(quicklist * fgs, int *power, bool heal_monsters) { int healhp = *power, healed = 0, qi; quicklist *ql; for (qi = 0, ql = fgs; ql; ql_advance(&ql, &qi, 1)) { fighter *df = (fighter *)ql_get(ql, qi); if (healhp <= 0) break; /* Untote kann man nicht heilen */ if (df->unit->number == 0 || (u_race(df->unit)->flags & RCF_NOHEAL)) continue; /* wir heilen erstmal keine Monster */ if (heal_monsters || playerrace(u_race(df->unit))) { int n, hp = df->unit->hp / df->unit->number; int rest = df->unit->hp % df->unit->number; for (n = 0; n < df->unit->number; n++) { int wound = hp - df->person[n].hp; if (rest > n) ++wound; if (wound > 0 && wound < hp) { int heal = _min(healhp, wound); assert(heal >= 0); df->person[n].hp += heal; healhp = _max(0, healhp - heal); ++healed; if (healhp <= 0) break; } } } } *power = healhp; return healed; }
void age_borders(void) { quicklist *deleted = NULL, *ql; int i; for (i = 0; i != BORDER_MAXHASH; ++i) { connection *bhash = borders[i]; for (; bhash; bhash = bhash->nexthash) { connection *b = bhash; for (; b; b = b->next) { if (b->type->age) { if (b->type->age(b) == AT_AGE_REMOVE) { ql_push(&deleted, b); } } } } } for (ql = deleted, i = 0; ql; ql_advance(&ql, &i, 1)) { connection *b = (connection *)ql_get(ql, i); erase_border(b); } ql_free(deleted); }