/********************************************************************** * Bonuses **********************************************************************/ static void _calc_bonuses(void) { int r = _rank(); p_ptr->to_a += 2*r; p_ptr->dis_to_a += 2*r; p_ptr->skill_dig += 50; p_ptr->pspeed += _rank(); }
size_t _rank(Node* node, const Key& key) const { if (! node || node == _end) return 0; if (key < node->key) return _rank(node->left, key); size_t size = 1; if (node->left) size += node->left->size; if (key > node->key) size += _rank(node->right, key); return size; }
bool sword_disenchant(void) { bool result = FALSE; int r = _rank(); int i; for (i = 0; i < _MAX_ESSENCE; i++) { int n = _essences[i]; if (!n) continue; if (i == TR_SPEED) continue; if (res_save(RES_DISEN, 70)) continue; _essences[i] -= MAX(1, _essences[i] * randint1(r) / 20); if (_essences[i] < n) result = TRUE; } if (result) { p_ptr->update |= PU_BONUS; msg_print("You feel power draining from your body!"); } return result; }
inline void erase(node *root) { int pos = _rank(root); splay(pos - 1, pos + 1); head->ch[0]->ch[1] = null; head->ch[0]->update(); head->update(); }
/********************************************************************** * Attacks **********************************************************************/ static void _calc_innate_attacks(void) { int r = _rank(); /* Bite */ { innate_attack_t a = {0}; a.dd = 1; a.ds = 3 + r; a.to_h = p_ptr->lev/3; a.to_d = 2*r; a.weight = 70; a.effect[0] = GF_MISSILE; a.blows = 100; a.msg = "You bite."; a.name = "Bite"; p_ptr->innate_attacks[p_ptr->innate_attack_ct++] = a; } /* Sting */ { innate_attack_t a = {0}; a.dd = 1; a.ds = 2 + r; a.to_h = p_ptr->lev/3; a.to_d = 2*r; a.weight = 70; a.effect[0] = GF_MISSILE; if (r >= 5) a.effect[1] = GF_POIS; a.blows = 100; a.msg = "You sting."; a.name = "Sting"; p_ptr->innate_attacks[p_ptr->innate_attack_ct++] = a; } /* Crawl */ { innate_attack_t a = {0}; a.dd = 1; a.ds = 3 + r; if (r >= 5) a.ds += 7; a.to_h = p_ptr->lev/3; a.to_d = 2*r; a.weight = 70; a.effect[0] = GF_MISSILE; calc_innate_blows(&a, 100 + 50*r); a.msg = "You crawl."; a.name = "Crawl"; p_ptr->innate_attacks[p_ptr->innate_attack_ct++] = a; } }
static int _rank_decay(int p) { int r = _rank(); for (; r < 4; r++) p /= 2; return MAX(1, p); }
/********************************************************************** * Public **********************************************************************/ race_t *mon_sword_get_race_t(void) { static race_t me = {0}; static bool init = FALSE; static cptr titles[5] = {"Broken Death Sword", "Death Sword", "Poleaxe of Animated Attack", "Hellblade", "Death Scythe"}; int rank = _rank(); if (!init) { /* dis, dev, sav, stl, srh, fos, thn, thb */ skills_t bs = { 25, 37, 40, 4, 14, 5, 56, 20}; skills_t xs = { 12, 12, 12, 0, 0, 0, 20, 7}; me.skills = bs; me.extra_skills = xs; me.name = "Death-Sword"; me.desc = "Death Swords are mighty weapons animated by magical means. As such, " "they are unable to use equipment the way other players can. Instead, " "they simply are a weapon of their current form. But never fear, Death " "Swords have the power to absorb magical essences from the weapons they " "find, gaining power in the process."; me.infra = 3; me.exp = 150; me.base_hp = 30; me.calc_bonuses = _calc_bonuses; me.calc_weapon_bonuses = _calc_weapon_bonuses; me.character_dump = _character_dump; me.get_flags = _get_flags; me.get_immunities = _get_immunities; me.gain_level = _gain_level; me.get_powers = _get_powers; me.birth = _birth; me.load_player = _load; me.save_player = _save; me.flags = RACE_IS_MONSTER | RACE_IS_NONLIVING; me.pseudo_class_idx = CLASS_WARRIOR; init = TRUE; } me.subname = titles[rank]; me.stats[A_STR] = 1 + rank; me.stats[A_INT] = -5; me.stats[A_WIS] = -5; me.stats[A_DEX] = 0 + rank/2; me.stats[A_CON] = 1 + rank; me.stats[A_CHR] = 0; me.life = 85 + 5*rank; me.boss_r_idx = MON_STORMBRINGER; me.equip_template = mon_get_equip_template(); return &me; }
inline Result KPKPosition::classify (const vector<KPKPosition>& db) { // White to Move: // If one move leads to a position classified as WIN, the result of the current position is WIN. // If all moves lead to positions classified as DRAW, the result of the current position is DRAW // otherwise the current position is classified as UNKNOWN. // // Black to Move: // If one move leads to a position classified as DRAW, the result of the current position is DRAW. // If all moves lead to positions classified as WIN, the result of the current position is WIN // otherwise the current position is classified as UNKNOWN. const Color C_ = ((WHITE == C) ? BLACK : WHITE); Result r = INVALID; Bitboard b = attacks_bb<KING> ((WHITE == C) ? wk_sq : bk_sq); while (b) { r |= (WHITE == C) ? db[index(C_, bk_sq, pop_lsq (b), p_sq)] : db[index(C_, pop_lsq (b), wk_sq, p_sq)]; } if ((WHITE == C) && (_rank (p_sq) < R_7)) { Square s = p_sq + DEL_N; r |= db[index(BLACK, bk_sq, wk_sq, s)]; // Single push if (_rank (p_sq) == R_2 && s != wk_sq && s != bk_sq) { r |= db[index(BLACK, bk_sq, wk_sq, s + DEL_N)]; // Double push } } return result = (WHITE == C) ? (r & WIN ? WIN : r & UNKNOWN ? UNKNOWN : DRAW) : (r & DRAW ? DRAW : r & UNKNOWN ? UNKNOWN : WIN); }
/********************************************************************** * Public Methods **********************************************************************/ race_t *mon_centipede_get_race(void) { static race_t me = {0}; static bool init = FALSE; int r = _rank(); static cptr titles[6] = {"Giant white centipede", "Metallic green centipede", "Metallic blue centipede", "Metallic red centipede", "Giant clear centipede", "The Multi-hued Centipede"}; if (!init) { /* dis, dev, sav, stl, srh, fos, thn, thb */ skills_t bs = { 25, 21, 35, 5, 10, 7, 50, 10}; skills_t xs = { 12, 10, 10, 0, 0, 0, 15, 2}; me.skills = bs; me.extra_skills = xs; me.name = "Centipede"; me.desc = _desc; me.infra = 5; me.exp = 100; me.base_hp = 15; me.shop_adjust = 120; me.calc_innate_attacks = _calc_innate_attacks; me.calc_bonuses = _calc_bonuses; me.get_flags = _get_flags; me.gain_level = _gain_level; me.birth = _birth; me.flags = RACE_IS_MONSTER; me.boss_r_idx = MON_CENTIPEDE_MULTIHUED; me.pseudo_class_idx = CLASS_WARRIOR; init = TRUE; } if (!birth_hack && !spoiler_hack) me.subname = titles[r]; else me.subname = NULL; me.stats[A_STR] = (r + 1)/3; me.stats[A_INT] = -3; me.stats[A_WIS] = -3; me.stats[A_DEX] = r; me.stats[A_CON] = (r + 1)/2; me.stats[A_CHR] = -3; me.life = 90 + 2*r; me.equip_template = mon_get_equip_template(); return &me; }
static int _blows_mult(void) { switch (_rank()) { case 0: return 100; case 1: return 100; case 2: return 75; case 3: return 50; case 4: default: return 20; } }
static double _evaluate(T&& t, V&& x) { if(_rank(t) == 0) { return 0.; } double acc = 1.; for(auto&& m : t.m) { const std::size_t i = m.first; const std::size_t exponent_i = m.second; acc *= std::pow(x[i], exponent_i); } return acc; }
// Entry::shelter_storm() calculates shelter and storm penalties for the file // the king is on, as well as the two adjacent files. Value Entry::shelter_storm (const Position &pos, Square k_sq) { const Color C_ = ((WHITE == C) ? BLACK : WHITE); Value safety = MaxSafetyBonus; Bitboard front_pawns = pos.pieces (PAWN) & (front_ranks_bb (C, _rank (k_sq)) | rank_bb (k_sq)); Bitboard pawns[CLR_NO] = { front_pawns & pos.pieces (C ), front_pawns & pos.pieces (C_), }; File kf = max (F_B, min (F_G, _file (k_sq))); for (File f = kf - 1; f <= kf + 1; ++f) { Bitboard mid_pawns; mid_pawns = pawns[1] & file_bb (f); Rank b_rk = mid_pawns ? rel_rank (C, scan_rel_frntmost_sq (C_, mid_pawns)) : R_1; if ((MID_EDGE_bb & (f | b_rk)) && _file (k_sq) == f && rel_rank (C, k_sq) == b_rk - 1) { safety += Value (200); } else { mid_pawns = pawns[0] & file_bb (f); Rank w_rk = mid_pawns ? rel_rank (C, scan_rel_backmost_sq (C , mid_pawns)) : R_1; int8_t danger = (w_rk != R_1) ? ((b_rk == w_rk + 1) ? 2 : 1) : 0; safety -= ShelterWeakness[w_rk] + StormDanger[danger][b_rk]; } } return safety; }
/********************************************************************** * Public **********************************************************************/ race_t *mon_golem_get_race(int psubrace) { static race_t me = {0}; static bool init = FALSE; int rank = _rank(); if (!init) { /* dis, dev, sav, stl, srh, fos, thn, thb */ skills_t bs = { 25, 18, 40, 0, 10, 7, 70, 30}; skills_t xs = { 10, 7, 15, 0, 0, 0, 30, 10}; me.skills = bs; me.extra_skills = xs; me.infra = 5; me.shop_adjust = 130; me.name = "Golem"; me.desc = _desc; me.calc_innate_attacks = _calc_innate_attacks; me.birth = _birth; me.gain_level = _gain_level; me.calc_bonuses = _calc_bonuses; me.get_powers = _get_powers; me.get_flags = _get_flags; me.flags = RACE_IS_MONSTER | RACE_IS_NONLIVING; me.base_hp = 50; me.boss_r_idx = MON_DESTROYER; me.pseudo_class_idx = CLASS_MAULER; init = TRUE; } me.subname = _mon_name(p_ptr->current_r_idx); me.stats[A_STR] = 1 + rank; me.stats[A_INT] = -2 - (rank+1)/2; me.stats[A_WIS] = -2 - (rank+1)/2; me.stats[A_DEX] = -1 - (rank+1)/2; me.stats[A_CON] = 1 + rank; me.stats[A_CHR] = 0 + (rank+1)/2; switch (psubrace) { case GOLEM_SKY: if (!p_ptr->current_r_idx) me.subname = "Sky Golem"; me.life = 100 + 2*rank; me.exp = 250; break; case GOLEM_SPELLWARP: if (!p_ptr->current_r_idx) me.subname = "Spellwarp Automaton"; me.life = 100 + 3*rank; me.exp = 350; break; case GOLEM_COLOSSUS: default: if (!p_ptr->current_r_idx) me.subname = "Colossus"; if (p_ptr->current_r_idx == MON_COLOSSUS) { me.stats[A_STR] += 3; me.stats[A_DEX] -= 2; me.stats[A_CON] += 3; } me.life = 100 + 5*rank; me.exp = 200; break; } return &me; }
/* * `polynomial::rank` * * */ std::size_t polynomial::rank() const { return _rank(*this); }
static void _get_flags(u32b flgs[OF_ARRAY_SIZE]) { if (_rank()) add_flag(flgs, OF_SPEED); }
static void _add_term(polynomial& p, double coefficient, T&& t) { #ifdef EXDEBUG using multiindex = typename polynomial::multiindex; if(t.m.size() > 0) { const std::size_t testing__term_max_var_index = std::max_element(std::cbegin(t.m), std::cend(t.m), [](const auto& m0, const auto& m1) { return m0.first < m1.first; })->first; const std::size_t testing__term_max_nvars = testing__term_max_var_index + 1; const std::size_t testing__polynomial_max_nvars = p.ni; std::cout << __func__ << " multiindex = " << multiindex(t, std::max(testing__polynomial_max_nvars, testing__term_max_nvars)) << std::endl; } else { const std::size_t testing__polynomial_max_nvars = p.ni; std::cout << __func__ << " multiindex = " << multiindex(t, testing__polynomial_max_nvars) << std::endl; } #endif if(_rank(t) == 0) { p.constant += coefficient; return; } // Get new number of terms to store const std::size_t cur_max_nterms = _max_nterms(p); const std::size_t cur_max_nvars = _max_nvars(p); const std::size_t new_term_index = _get_term_index(p, t); std::size_t new_max_nterms = cur_max_nterms; if(new_term_index >= cur_max_nterms) { new_max_nterms = cur_max_nterms + 1; } else { new_max_nterms = cur_max_nterms; } // Get new number of variables to store. const std::size_t term_max_var_index = std::max_element(std::cbegin(t.m), std::cend(t.m), [](const auto& m0, const auto& m1) { return m0.first < m1.first; })->first; const std::size_t term_max_nvars = term_max_var_index + 1; std::size_t new_max_nvars = cur_max_nvars; if(term_max_nvars > cur_max_nvars) { new_max_nvars = term_max_nvars; } else { new_max_nvars = cur_max_nvars; } // Grow _resize(p, new_max_nvars, new_max_nterms); // Insert new term data if(new_max_nterms == cur_max_nterms + 1) { p.c.insert(std::cbegin(p.c) + new_term_index, coefficient); } else { p.c[new_term_index] += coefficient; } for(auto&& m : t.m) { auto term_var_index = m.first; auto term_var_exponent = m.second; _get_exponent(p, term_var_index, new_term_index) = term_var_exponent; } }
size_t rank(const Key& key) const { return _rank(_root, key); }