示例#1
0
/* HMM_calcGammas computes gammas, which are the probabilities that
 * each frame is in each state
 */
void HMM_calcGammas(Hmm *m, RVec *logL, RVec *gamma) {
  int t, u, v, tt = VLENGTH(logL[0]);
  Real **a = MATRIX(m->logA), **al, **be;
  Real like;

  assert(VLENGTH(logL[0])==VLENGTH(gamma[0]));
  HMM_initGlobals(m->uu, tt);
  al = MATRIX(g_alpha);
  be = MATRIX(g_beta);
  /* calculate alpha's */
  HMM_calcAlphas(m, logL);
  /* calculate beta's -
   * beta[u][tt] = 1
   * beta[u][t] = sum(v = 1 ... m->uu, a[u][v]*beta[v][t+1]*logL[v][t+1])
   */
  for (u = 0; u<m->uu; u++) be[u][tt-1] = 0.0;
  for (t = tt-2; t>=0; t--)
    { for (u = 0; u<m->uu; u++)
	{ be[u][t] = NEGATIVE_INFINITY;
	  for (v = 0; v<m->uu; v++)
	    { be[u][t] =
		add_exp(be[u][t], a[u][v]+be[v][t+1]+VECTOR(logL[v])[t+1]);}}}
  /* calculate logL of sequence -
   * P(sequence|m) = sum(u = 1 ... m->uu, alpha[u][tt])
   */
  like = NEGATIVE_INFINITY;
  for (u = 0; u<m->uu; u++) like = add_exp(like, al[u][tt-1]);
  /* calculate responsibilities
   *               alpha[u][t]*beta[u][t]
   * gamma[u][t] = ----------------------
   *                    P(data|model)
   */
  for (t = 0; t<tt; t++)
    { for (u = 0; u<m->uu; u++) VECTOR(gamma[u])[t] = al[u][t]+be[u][t]-like;}}
示例#2
0
/* Add noise to m */
void noiseHMM(Hmm *m, int upper_triangular, Real delta){
  int u, v;
  for (u = 0; u < m->uu; u ++){
    VECTOR(m->logB)[u] = add_exp(VECTOR(m->logB)[u], my_log(delta * RANDOM));
    for (v = (upper_triangular? u: 0); v < m->uu; v ++){
      MATRIX(m->logA)[u][v] = add_exp(MATRIX(m->logA)[u][v], my_log(delta * RANDOM));
    }
  }
  normaliseHMM(m, upper_triangular);
}
示例#3
0
boolean
mon_damage(object *monster, short damage)
{
	const char *mn;
	short row, col;

	monster->hp_to_kill -= damage;

	if (monster->hp_to_kill <= 0) {
		row = monster->row;
		col = monster->col;
		dungeon[row][col] &= ~MONSTER;
		mvaddch(row, col, (int)get_dungeon_char(row, col));

		fight_monster = NULL;
		cough_up(monster);
		mn = mon_name(monster);
		sprintf(hit_message+strlen(hit_message), "defeated the %s", mn);
		message(hit_message, 1);
		hit_message[0] = 0;
		add_exp(monster->kill_exp, 1);
		take_from_pack(monster, &level_monsters);

		if (monster->m_flags & HOLDS) {
			being_held = 0;
		}
		free_object(monster);
		return(0);
	}
	return(1);
}
示例#4
0
/* HMM_logL -
 *  Given an HMM and a vector of log likelihoods for states assigned to
 *  data vectors in the sequence, returns the log likelihood of the data
 *  given the HMM.
 */
Real HMM_logL(Hmm *m, RVec *logL)
{ int u, tt = VLENGTH(logL[0]);
  Real l = NEGATIVE_INFINITY;
  /* P(sequence|m) = sum(u = 1 ... m->uu, alpha[u][tt]) */
  HMM_calcAlphas(m, logL);
  for (u = 0; u<m->uu; u++) l = add_exp(l, MATRIX(g_alpha)[u][tt-1]);
  return l;}
