src/player-birth.c
static void generate_stats(int stats[STAT_MAX], int points_spent[STAT_MAX], 
						   int *points_left)
{
	int step = 0;
	int maxed[STAT_MAX] = { 0 };
	int spell_stat = player->class->magic.spell_realm->stat;
	bool caster = FALSE, warrior = FALSE;

	/* Determine whether the class is warrior */
	if (player->class->max_attacks > 5) { 
		warrior = TRUE;
	}

	/* Determine whether the class is priest/mage */
	if (player->class->max_attacks < 5) {
		caster = TRUE;
	}

	while (*points_left && step >= 0) {
	
		switch (step) {
		
			/* Buy base STR 17 */
			case 0: {
			
				if (!maxed[STAT_STR] && stats[STAT_STR] < 17) {
					if (!buy_stat(STAT_STR, stats, points_spent, points_left,
								  FALSE))
						maxed[STAT_STR] = TRUE;
				} else {
					step++;
					
					/* If pure caster skip to step 3 */
					if (caster){
						step = 3;
					}
				}

				break;
			}

			/* Try and buy adj DEX of 18/10 */
			case 1: {
				if (!maxed[STAT_DEX] && player->state.stat_top[STAT_DEX]
					< 18+10) {
					if (!buy_stat(STAT_DEX, stats, points_spent, points_left,
								  FALSE))
						maxed[STAT_DEX] = TRUE;
				} else {
					step++;
				}

				break;
			}

			/* If we can't get 18/10 dex, sell it back. */
			case 2: {
				if (player->state.stat_top[STAT_DEX] < 18+10) {
					while (stats[STAT_DEX] > 10)
						sell_stat(STAT_DEX, stats, points_spent, points_left,
								  FALSE);
					maxed[STAT_DEX] = FALSE;
				}
				step++;
			}

			/* 
			 * Spend up to half remaining points on each of spell-stat and 
			 * con, but only up to max base of 16 unless a pure class 
			 * [mage or priest or warrior]
			 */
			case 3: 
			{
				int points_trigger = *points_left / 2;
				
				if (warrior) {
					points_trigger = *points_left;
				} else {
					while (!maxed[spell_stat] &&
						   (caster || stats[spell_stat] < 16) &&
						   points_spent[spell_stat] < points_trigger) {

						if (!buy_stat(spell_stat, stats, points_spent,
									  points_left, FALSE)) {
							maxed[spell_stat] = TRUE;
						}

						if (points_spent[spell_stat] > points_trigger) {
						
							sell_stat(spell_stat, stats, points_spent, 
									  points_left, FALSE);
							maxed[spell_stat] = TRUE;
						}
					}
				}

				/* Skip CON for casters because DEX is more important early
				 * and is handled in 4 */
				while (!maxed[STAT_CON] &&
					   !(caster) && stats[STAT_CON] < 16 &&
					   points_spent[STAT_CON] < points_trigger) {
					   
					if (!buy_stat(STAT_CON, stats, points_spent,points_left,
								  FALSE)) {
						maxed[STAT_CON] = TRUE;
					}

					if (points_spent[STAT_CON] > points_trigger) {
						sell_stat(STAT_CON, stats, points_spent, points_left,
								  FALSE);
						maxed[STAT_CON] = TRUE;
					}
				}
				
				step++;
				break;
			}

			/* 
			 * If there are any points left, spend as much as possible in 
			 * order on DEX, and the non-spell-stat. 
			 */
			case 4:{
			
				int next_stat;

				if (!maxed[STAT_DEX]) {
					next_stat = STAT_DEX;
				} else if (!maxed[STAT_INT] && spell_stat != STAT_INT) {
					next_stat = STAT_INT;
				} else if (!maxed[STAT_WIS] && spell_stat != STAT_WIS) {
					next_stat = STAT_WIS;
				} else {
					step++;
					break;
				}

				/* Buy until we can't buy any more. */
				while (buy_stat(next_stat, stats, points_spent, points_left,
								FALSE));
				maxed[next_stat] = TRUE;

				break;
			}

			default: {
			
				step = -1;
				break;
			}
		}
	}
	/* Tell the UI the new points situation. */
	event_signal_birthpoints(points_spent, *points_left);

	/* Recalculate everything that's changed because
	   the stat has changed, and inform the UI. */
	recalculate_stats(stats, *points_left);
}
/**
 * This picks some reasonable starting values for stats based on the
 * current race/class combo, etc.  For now I'm disregarding concerns
 * about role-playing, etc, and using the simple outline from
 * http://angband.oook.cz/forum/showpost.php?p=17588&postcount=6:
 *
 * 0. buy base STR 17
 * 1. if possible buy adj DEX of 18/10
 * 2. spend up to half remaining points on each of spell-stat and con, 
 *    but only up to max base of 16 unless a pure class 
 *    [mage or priest or warrior]
 * 3. If there are any points left, spend as much as possible in order 
 *    on DEX and then the non-spell-stat.
 */