示例#5
0
void simple_exp(int level)
{
    int this_line = line_cnt;
    push_child(this_line,AEXP);
    add_exp(level);
    if(strcmp(tokenPos->textOfLine,"<=") == 0 || strcmp(tokenPos->textOfLine,"<") == 0 || strcmp(tokenPos->textOfLine,"!=") == 0 || strcmp(tokenPos->textOfLine,"==") == 0||strcmp(tokenPos->textOfLine,">=") == 0 || strcmp(tokenPos->textOfLine,">") == 0)
    {
		int else_to_go = push_child_else(this_line,RELOP);
        push(RELOP,else_to_go);
		pTreeType[else_to_go][0] = RELOP;
		pTreeType[else_to_go][1] = level;
        //push(RELOP, this_line);
        push_child(this_line,AEXP);
        add_exp(level+1);
    }

}
示例#6
0
void eat(void)
{
	short ch;
	short moves;
	object *obj;
	char buf[70];

	ch = pack_letter("Eat what?", FOOD);

	if (ch == ROGUE_KEY_CANCEL)
	{
		return;
	}
	if (!(obj = get_letter_object(ch)))
	{
		message("No such item.", 0);
		return;
	}
	if (obj->what_is != FOOD)
	{
		message("You can't eat that!", 0);
		return;
	}
	if ((obj->which_kind == FRUIT) || rand_percent(60))
	{
		moves = get_rand(900, 1100);
		if (obj->which_kind == RATION)
		{
			message("Yum, that tasted good.", 0);
		}
		else
		{
			sprintf(buf, "My, that was a yummy %s\b.", fruit);
			message(buf, 0);
		}
	}
	else
	{
		moves = get_rand(700, 900);
		message("Yuk, that food tasted awful.", 0);
		add_exp(2, 1);
	}
	rogue.moves_left /= 3;
	rogue.moves_left += moves;
	hunger_str[0] = 0;
	print_stats(STAT_HUNGER);

	vanish(obj, 1, &rogue.pack);
}
示例#7
0
void register_death( char_data* victim, char_data* ch, char* dt )
{
  char          tmp1  [ TWO_LINES ];
  char          tmp2  [ TWO_LINES ];
  mprog_data*  mprog;
  int            exp;

  if( victim->species != NULL ) {
    if( is_set( &victim->status, STAT_PET ) && victim->leader != NULL
      && victim->leader->pcdata != NULL ) {
      sprintf( tmp1, "%s killed by %s at %s. (Pet)",
        victim->Name( ), ch == NULL ? dt : ch->Name( ),
        victim->array->where->Location( ) );
      player_log( victim->leader, tmp1 );
      }
    for( mprog = victim->species->mprog; mprog != NULL;
      mprog = mprog->next ) 
      if( mprog->trigger == MPROG_TRIGGER_DEATH ) {
        var_mob  = victim;
        var_ch   = ch;
        var_room = Room( victim->array->where );
        execute( mprog );
        }
    return;
    }

  sprintf( tmp1, "%s killed by %s.", victim->Name( ),
    ch == NULL ? dt : ch->Name( ) );
  sprintf( tmp2, "%s killed by %s at %s.", victim->Name( ),
    ch == NULL ? dt : ch->Name( ), victim->array->where->Location( ) );
  info( tmp1, LEVEL_APPRENTICE, tmp2, IFLAG_DEATHS, 1, victim );

  exp = death_exp( victim, ch );
  add_exp( victim, -exp, "You lose %d exp for dying.\n\r" );

  sprintf( tmp1, "Killed by %s at %s.",
    ch == NULL ? dt : ch->real_name( ), victim->array->where->Location( ) );
  player_log( victim, tmp1 );
      
  if( ch != NULL && ch->pcdata != NULL ) {
    sprintf( tmp1, "Pkilled %s at %s.",
      victim->real_name( ), victim->array->where->Location( ) );
    player_log( ch, tmp1 );
    }
}
示例#8
0
文件: use.c 项目: masoo/rogueclone2s
void
eat(void)
{
    short ch;
    short moves;
    object *obj;
    char buf[70];

    ch = pack_letter(mesg[262], FOOD);
    if (ch == CANCEL) {
	return;
    }
    if (!(obj = get_letter_object(ch))) {
	message(mesg[263], 0);
	return;
    }
    if (obj->what_is != FOOD) {
	message(mesg[264], 0);
	return;
    }
    if ((obj->which_kind == FRUIT) || rand_percent(60)) {
	moves = get_rand(900, 1100);
	if (obj->which_kind == RATION) {
	    if (get_rand(1, 10) == 1) {
		message(mesg[265], 0);
	    } else
		message(mesg[266], 0);
	} else {
	    sprintf(buf, mesg[267], fruit);
	    message(buf, 0);
	}
    } else {
	moves = get_rand(700, 900);
	message(mesg[268], 0);
	add_exp(2, 1);
    }
    rogue.moves_left /= 3;
    rogue.moves_left += moves;
    hunger_str[0] = 0;
    print_stats(STAT_HUNGER);

    vanish(obj, 1, &rogue.pack);
}
示例#9
0
/* HMM_calcAlphas -
 *  Given an HMM and a vector of log likelihoods for states assigned to
 *  data vectors in the sequence, calculates the alpha values from the
 *  forward-backward algorithm.
 */
void HMM_calcAlphas(Hmm *m, RVec *logL)
{ int t, u, v, tt = VLENGTH(logL[0]);
  Real **al, **a = MATRIX(m->logA), *b = VECTOR(m->logB);
  HMM_initGlobals(m->uu, tt);
  al = MATRIX(g_alpha);
  /* alpha[u][1] = b[u]*logL[u][1]
   * alpha[u][t] = sum(v = 1 ... m->uu, a[v][u]*alpha[v][t-1])*logL[u][t]
   */
  for (u = 0; u<m->uu; u++)
    al[u][0] = VECTOR(logL[u])[0]+b[u];
  for (t = 1; t<tt; t++)
  { for (u = 0; u<m->uu; u++)
    { al[u][t] = NEGATIVE_INFINITY;
      for (v = 0; v<m->uu; v++)
      { al[u][t] = add_exp(al[u][t], a[v][u]+al[v][t-1]);}
      al[u][t] += VECTOR(logL[u])[t];
    }
  }
}
示例#10
0
void
drop_level(void)
{
    int hp;

    if (rand_percent(80) || (rogue.exp <= 5)) {
	return;
    }
    rogue.exp_points = level_points[rogue.exp - 2] - get_rand(9, 29);
    rogue.exp -= 2;
    hp = hp_raise();
    if ((rogue.hp_current -= hp) <= 0) {
	rogue.hp_current = 1;
    }
    if ((rogue.hp_max -= hp) <= 0) {
	rogue.hp_max = 1;
    }
    add_exp(1, 0);
}
void compute_posterior(Model **m, RMat *data, Real *prior, int *c_ls, int ll,
		       int cc, enum training_mode training_mode,
		       /* outputs */
		       Real *objective_function, Real *auxiliary, Real **postpC) {
  int l, c;
  Real postp_sum;
  assert(postpC);
  for (l = 0; l<ll; l++)
    for (c = 0; c<cc; c++)
      postpC[c][l] = logLike(m[c], data[l])+my_log(prior[c]);
  
  *objective_function = 0.0;
  *auxiliary = 0.0;
  for (l = 0; l<ll; l++) {
    postp_sum = NEGATIVE_INFINITY;
    for (c = 0; c<cc; c++) postp_sum = add_exp(postp_sum, postpC[c][l]);
    if(postp_sum==NEGATIVE_INFINITY)
      printf("|| A sample has -inf likelihood on all the models! \n || An outlier occurs (perhaps due to clip hack): l = %d\n", l);
    for (c = 0; c<cc; c++) {
	switch (training_mode) {
	case HMM_ML:
	  if(c==c_ls[l]) *objective_function += postpC[c][l];
	  if(postp_sum!=NEGATIVE_INFINITY)
	    postpC[c][l] -= postp_sum;
	  if(c==c_ls[l]) *auxiliary += postpC[c][l];
	  break;
	case HMM_DT:
	  if(c==c_ls[l]) *auxiliary += postpC[c][l];
	  if(postp_sum!=NEGATIVE_INFINITY)
	    postpC[c][l] -= postp_sum;
	  if(c==c_ls[l]) *objective_function += postpC[c][l];
	  break;
	default: panic("unrecognized training mode");
	}
    }
  }
}
示例#12
0
void
quaff(void)
{
	short ch;
	char buf[80];
	object *obj;

	ch = pack_letter("quaff what?", POTION);

	if (ch == CANCEL) {
		return;
	}
	if (!(obj = get_letter_object(ch))) {
		message("no such item.", 0);
		return;
	}
	if (obj->what_is != POTION) {
		message("you can't drink that", 0);
		return;
	}
	switch(obj->which_kind) {
		case INCREASE_STRENGTH:
			message("you feel stronger now, what bulging muscles!",
			0);
			rogue.str_current++;
			if (rogue.str_current > rogue.str_max) {
				rogue.str_max = rogue.str_current;
			}
			break;
		case RESTORE_STRENGTH:
			rogue.str_current = rogue.str_max;
			message("this tastes great, you feel warm all over", 0);
			break;
		case HEALING:
			message("you begin to feel better", 0);
			potion_heal(0);
			break;
		case EXTRA_HEALING:
			message("you begin to feel much better", 0);
			potion_heal(1);
			break;
		case POISON:
			if (!sustain_strength) {
				rogue.str_current -= get_rand(1, 3);
				if (rogue.str_current < 1) {
					rogue.str_current = 1;
				}
			}
			message("you feel very sick now", 0);
			if (halluc) {
				unhallucinate();
			}
			break;
		case RAISE_LEVEL:
			rogue.exp_points = level_points[rogue.exp - 1];
			message("you suddenly feel much more skillful", 0);
			add_exp(1, 1);
			break;
		case BLINDNESS:
			go_blind();
			break;
		case HALLUCINATION:
			message("oh wow, everything seems so cosmic", 0);
			halluc += get_rand(500, 800);
			break;
		case DETECT_MONSTER:
			show_monsters();
			if (!(level_monsters.next_monster)) {
				message(strange_feeling, 0);
			}
			break;
		case DETECT_OBJECTS:
			if (level_objects.next_object) {
				if (!blind) {
					show_objects();
				}
			} else {
				message(strange_feeling, 0);
			}
			break;
		case CONFUSION:
			message((halluc ? "what a trippy feeling" :
			"you feel confused"), 0);
			cnfs();
			break;
		case LEVITATION:
			message("you start to float in the air", 0);
			levitate += get_rand(15, 30);
			bear_trap = being_held = 0;
			break;
		case HASTE_SELF:
			message("you feel yourself moving much faster", 0);
			haste_self += get_rand(11, 21);
			if (!(haste_self % 2)) {
				haste_self++;
			}
			break;
		case SEE_INVISIBLE:
			sprintf(buf, "hmm, this potion tastes like %sjuice", fruit);
			message(buf, 0);
			if (blind) {
				unblind();
			}
			see_invisible = 1;
			relight();
			break;
	}
	print_stats((STAT_STRENGTH | STAT_HP));
	if (id_potions[obj->which_kind].id_status != CALLED) {
		id_potions[obj->which_kind].id_status = IDENTIFIED;
	}
	vanish(obj, 1, &rogue.pack);
}
示例#13
0
/* normaliseHMMlinear -
    Normalises an HMM in the original space so that transition probabilites
    sum to 1. After this, convert all the values from the original space to
    log space.
 */