This picks some reasonable starting values for stats based on the
current race/class combo, etc.

0. buy base STR 17
1. if possible buy adj DEX of 18/10
2. spend up to half remaining points on each of spell-stat and con,
but only up to max base of 16 unless a pure class
[mage or priest or warrior]
3. If there are any points left, spend as much as possible in order
on DEX and then the non-spell-stat.
This picks some reasonable starting values for stats based on the current race / class combo etc . 0 . buy base STR 17 1 . if possible buy adj DEX of 18 / 10 2 . spend up to half remaining points on each of spell - stat and con but only up to max base of 16 unless a pure class [ mage or priest or warrior ] 3 . If there are any points left spend as much as possible in order on DEX and then the non - spell - stat .
static void generate_stats(int stats[STAT_MAX], int points_spent[STAT_MAX], 
						   int *points_left)
{
	int step = 0;
	int maxed[STAT_MAX] = { 0 };
	int spell_stat = player->class->magic.spell_realm->stat;
	bool caster = FALSE, warrior = FALSE;
	if (player->class->max_attacks > 5) { 
		warrior = TRUE;
	}
	if (player->class->max_attacks < 5) {
		caster = TRUE;
	}
	while (*points_left && step >= 0) {
		switch (step) {
			case 0: {
				if (!maxed[STAT_STR] && stats[STAT_STR] < 17) {
					if (!buy_stat(STAT_STR, stats, points_spent, points_left,
								  FALSE))
						maxed[STAT_STR] = TRUE;
				} else {
					step++;
					if (caster){
						step = 3;
					}
				}
				break;
			}
			case 1: {
				if (!maxed[STAT_DEX] && player->state.stat_top[STAT_DEX]
					< 18+10) {
					if (!buy_stat(STAT_DEX, stats, points_spent, points_left,
								  FALSE))
						maxed[STAT_DEX] = TRUE;
				} else {
					step++;
				}
				break;
			}
			case 2: {
				if (player->state.stat_top[STAT_DEX] < 18+10) {
					while (stats[STAT_DEX] > 10)
						sell_stat(STAT_DEX, stats, points_spent, points_left,
								  FALSE);
					maxed[STAT_DEX] = FALSE;
				}
				step++;
			}
			case 3: 
			{
				int points_trigger = *points_left / 2;
				if (warrior) {
					points_trigger = *points_left;
				} else {
					while (!maxed[spell_stat] &&
						   (caster || stats[spell_stat] < 16) &&
						   points_spent[spell_stat] < points_trigger) {
						if (!buy_stat(spell_stat, stats, points_spent,
									  points_left, FALSE)) {
							maxed[spell_stat] = TRUE;
						}
						if (points_spent[spell_stat] > points_trigger) {
							sell_stat(spell_stat, stats, points_spent, 
									  points_left, FALSE);
							maxed[spell_stat] = TRUE;
						}
					}
				}
				while (!maxed[STAT_CON] &&
					   !(caster) && stats[STAT_CON] < 16 &&
					   points_spent[STAT_CON] < points_trigger) {
					if (!buy_stat(STAT_CON, stats, points_spent,points_left,
								  FALSE)) {
						maxed[STAT_CON] = TRUE;
					}
					if (points_spent[STAT_CON] > points_trigger) {
						sell_stat(STAT_CON, stats, points_spent, points_left,
								  FALSE);
						maxed[STAT_CON] = TRUE;
					}
				}
				step++;
				break;
			}
			case 4:{
				int next_stat;
				if (!maxed[STAT_DEX]) {
					next_stat = STAT_DEX;
				} else if (!maxed[STAT_INT] && spell_stat != STAT_INT) {
					next_stat = STAT_INT;
				} else if (!maxed[STAT_WIS] && spell_stat != STAT_WIS) {
					next_stat = STAT_WIS;
				} else {
					step++;
					break;
				}
				while (buy_stat(next_stat, stats, points_spent, points_left,
								FALSE));
				maxed[next_stat] = TRUE;
				break;
			}
			default: {
				step = -1;
				break;
			}
		}
	}
	event_signal_birthpoints(points_spent, *points_left);
	recalculate_stats(stats, *points_left);
}
static void generate_stats ( int stats [ STAT_MAX ] , int points_spent [ STAT_MAX ] , int * points_left ) { int step = 0 ; int maxed [ STAT_MAX ] = { 0 } ; int spell_stat = player -> class -> magic . spell_realm -> stat ; bool caster = FALSE , warrior = FALSE ; if ( player -> class -> max_attacks > 5 ) { warrior = TRUE ; } if ( player -> class -> max_attacks < 5 ) { caster = TRUE ; } while ( * points_left && step >= 0 ) { switch ( step ) { case 0 : { if ( ! maxed [ STAT_STR ] && stats [ STAT_STR ] < 17 ) { if ( ! buy_stat ( STAT_STR , stats , points_spent , points_left , FALSE ) ) maxed [ STAT_STR ] = TRUE ; } else { step ++ ; if ( caster ) { step = 3 ; } } break ; } case 1 : { if ( ! maxed [ STAT_DEX ] && player -> state . stat_top [ STAT_DEX ] < 18 + 10 ) { if ( ! buy_stat ( STAT_DEX , stats , points_spent , points_left , FALSE ) ) maxed [ STAT_DEX ] = TRUE ; } else { step ++ ; } break ; } case 2 : { if ( player -> state . stat_top [ STAT_DEX ] < 18 + 10 ) { while ( stats [ STAT_DEX ] > 10 ) sell_stat ( STAT_DEX , stats , points_spent , points_left , FALSE ) ; maxed [ STAT_DEX ] = FALSE ; } step ++ ; } case 3 : { int points_trigger = * points_left / 2 ; if ( warrior ) { points_trigger = * points_left ; } else { while ( ! maxed [ spell_stat ] && ( caster || stats [ spell_stat ] < 16 ) && points_spent [ spell_stat ] < points_trigger ) { if ( ! buy_stat ( spell_stat , stats , points_spent , points_left , FALSE ) ) { maxed [ spell_stat ] = TRUE ; } if ( points_spent [ spell_stat ] > points_trigger ) { sell_stat ( spell_stat , stats , points_spent , points_left , FALSE ) ; maxed [ spell_stat ] = TRUE ; } } } while ( ! maxed [ STAT_CON ] && ! ( caster ) & & stats [ STAT_CON ] < 16 && points_spent [ STAT_CON ] < points_trigger ) { if ( ! buy_stat ( STAT_CON , stats , points_spent , points_left , FALSE ) ) { maxed [ STAT_CON ] = TRUE ; } if ( points_spent [ STAT_CON ] > points_trigger ) { sell_stat ( STAT_CON , stats , points_spent , points_left , FALSE ) ; maxed [ STAT_CON ] = TRUE ; } } step ++ ; break ; } case 4 : { int next_stat ; if ( ! maxed [ STAT_DEX ] ) { next_stat = STAT_DEX ; } else if ( ! maxed [ STAT_INT ] && spell_stat != STAT_INT ) { next_stat = STAT_INT ; } else if ( ! maxed [ STAT_WIS ] && spell_stat != STAT_WIS ) { next_stat = STAT_WIS ; } else { step ++ ; break ; } while ( buy_stat ( next_stat , stats , points_spent , points_left , FALSE ) ) ; maxed [ next_stat ] = TRUE ; break ; } default : { step = -1 ; break ; } } } event_signal_birthpoints ( points_spent , * points_left ) ; recalculate_stats ( stats , * points_left ) ; }
This picks some reasonable starting values for stats based on the
 current race/class combo, etc.
This picks some reasonable starting values for stats based on the current race / class combo etc .
/* Determine whether the class is warrior */ /* Determine whether the class is priest/mage */ /* Buy base STR 17 */ /* If pure caster skip to step 3 */ /* Try and buy adj DEX of 18/10 */ /* If we can't get 18/10 dex, sell it back. */ /* 
			 * Spend up to half remaining points on each of spell-stat and 
			 * con, but only up to max base of 16 unless a pure class 
			 * [mage or priest or warrior]
			 */ /* Skip CON for casters because DEX is more important early
				 * and is handled in 4 */ /* 
			 * If there are any points left, spend as much as possible in 
			 * order on DEX, and the non-spell-stat. 
			 */ /* Buy until we can't buy any more. */ /* Tell the UI the new points situation. */ /* Recalculate everything that's changed because
	   the stat has changed, and inform the UI. */