int normaliseHMMlinear(Hmm *m, int upper_triangular, enum training_mode train_mode, int *xu)
{ int u, v, w;
  Real sum, corrected_sum;
  int flag;
  sum = 0.0;
  for (u = 0; u < m->uu; u++)
    sum += VECTOR(m->logB)[u];

  assert(fabs(sum)>0.0);
  flag = 0;
  corrected_sum = NEGATIVE_INFINITY;
  for (u = 0; u<m->uu; u++) {
    if(VECTOR(m->logB)[u]/sum < -1e-50){
      printf("normaliseHMMlinear: b error\n");
      return FALSE;
    }
    VECTOR(m->logB)[u] = my_log(VECTOR(m->logB)[u]/sum);
    /* Clip the value to zero if it is smaller than CORRECTION_EPS */
    if(train_mode == HMM_DT
       && VECTOR(m->logB)[u] != NEGATIVE_INFINITY
       && VECTOR(m->logB)[u] < my_log(CORRECTION_EPS)){
      printf("normaliseHMMlinear: clip zero\n");
      VECTOR(m->logB)[u] = NEGATIVE_INFINITY;
      flag = 1;
    }
    corrected_sum = add_exp(corrected_sum, VECTOR(m->logB)[u]);
  }
  assert(corrected_sum != NEGATIVE_INFINITY);
  if(flag){
    for(u = 0; u < m->uu; u ++)
      VECTOR(m->logB)[u] -= corrected_sum;
  }
  for (u = 0; u<m->uu; u++)
  { sum = 0.0;
    w = (upper_triangular?u:0);
    for (v = w; v<m->uu; v++) sum += MATRIX(m->logA)[u][v];
    if (sum==0.0) {
      /* A state never jumps to another state (include itself)
	 This is not the unreachable state. It may be a final state or a useless state.
	 An unreachable state is finally to be a useless state.
         We can just keep all the outward transition probabilities zero. */
      // Do NOTHING. We don't want a corrected uniform distribution.
      for(v = 0; v < m->uu; v ++)
	MATRIX(m->logA)[u][v] = NEGATIVE_INFINITY;
      continue;
    }
    flag = 0;
    corrected_sum = NEGATIVE_INFINITY;
    for (v = 0; v<m->uu; v ++) {
      if(MATRIX(m->logA)[u][v]/sum < -1e-50){
	printf("normaliseHMMlinear: a error\n");
	return FALSE;
      }
      MATRIX(m->logA)[u][v] = my_log(MATRIX(m->logA)[u][v]/sum);
      /* Clip the value to zero if it is smaller than CORRECTION_EPS */
      if(train_mode == HMM_DT
	 && MATRIX(m->logA)[u][v] != NEGATIVE_INFINITY
      	 && MATRIX(m->logA)[u][v] < my_log(CORRECTION_EPS)){
	printf("normaliseHMMlinear: clip zero\n");
      	MATRIX(m->logA)[u][v] = NEGATIVE_INFINITY;
      	flag = 1;
      }
      corrected_sum = add_exp(corrected_sum, MATRIX(m->logA)[u][v]);
    }
    assert(corrected_sum != NEGATIVE_INFINITY);
    if(flag){
      for(v = 0; v < m->uu; v ++)
    	MATRIX(m->logA)[u][v] -= corrected_sum;
    }
  }
  /* Check whether any column in logA has entries that are all NEGATIVE_INFINITY,
     which is an unreachable state. */
  if (xu != NULL){
    memset(xu, 0, sizeof(int) * m->uu);
    for(u = 0; u < m->uu; u ++){
      flag = 0;
      /* 1. The entry of initial probability is 0 */
      if(VECTOR(m->logB)[u] == NEGATIVE_INFINITY) flag ++;
      /* 2. No other state (include itself) can reach this state */
      for(v = 0; v < m->uu; v ++)
	if(MATRIX(m->logA)[v][u] != NEGATIVE_INFINITY) break;
      if(v == m->uu) flag ++;
      if(flag == 2){
	printf("AN UNREACHABLE STATE IS REMOVED! State_#: %d Total state_#: %d\n", u, m->uu);
	xu[u] = 1;
      }
    }
  }
  return TRUE;
}
示例#14
0
/* HMM_updateModel -
 *  Given an HMM and a vector of log likelihoods for states in the sequences,
 *  calculates the responsibilities of each state in the HMM for each symbol
 *  in the sequences, and maximises the model parameters based on the
 *  assigned log likelihoods.
*/
Real HMM_updateModel(Hmm *m, Hmm *new_m, RVec *logL, RVec *gamma, Real log_D,
		     Real postpC, int c, int c_ls,
		     enum training_mode training_mode) {
  int t, u, v, tt = VLENGTH(logL[0]);
  Real **a = MATRIX(m->logA), *b = VECTOR(m->logB), **al, **be, ***ps;
  Real logD = 0, like, dtf;
  int Sc = (c==c_ls);
  switch (training_mode) {
  case HMM_ML:
    assert(postpC==0.0);
    logD = NEGATIVE_INFINITY;
    break;
  case HMM_DT:
    assert(c>=0&&c_ls>=0);
    logD = log_D;
    break;
  default: panic("unrecognized training mode");
  }
  assert(VLENGTH(logL[0])==VLENGTH(gamma[0]));
  HMM_initGlobals(m->uu, tt);
  al = MATRIX(g_alpha);
  be = MATRIX(g_beta);
  ps = MATRIX(g_psi);
  /* calculate alpha's */
  HMM_calcAlphas(m, logL);
  /* calculate beta's -
   * beta[u][tt] = 1
   * beta[u][t] = sum(v = 1 ... m->uu, a[u][v]*beta[v][t+1]*logL[v][t+1])
   */
  for (u = 0; u<m->uu; u++) be[u][tt-1] = 0.0;
  for (t = tt-2; t>=0; t--)
  { for (u = 0; u<m->uu; u++)
    { be[u][t] = NEGATIVE_INFINITY;
      for (v = 0; v<m->uu; v++)
      { be[u][t] =
	add_exp(be[u][t], a[u][v]+be[v][t+1]+VECTOR(logL[v])[t+1]);}}}

  /* calculate logL of sequence -
   * P(sequence|m) = sum(u = 1 ... m->uu, alpha[u][tt])
   */
  like = NEGATIVE_INFINITY;
  for (u = 0; u<m->uu; u++)
    like = add_exp(like, al[u][tt-1]);

  /* A sample that can NEVER belong to this category */
  if(like == NEGATIVE_INFINITY){
    assert(postpC == 0.0);
    assert(Sc==0);
  }

  /* calculate responsibilities
   *               alpha[u][t]*beta[u][t]
   * gamma[u][t] = ----------------------
   *                    P(data|model)
   */
  for (t = 0; t<tt; t++){
     for (u = 0; u<m->uu; u++){
       if(like!=NEGATIVE_INFINITY)
	 VECTOR(gamma[u])[t] = al[u][t]+be[u][t]-like;
       else
	 VECTOR(gamma[u])[t] = NEGATIVE_INFINITY;
     }
  }
  /* calculate time-indexed transition probabilities
   *                alpha[u][t]*a[u][v]*logL[v][t+1]*beta[v][t+1]
   * psi[u][v][t] = ---------------------------------------------
   *                               P(data|model)
   */
  for (u = 0; u<m->uu; u++){
    for (v = 0; v<m->uu; v++){
      for (t = 0; t<tt-1; t++){
	if(like!=NEGATIVE_INFINITY)
	  ps[u][v][t] = al[u][t]+a[u][v]+VECTOR(logL[v])[t+1]+be[v][t+1]-like;
	else
	  ps[u][v][t] = NEGATIVE_INFINITY;
      }
    }
  }
  /* Update new model. The model may have been partly updated by some training
     samples. */
  a = MATRIX(new_m->logA);
  b = VECTOR(new_m->logB);
  /* calculate B
     b[u] = gamma[u][1]
     - added scaling by sum of gammas to catch any numerical accuracy problems
     not log space here
   */
  for (u = 0; u<m->uu; u++) {
    /* This may be negative */
    b[u] += (Sc-postpC)*my_exp(VECTOR(gamma[u])[0])
      +my_exp(logD+VECTOR(m->logB)[u]);
  }
  /* calculate A matrix
   *                    sum(t = 1 ... tt-1, psi[u][v][t])
   * a[u][v] = -------------------------------------------------------
   *           sum(t = 1 ... tt-1, sum(w = 1 ... m->uu, psi[u][w][t]))
   * see note above about log space
   */
  for (u = 0; u<m->uu; u++) {
    for (v = 0; v<m->uu; v++) {
      /* This may be negative */
      dtf = 0.0;
      for(t = 0; t<tt-1; t++)
	dtf += my_exp(ps[u][v][t])*(Sc-postpC) + my_exp(logD+MATRIX(m->logA)[u][v]);
      a[u][v] += dtf;
    }
  }
  for (t = 0; t<tt; t++) {
    for (u = 0; u<m->uu; u++) VECTOR(gamma[u])[t] = my_exp(VECTOR(gamma[u])[t]);
  }
  return like;
}
示例#15
0
/* normaliseHMMlinear -
    Normalises an HMM in the original space so that transition probabilites
    sum to 1. After this, convert all the values from the original space to
    log space. This function should be paired with zeroHMMlinear. If some value
    in the numerator is negative while the sum is positive, return false which
    means should increase log_D; otherwise return true.
 */
int normaliseHMMlinear(Hmm *m, int upper_triangular, enum training_mode train_mode, int *xu)
{ int u, v, w;
  Real sum, corrected_sum;
  Real delta_correction = 1e-20;
  int flag;
  sum = 0.0;
  for (u = 0; u<m->uu; u++){
    //printf("b0[%d]=%e ", u, VECTOR(m->logB)[u]);
    sum += VECTOR(m->logB)[u];
  }
  //printf("\n");
  assert(fabs(sum)>0.0);
  flag = 0;
  corrected_sum = NEGATIVE_INFINITY;
  for (u = 0; u<m->uu; u++) {
    if(VECTOR(m->logB)[u]/sum < 0.0){
      //printf("@@@ b[%d] = %0.10lf sum = %0.4lf\n", u, VECTOR(m->logB)[u], sum);
      return FALSE;
    }
    VECTOR(m->logB)[u] = my_log(VECTOR(m->logB)[u]/sum);
    /* Clip the value to zero if it is smaller than delta_correction
       This jumps to another hopefully better optimization space */
    if(train_mode == HMM_DT && VECTOR(m->logB)[u] != NEGATIVE_INFINITY 
       && VECTOR(m->logB)[u] < my_log(delta_correction)){
      printf("b[%d]=%e is replaced by 0.0!\n", u, my_exp(VECTOR(m->logB)[u]));
      VECTOR(m->logB)[u] = NEGATIVE_INFINITY;
      flag = 1;
    }
    corrected_sum = add_exp(corrected_sum, VECTOR(m->logB)[u]);
  }
  /* Normalise the corrected array is necessary */
  if(flag){
    for(u = 0; u < m->uu; u ++)
      VECTOR(m->logB)[u] -= corrected_sum;
  }

  for (u = 0; u<m->uu; u++)
  { sum = 0.0;
    w = (upper_triangular?u:0);
    for (v = w; v<m->uu; v++) sum += MATRIX(m->logA)[u][v];
    if (sum==0.0) {
      /* A state never jumps to another state (include itself)
	 This is not the unreachable state. It may be a final state or a useless state.
	 An unreachable state is finally to be a useless state.
         We can just keep all the outward transition probabilities zero. */
      // Do NOTHING. We don't want a corrected normal distribution. 
      for(v = 0; v < m->uu; v ++)
	MATRIX(m->logA)[u][v] = NEGATIVE_INFINITY;
      continue;
    }
    flag = 0;
    corrected_sum = NEGATIVE_INFINITY;
    for (v = 0; v<m->uu; v ++) {
      if(MATRIX(m->logA)[u][v]/sum < 0.0){
	//printf("@@@ m->A[%d][%d] = %0.4lf   sum = %0.4lf\n", u, v, MATRIX(m->logA)[u][v], sum);
	return FALSE;
      }
      MATRIX(m->logA)[u][v] = my_log(MATRIX(m->logA)[u][v]/sum);
      /* Clip the value to zero if it is smaller than delta_correction
       This jumps to another hopefully better optimization space */
      if(train_mode == HMM_DT && MATRIX(m->logA)[u][v] != NEGATIVE_INFINITY 
	 && MATRIX(m->logA)[u][v] < my_log(delta_correction)){
	//printf("a[%d][%d]=%e is replaced by 0.0!\n", u, v, my_exp(MATRIX(m->logA)[u][v]));
	MATRIX(m->logA)[u][v] = NEGATIVE_INFINITY;
	flag = 1;
      }
      corrected_sum = add_exp(corrected_sum, MATRIX(m->logA)[u][v]);
    }
    if(flag){
      for(v = 0; v < m->uu; v ++)
	MATRIX(m->logA)[u][v] -= corrected_sum;
    }
  }

  /* Check whether any column in logA has entries that are all NEGATIVE_INFINITY,
     which is an unreachable state. */
  memset(xu, 0, sizeof(int) * m->uu);
  for(u = 0; u < m->uu; u ++){
    flag = 0;
    if(VECTOR(m->logB)[u] == NEGATIVE_INFINITY) flag ++;
    for(v = 0; v < m->uu; v ++)
      if(MATRIX(m->logA)[v][u] != NEGATIVE_INFINITY) break;
    if(v == m->uu) flag ++;
    if(flag == 2){
      //printf("AN UNREACHABLE STATE IS TO BE REMOVED! State_#: %d\n", u);
      xu[u] = 1;
    }
  }
   
  return TRUE;
}
示例#16
0
/*
 * (zerogue 0.4.3) Applies the effect of a potion to the rogue.
 */
void apply_potion( unsigned short pkind )
{
	char buf[80] ;

	switch( pkind )
	{
		case INCREASE_STRENGTH:
			message( "You feel stronger now, what bulging muscles!", 0 ) ;
			rogue.str_current++ ;
			rogue.str_max++ ; // (zerogue 0.4.1)
			break ;
		case RESTORE_STRENGTH:
			rogue.str_current = rogue.str_max;
			message( "This tastes great, you feel warm all over.", 0 ) ;
			break ;
		case HEALING:
			message( "You begin to feel better.", 0 ) ;
			potion_heal(0) ;
			break ;
		case EXTRA_HEALING:
			message( "You begin to feel much better.", 0 ) ;
			potion_heal(1) ;
			break ;
		case POISON:
			if( !sustain_strength )
			{
				rogue.str_current -= get_rand( 1, 3 ) ;
				if( rogue.str_current < 1 )
					rogue.str_current = 1 ;
			}
			message( "You feel very sick now.", 0 ) ;
			if( halluc ) unhallucinate() ;
			break ;
		case RAISE_LEVEL:
			rogue.exp_points = level_points[rogue.exp - 1] ;
			add_exp( 1, 1 ) ;
			break ;
		case BLINDNESS:
			go_blind() ;
			break ;
		case HALLUCINATION:
			message( "Oh wow, everything seems so cosmic.", 0 ) ;
			halluc += get_rand( 500, 800 ) ;
			break ;
		case DETECT_MONSTER:
			show_monsters() ;
			if( !(level_monsters.next_monster) )
				message( strange_feeling, 0 ) ;
			break;
		case DETECT_OBJECTS:
			if( level_objects.next_object )
				if( !blind ) show_objects() ;
			else
				message( strange_feeling, 0 ) ;
			break;
		case CONFUSION:
			message( ( halluc ? "What a trippy feeling." :
			                    "You feel confused." ), 0 ) ;
			confuse() ;
			break;
		case LEVITATION:
			message( "You start to float in the air.", 0 ) ;
			levitate += get_rand( 15, 30 ) ;
			being_held = 0 ;
		   	bear_trap = 0 ;
			break ;
		case HASTE_SELF:
			message( "You feel yourself moving much faster.", 0 ) ;
			haste_self += get_rand( 11, 21 ) ;
			if( !(haste_self % 2) ) haste_self++ ;
			break ;
		case SEE_INVISIBLE:
			sprintf( buf, "Hmm ... this potion tastes like %sjuice.", fruit ) ;
			message( buf, 0 ) ;
			if( blind ) unblind() ;
			see_invisible = 1 ;
			relight() ;
			break ;
		case RESTORE_LEVEL:
			if( expmod < 0 )
			{
				// Restore lost hit points.
				short i ;
				for( i = 0 ; i > expmod ; i-- )
					rogue.hp_max += hp_raise() ;
				expmod = 0 ;  // Clear negative levels.
				message( "You feel your lost vitality returning.", 0 ) ;
			}
			else
				message( "Your thirst is thoroughly quenched.", 0 ) ;
			break ;
		default:
			message( "Nothing happens.", 0 ) ;
	}

	return ;
}
示例#17
0
文件: use.c 项目: masoo/rogueclone2s
void
quaff(void)
{
    short ch;
    char buf[80];
    object *obj;

    ch = pack_letter(mesg[231], POTION);
    if (ch == CANCEL) {
	return;
    }
    if (!(obj = get_letter_object(ch))) {
	message(mesg[232], 0);
	return;
    }
    if (obj->what_is != POTION) {
	message(mesg[233], 0);
	return;
    }
    switch (obj->which_kind) {
    case INCREASE_STRENGTH:
	message(mesg[234], 0);
	rogue.str_current++;
	if (rogue.str_current > rogue.str_max) {
	    rogue.str_max = rogue.str_current;
	}
	break;
    case RESTORE_STRENGTH:
	rogue.str_current = rogue.str_max;
	message(mesg[235], 0);
	break;
    case HEALING:
	message(mesg[236], 0);
	potion_heal(0);
	break;
    case EXTRA_HEALING:
	message(mesg[237], 0);
	potion_heal(1);
	break;
    case POISON:
	if (!sustain_strength) {
	    rogue.str_current -= get_rand(1, 3);
	    if (rogue.str_current < 1) {
		rogue.str_current = 1;
	    }
	}
	message(mesg[238], 0);
	if (halluc) {
	    unhallucinate();
	}
	break;
    case RAISE_LEVEL:
	rogue.exp_points = level_points[rogue.exp - 1];
	add_exp(1, 1);
	break;
    case BLINDNESS:
	go_blind();
	break;
    case HALLUCINATION:
	message(mesg[239], 0);
	halluc += get_rand(500, 800);
	break;
    case DETECT_MONSTER:
	show_monsters();
	if (!(level_monsters.next_monster)) {
	    message(strange_feeling, 0);
	}
	break;
    case DETECT_OBJECTS:
	if (level_objects.next_object) {
	    if (!blind) {
		show_objects();
	    }
	} else {
	    message(strange_feeling, 0);
	}
	break;
    case CONFUSION:
	message((halluc ? mesg[240]
		 : mesg[241]), 0);
	confuse();
	break;
    case LEVITATION:
	message(mesg[242], 0);
	levitate += get_rand(15, 30);
	being_held = bear_trap = 0;
	break;
    case HASTE_SELF:
	message(mesg[243], 0);
	haste_self += get_rand(11, 21);
	if (!(haste_self % 2)) {
	    haste_self++;
	}
	break;
    case SEE_INVISIBLE:
	sprintf(buf, mesg[244], fruit);
	message(buf, 0);
	if (blind) {
	    unblind();
	}
	see_invisible = true;
	relight();
	break;
    }
    print_stats((STAT_STRENGTH | STAT_HP));
#if !defined( ORIGINAL )
    id_potions[obj->which_kind].id_status = IDENTIFIED;
#else /* ORIGINAL */
    if (id_potions[obj->which_kind].id_status != CALLED) {
	id_potions[obj->which_kind].id_status = IDENTIFIED;
    }
#endif /* ORIGINAL */
    vanish(obj, 1, &rogue.pack);
}
示例#18
0
文件: alchemy.c 项目: atrinik/dwc
/**
 * Main part of the alchemy code. From this we call functions that take a
 * look at the contents of the 'cauldron' and, using these ingredients,
 * we construct an integer formula value which is referenced (randomly)
 * against a formula list (the formula list chosen is based on the #
 * contents of the cauldron).
 *
 * If we get a match between the recipe indicated in cauldron contents
 * and a randomly chosen one, an item is created and experience awarded.
 * Otherwise various failure effects are possible (getting worse and
 * worse with # cauldron ingredients). Note that the 'item' to be made
 * can be *anything* listed on the artifacts list in lib/artifacts which
 * has a recipe listed in lib/formulae.
 *
 * To those wondering why I am using the funky formula index method:
 *   1) I want to match recipe to ingredients regardless of ordering.
 *   2) I want a fast search for the 'right' recipe.
 *
 * Note: it is just possible that a totally different combination of
 * ingredients will result in a match with a given recipe. This is not a
 * bug! There is no good reason (in my mind) why alchemical processes
 * have to be unique -- such a 'feature' is one reason why players might
 * want to experiment around. :)
 * @param caster Who is doing alchemy.
 * @param cauldron The cauldron in which alchemy should take place. */
static void attempt_do_alchemy(object *caster, object *cauldron)
{
	recipelist *fl;
	recipe *rp = NULL;
	float success_chance;
	int numb, ability = 1;
	int formula = 0;

	/* Only players for now */
	if (caster->type != PLAYER)
	{
		return;
	}

	/* If no ingredients, no formula! Let's forget it */
	if (!(formula = content_recipe_value(cauldron)))
	{
		return;
	}

	numb = numb_ob_inside(cauldron);

	if ((fl = get_formulalist(numb)))
	{
		/* The caster only gets an increase in ability if they know
		 * alchemy skill */
		if (find_skill(caster, SK_ALCHEMY) != NULL)
		{
			change_skill(caster, SK_ALCHEMY);
			ability += (int) ((float) SK_level(caster) * (float) ((float) (4 + cauldron->magic) / 4.0f));
		}

#ifdef ALCHEMY_DEBUG
		LOG(llevDebug, "DEBUG: Got alchemy ability lvl = %d\n", ability);
#endif

		if (QUERY_FLAG(caster, FLAG_WIZ))
		{
			rp = fl->items;

			while (rp && (formula % rp->index) != 0)
			{
#ifdef EXTREME_ALCHEMY_DEBUG
				LOG(llevDebug, "DEBUG: found list %d formula: %s of %s (%d)\n", numb, rp->arch_name, rp->title, rp->index);
#endif
				rp = rp->next;
			}

			if (rp)
			{
#ifdef ALCHEMY_DEBUG
				if (rp->title != shstr_cons.NONE)
				{
					LOG(llevDebug, "DEBUG: WIZ got formula: %s of %s\n", rp->arch_name, rp->title);
				}
				else
				{
					LOG(llevDebug, "DEBUG: WIZ got formula: %s (nbatches:%d)\n", rp->arch_name, formula / rp->index);
				}
#endif
				attempt_recipe(caster, cauldron, ability, rp, formula / rp->index);
			}
			else
			{
				LOG(llevDebug, "DEBUG: WIZ couldnt find formula for ingredients.\n");
			}

			return;
		}

		/* Find the recipe */
		for (rp = fl->items; rp != NULL && (formula % rp->index) != 0; rp = rp->next)
		{
		}

		/* If we found a recipe */
		if (rp)
		{
			float ave_chance = fl->total_chance / (float) fl->number;
			object *item;

			/* Create the object **FIRST**, then decide whether to keep it. */
			if ((item = attempt_recipe(caster, cauldron, ability, rp, formula / rp->index)) != NULL)
			{
				/* Compute base chance of recipe success */
				success_chance = ((float) (15 * ability) / (float) (15 * ability + numb * item->level * (numb + item->level + formula / rp->index)));

				if (ave_chance == 0)
				{
					ave_chance = 1;
				}

				/* Adjust the success chance by the chance from the recipe list	*/
				if (ave_chance > rp->chance)
				{
					success_chance *= ((float) rp->chance + ave_chance) / (2.0f * ave_chance);
				}
				else
				{
					success_chance = 1.0f - ((1.0f - success_chance) * ((float) rp->chance + ave_chance) / (2.0f * (float) rp->chance));
				}

#ifdef ALCHEMY_DEBUG
				LOG(llevDebug, "DEBUG: percent success chance =  %f\n", success_chance);
#endif

				/* Roll the dice */
				if ((float) (rndm(0, 99)) <= 100.0 * success_chance)
				{
					/* We learn from our experience IF we know something of the alchemical arts */
					if (caster->chosen_skill && caster->chosen_skill->stats.sp == SK_ALCHEMY)
					{
						/* More exp is given for higher ingred number recipes */
						sint64 amount = numb * numb * calc_skill_exp(caster, item, -1);
						add_exp(caster, amount, SK_ALCHEMY);
						/* So when skill id this item, less xp is awarded */
						item->stats.exp = 0;
#ifdef EXTREME_ALCHEMY_DEBUG
						LOG(llevDebug, "DEBUG: %s gains %d experience points.\n", caster->name, amount);
#endif
					}

					return;
				}
			}
		}
	}

	/* If we get here, we failed! */
	alchemy_failure_effect(caster, cauldron, rp, calc_alch_danger(caster, cauldron));
}