Exemplo n.º 1
0
HEADER_DECLARE
bool Term_exact_eq(Term* a, Term* b){
    a = chase(a);
    b = chase(b);
    if(a->type != b->type){
        return false;
    }
    switch(a->type){
    case MOVED:
        fatal_error("Found a moved term when comparing terms");
    case VAR:
        return a == b;
    case INTEGER:
        return a->data.integer == b->data.integer;
    case STRING:
        return !Buffer_cmp(&a->data.string, &b->data.string);
    case FUNCTOR:
        if(a->data.functor.atom != b->data.functor.atom){
            return false;
        }
        if(a->data.functor.size != b->data.functor.size){
            return false;
        }
        for(int i = 0; i < a->data.functor.size; i++){
            if(!Term_exact_eq(a->data.functor.args[i], b->data.functor.args[i])){
                return false;
            }
        }
        return true;
    case DICT:
        fatal_error("unimplemented: exact_eq dict");
    }
    UNREACHABLE;
}
Exemplo n.º 2
0
int
pushsnake(void)
{
	int	i, bonus;
	int	issame = 0;
	struct point tmp;

	/*
	 * My manual says times doesn't return a value.  Furthermore, the
	 * snake should get his turn every time no matter if the user is
	 * on a fast terminal with typematic keys or not.
	 * So I have taken the call to times out.
	 */
	for (i = 4; i >= 0; i--)
		if (same(&snake[i], &snake[5]))
			issame++;
	if (!issame)
		pchar(&snake[5], ' ');
	/* Need the following to catch you if you step on the snake's tail */
	tmp.col = snake[5].col;
	tmp.line = snake[5].line;
	for (i = 4; i >= 0; i--)
		snake[i + 1] = snake[i];
	chase(&snake[0], &snake[1]);
	pchar(&snake[1], SNAKETAIL);
	pchar(&snake[0], SNAKEHEAD);
	for (i = 0; i < 6; i++) {
		if ((same(&snake[i], &you)) || (same(&tmp, &you))) {
			surround(&you);
			i = (cashvalue) % 10;
			bonus = arc4random_uniform(10);
			mvprintw(lcnt + 1, 0, "%d\n", bonus);
			refresh();
			delay(30);
			if (bonus == i) {
				spacewarp(1);
#ifdef LOGGING
				logit("bonus");
#endif
				flushinp();
				return(1);
			}
			flushinp();
			endwin();
			if (loot >= penalty) {
				printf("\nYou and your $%d have been eaten\n", cashvalue);
			} else {
				printf("\nThe snake ate you.  You owe $%d.\n", -cashvalue);
			}
#ifdef LOGGING
			logit("eaten");
#endif
			length(moves);
			snscore(TOPN);
			close(rawscores);
			exit(0);
		}
	}
	return(0);
}
Exemplo n.º 3
0
HEADER_DECLARE
hash_t hash_rec(Term* term, hash_t hash){
    term = chase(term);
    switch(term->type){
    case INTEGER:
        return hash_integer(term->data.integer, hash);
    case FUNCTOR:
        hash = hash_atom(term->data.functor.atom, hash);
        functor_size_t size = term->data.functor.size;
        if(size){
            hash = hash_byte(size, hash);
            for(functor_size_t i = 0; i < size; i++){
                hash = hash_rec(term->data.functor.args[i], hash);
            }
        }
        return hash;
    case STRING:
        return hash_string(&term->data.string, hash);
    case VAR:
        fatal_error("Cannot hash variable '%s'", term->data.var.name);
    case DICT:
        fatal_error("unimplemented: hash dict");
    case MOVED:
        fatal_error("Cannot hash a moved term");
    }
    UNREACHABLE;
}
Exemplo n.º 4
0
Arquivo: ring.c Projeto: kahrs/cda
void
cksignal(Signal *s)
{
	int i, j, pin, wc;
	float length, cap, rise_time, prop_delay, ok_length, delay_per;
	Wire *w;
	Chip *c;
	Line *l;

	if((s->type != NORMSIG) || (s->n == 0))
		return;
	cap = device_cap(s);
	for (w = s->wires; w; w = w->next)
	    for(i = 0; i < w->ninf; i++)
		for(j=0; j<s->n; j++)
		    if (pteq(w->inflections[i].p, s->pins[j].p))
			if ((c = (Chip *) symlook(s->coords[j].chip, S_CHIP, (void *) 0)) == 0)
				f_major("chip %s not found", s->coords[j].chip);
			else
			if (isdriver(c->type->tt[s->coords[j].pin-1])) {
				rise_time = get_rise(c->type->family);
				l = (Line *) pinlook(XY(s->pins[j].p.x, s->pins[j].p.y), 0);
				length = chase(l, 0);
				prop_delay = sqrt(L0 * length * (C0 * length + cap));
				delay_per = sqrt(L0 * (C0 + cap / length));
				ok_length = (rise_time * 1000.0) / (konstant * delay_per);
				if (length > ok_length)
fprint(1, "%s (%C): %f mils > %f mils, z = %f\n", s->name, s->coords[j], length, ok_length, sqrt((L0 * length) / (C0 * length + cap)));
/***fprint(1, "%s : %C = %f > %f, %f, %f, %f = %f\n", s -> name, s->coords[j], length, ok_length, L0 * length, C0 * length, cap, prop_delay); ***/
			}
}
Exemplo n.º 5
0
Arquivo: ring.c Projeto: kahrs/cda
float chase(Line *l, int level)
{
	Line *connecting;
	Wire *w;
	int ip;
	float l_length, r_length, max_length;
	Point lastPt;
	if (!l) return(0.0);
	if (l -> length > 0.0) return(l -> length);
	max_length = 0.0;
	for(; l; l = l->connect) {
		l_length = r_length = 0.0;
		w = l->wire;
		lastPt = w->inflections[0].p;
		for(ip=0; ip<w->ninf; ip++) {
			if (ip <= l->inf)
				l_length += Euclidian(lastPt, w->inflections[ip].p);
			else
				r_length += Euclidian(lastPt, w->inflections[ip].p);
			lastPt = w->inflections[ip].p;
		}
		l -> length = max(l_length, r_length);
		l_length = r_length = 0.0;
		for(ip=0; ip<w->ninf; ip++)
		    if (ip != l->inf)
			for (connecting = (Line *) pinlook(XY(w->inflections[ip].p.x, w->inflections[ip].p.y), 0);
			connecting; connecting = connecting -> connect)
			    if (connecting -> wire != w)
			        r_length = max(r_length, chase(connecting, level+1));
		l -> length += r_length;
		max_length = max(max_length, l -> length);
	}
	return(max_length);
}
Exemplo n.º 6
0
HEADER_DECLARE
integer_t Integer_get(Term* term){
    term = chase(term);
    if(term->type != INTEGER){
        fatal_error("expected integer");
    }
    return term->data.integer;
}
Exemplo n.º 7
0
//Return a reaction based on state
Enemy::Reaction Enemy::ruminate()
{
	//Update player presence
	player_ = getPlayer_();
	play_ = (player_ != nullptr);

	//Change states based on behaviour
	float hpf = (float)getHP() / (float)(startingHP_);
	
	//Distance to player, if she's there
	float between = FLT_MAX;
	if (play_) between = (getPosition() - player_->getPosition()).Length();

	//If the player's dead, hang ten
	if (!play_) stateOfMind_ = IDLE;

	//Flee if hurt
	else if (hpf < ouch_[brainStem_.pain_tolerance]) stateOfMind_ = FLEE;

	//Otherwise think about what we should do
	else switch (stateOfMind_)
	{
	//If we're running, check if we're healthy enough to stop
	case FLEE:
		if (hpf > ouch_[brainStem_.pain_tolerance]) stateOfMind_ = IDLE;
		
	//If we're chilling, check if the player is messing with the bull
	case IDLE:
		if (play_ && between < 128 && between <= chaseRange_[brainStem_.personal_space] || angry_ == angryMAX_) stateOfMind_ = CHASE;
	
	//If we're chasing, make sure we can still see him
	case CHASE:
			if (play_ && between > chaseRangeMAX_[brainStem_.perserverance]) stateOfMind_ = IDLE;
	}

	//Execute our current mood
	switch (stateOfMind_)
	{
	case IDLE:
		//std::cout << "idle" << std::endl;
		return idle();
		break;
	case CHASE:
		//std::cout << "chase" << std::endl;
		return chase();
		break;
	case FLEE:
		//std::cout << "flee" << std::endl;
		return flee();
		break;
	}

	return Reaction();
}
Exemplo n.º 8
0
HEADER_DECLARE
atom_t intern(Term* str){
    FRAME_ENTER_1(str);
    assert(str->type == STRING, "cannot intern non-string");
    FRAME_LOCAL(term) = chase(HashTable_get(root.interned, str));
    if(!Var_is_terminal(term)){
        guarantee(is_Atom(term), "interned term is not an atom");
        D_ATOM{
            debug("already interned `%s' as %lu\n", str->data.string.ptr, term->data.functor.atom);
        }
        FRAME_RETURN(atom_t, term->data.functor.atom);
    }
Exemplo n.º 9
0
	int checkDetectionRadius(glm:: mat4 tar[], float tarBR[] , int nTargets)	{

		for (int i = 0; i < nTargets; i++)	{
			if (collision(tar[i], tarBR[i], 0))	{
				chase(tar[i]);
				printf("MISSILE FOUND SITE %d\n",i);
				return i;
			}
		}
		return -1;
		
	}
Exemplo n.º 10
0
//------------------------------------------------------------------------------
int __attribute__((OS_main)) main(void)
{
	DDRC = 0xFF;
	PORTC = 0xFF;
	DDRB = 0xFF;
	PORTB = 0xFF;
	DDRD = 0xFF;
	PORTD = 0xFF;

	H_SLEEP;
	
	rnaInit();
	sei();

	TCCR0B = 1<<CS00;
	_delay_ms(100);

	srand( TCNT0 );

	TIMSK0 = 1<<TOIE0; // enable the interrupt

	for( unsigned char i=0; i<16; i++ )
	{
		intensity[i] = 0x0;
	}

	for(;;)
	{
		compute(20);
		glowPick(16);
		chase(1);
		glowRandom(20);
		chase(2);
		randomPick(128);
		chase(1);
	}
}
Exemplo n.º 11
0
void Ghost::navigate(Direction directions)
{
	Direction opposite = NONE;
	if (direction)
	{
		switch (direction)
		{
		case UP:	opposite = DOWN;	break;
		case DOWN:	opposite = UP;		break;
		case LEFT:	opposite = RIGHT;	break;
		case RIGHT:	opposite = LEFT;	break;
		}

		directions = (Direction)(directions & ~opposite);

		if (directions == NONE) directions = opposite;
	}

	switch (directions)
	{
	case UP:	direction = UP;		return;
	case DOWN:	direction = DOWN;	return;
	case LEFT:	direction = LEFT;	return;
	case RIGHT:	direction = RIGHT;	return;
	default: break;
	}

	switch (mode)
	{
	case INACTIVE:														break;
	case CHASE:		direction = chase(targetX, targetY, directions);	break;
	case SCATTER:	direction = chase(homeX, homeY, directions);		break;
	case AFRAID:	direction = flee(directions);						break;
	case HOME:															break;
	}
}
Exemplo n.º 12
0
void Ghost::move()
{
    if(isInsideGhostHouse())
    {
        if(isFree())
        {
            if(!isCaught())
            {
                release();
            }
        }
    }
    else if(isOnTheMove()) localMove();
    else if(isCaught()) goHome();
    else if(areGhostsScared()) escape();
    else if(isScattering()) scatter();
    else chase();
}
Exemplo n.º 13
0
unsigned int Thief::think()
{
    switch( _state )
    {
        case SEEK:
            seek(); // Procura por uma vítima
            break;
        
        case CHASE:
            chase(); // Persegue uma vítima
            break;
            
        case STEAL:
            steal(); // Rouba o meteorito
            break;
    }
    return 0;
}
Exemplo n.º 14
0
void zombie::move()
{

	 last_pos =  pos;

     if(chasing)
     {
        chase();
     }
     else
     {
         
         int new_pos_x[4],new_pos_y[4];
         if(pos.x!=0)
             {
                 new_pos_x[0]=pos.x-1;
                 new_pos_y[0]=pos.y;
             }
         else
             {
                 new_pos_x[0]=-1;
                 new_pos_y[0]=-1;
             }

         if(pos.x!=X-1)
             {
                 new_pos_x[2]=pos.x+1;
                 new_pos_y[2]=pos.y;
             }
         else
             {
                 new_pos_x[2]=-1;
                 new_pos_y[2]=-1;
             }
         if(pos.y!=0)
             {
                 new_pos_x[3]=pos.x;
                 new_pos_y[3]=pos.y-1;
             }
         else
             {
                 new_pos_x[3]=-1;
                 new_pos_y[3]=-1;
             }

         if(pos.y!=X-1)
             {
                 new_pos_x[1]=pos.x;
                 new_pos_y[1]=pos.y+1;
             }
         else
             {
                 new_pos_x[1]=-1;
                 new_pos_y[1]=-1;
             }
        int decision = decide( (new_pos_x[0]!=-1 && new_pos_y[0]!=-1)?1.0:0 ,(new_pos_x[1]!=-1 && new_pos_y[1]!=-1)?1.0:0,(new_pos_x[2]!=-1 && new_pos_y[2]!=-1)?1.0:0,(new_pos_x[3]!=-1 && new_pos_y[3]!=-1)?1.0:0);
        
        switch(decision)
        {
            case 0:moving(*it_zombie,grid[pos.x-1][pos.y]); break;
            case 1:moving(*it_zombie,grid[pos.x][pos.y-1]); break;
            case 2:moving(*it_zombie,grid[pos.x+1][pos.y]); break;
            case 3:moving(*it_zombie,grid[pos.x][pos.y+1]); break;
        }
     }
}
Exemplo n.º 15
0
//Lennard-Jones based AI
void Enemy::ljpTest()
{
	b2Vec2 sum(0, 0);
	b2Vec2 flock(0, 0);
	b2Vec2 chase(0, 0);
	b2Vec2 fire(0, 0);

	//Chase and fire at player?
	Shape* player = getPlayer_();
	if (player)
	{
		b2Vec2 myPos = getPosition();
		b2Vec2 pPos = player->getPosition();
		b2Vec2 between = (pPos - myPos);
		float dist = between.Length();

		if (!chasing_ && dist < chaseRange_[3])
		{
			chasing_ = true;
		}

		if (chasing_ && dist < chaseRangeMAX_[4])
		{
			chase = LJP(pPos, 100.f, 200.f, 1.0, 1.8);
		}

		else chasing_ = false;

		//Fire if in visible range
		if (dist < visRange_[3])
		{
			fire = LJP(pPos, 100, 0, 2.0, 0);
		}
	}

	if (chasing_) orient(chase);

	//Swarm to shapes
	int count = 0;
	for (Enemy* v : swarm_)
	{
		if (v != this)
		{
			b2Vec2 myPos = getPosition();
			b2Vec2 theirPos = v->getPosition();
			b2Vec2 between = theirPos - myPos;
			float minDist = v->getSize() + size_;
			float dist = between.Length();

			if (between.Length() < flockRange_)
			{
				b2Vec2 steer(0, 0);
				if (!chasing_) steer = LJP(theirPos, 75.f, 300.f, 1.0f, 1.8f);

				else if (v->getVertices() == vertices_) 
					 steer = LJP(theirPos, 0, 100.f, 0, 1.8f);

				else steer = LJP(theirPos, 0, 100.f, 0, 1.8f);

				if (steer.x != 0 && steer.y != 0)
				{
					sum += steer;
					count++;
				}
			}
		}
	}


	//get average
	if (count > 0)
	{
		sum.x /= static_cast<float>(count);
		sum.y /= static_cast<float>(count);
	}

	else sum = b2Vec2_zero;

	//If we didn't want to fire
	float seePlayer = fire.Length();
	if (seePlayer == 0)
	{
		angry_ -= angryMAX_ / triggerSatisfaction_[4];
	}

	else
	{
		orient(fire);
		chill_ = 0;
		angry_ += seePlayer;
	}

	//If we're mad enough
	float ammo = (float)getWeaponBar() / (float)getWeaponBarMAX();
	if (angry_ > angryMAX_ && seePlayer != 0)
	{
		if (fireAt(fire, 0.2f))
		{
			angry_ -= triggerSatisfaction_[4];
		}
		else release();

		
		if (ammo< 0.1f)
			reup();
	}
	angry_ = fmax(angry_, 0);

	//Chill out when idle
	if (angry_ == 0 && seePlayer == 0)
	{
		chill_ -= 1;

		if (chill_ <= chillMIN_)
		{
			if (ammo < 1.f)
				reup();

			spin(-0.05f);
		}
	}
	chill_ = fmax(chill_, chillMIN_);

	move(chase + sum);
}
Exemplo n.º 16
0
void AI_main(struct RoboAI *ai, struct blob *blobs, void *state)
{
    /*************************************************************************
     You will be working with a state-based AI. You are free to determine
     how many states there will be, what each state will represent, and
     what actions the robot will perform based on the state as well as the
     state transitions.

     You must *FULLY* document your state representation in the report

     Here two states are defined:
     State 0,100,200 - Before robot ID has taken place (this state is the initial
                       state, or is the result of pressing 'r' to reset the AI)
     State 1,101,201 - State after robot ID has taken place. At this point the AI
                       knows where the robot is, as well as where the opponent and
                       ball are (if visible on the playfield)

     Relevant UI keyboard commands:
     'r' - reset the AI. Will set AI state to zero and re-initialize the AI
    data structure.
     't' - Toggle the AI routine (i.e. start/stop calls to AI_main() ).
     'o' - Robot immediate all-stop! - do not allow your NXT to get damaged!

     ** Do not change the behaviour of the robot ID routine **
    **************************************************************************/

    if (ai->st.state == 0 || ai->st.state == 100 || ai->st.state == 200) // Initial set up - find own, ball, and opponent blobs
    {
        // Carry out self id process.
        fprintf(stderr, "Initial state, self-id in progress...\n");
        id_bot(ai, blobs);
        if ((ai->st.state % 100) != 0) // The id_bot() routine will change the AI state to initial state + 1
        {
            // if robot identification is successful.
            if (ai->st.self->cx[0] >= 512) ai->st.side = 1; else ai->st.side = 0;
            all_stop();
            clear_motion_flags(ai);
            fprintf(stderr, "Self-ID complete. Current position: (%f,%f), current heading: [%f, %f], AI state=%d\n", ai->st.self->cx[0], ai->st.self->cy[0], ai->st.self->mx, ai->st.self->my, ai->st.state);
        }
    }
    else
    {
        /****************************************************************************
         TO DO:
         You will need to replace this 'catch-all' code with actual program logic to
         have the robot do its work depending on its current state.
         After id_bot() has successfully completed its work, the state should be
         1 - if the bot is in SOCCER mode
         101 - if the bot is in PENALTY mode
         201 - if the bot is in CHASE mode

         Your AI code needs to handle these states and their associated state
         transitions which will determine the robot's behaviour for each mode.
        *****************************************************************************/
        // track_agents(ai,blobs);        // Currently, does nothing but endlessly track
        // fprintf(stderr,"Just trackin'!\n");    // bot, opponent, and ball.

        switch(ai->st.state){
            case 101:

                kick();
                sleep(2);
                break;
            case 201:
                chase(ai);
                break;
        }
    }

}
Exemplo n.º 17
0
void
do_chase(struct thing *th, int flee)
{
    struct room    *rer;        /* room of chaser */
    struct room    *ree;        /* room of chasee */
    struct room    *old_room;   /* old room of monster */
    struct room    *new_room;   /* new room of monster */

    int i, mindist = INT_MAX, maxdist = INT_MIN, dist = INT_MIN;

    int last_door = -1;     /* Door we just came from */
    int stoprun = FALSE;    /* TRUE means we are there */
    int rundoor;            /* TRUE means run to a door */
    int hit_bad = FALSE;    /* TRUE means hit bad monster */
    int mon_attack;         /* TRUE means find a monster to hit */

    char    sch;
    struct linked_list *item;
    coord   this;           /* Temporary destination for chaser */

    if (!th->t_ischasing)
        return;

    /* Make sure the monster can move */

    if (th->t_no_move != 0)
    {
        th->t_no_move--;
        return;
    }

    /*
     * Bad monsters check for a good monster to hit, friendly monsters
     * check for a bad monster to hit.
     */

    mon_attack = FALSE;

    if (good_monster(*th))
    {
        hit_bad = TRUE;
        mon_attack = TRUE;
    }
    else if (on(*th, ISMEAN))
    {
        hit_bad = FALSE;
        mon_attack = TRUE;
    }

    if (mon_attack)
    {
        struct linked_list  *mon_to_hit;

	mon_to_hit = f_mons_a(th->t_pos.y, th->t_pos.x, hit_bad);

        if (mon_to_hit)
        {
            mon_mon_attack(th, mon_to_hit, pick_weap(th), NOTHROWN);
            return;
        }
    }
	
    /* no nearby monster to hit */
	
    rer = roomin(th->t_pos);            /* Find room of chaser */
    ree = roomin(th->t_chasee->t_pos);  /* Find room of chasee */

    /*
     * We don't count doors as inside rooms for this routine
     */

    if (mvwinch(stdscr, th->t_pos.y, th->t_pos.x) == DOOR)
        rer = NULL;

    this = th->t_chasee->t_pos;

    /*
     * If we are not in a corridor and not a phasing monster, then if we
     * are running after the player, we run to a door if he is not in the
     * same room. If we are fleeing, we run to a door if he IS in the
     * same room.  Note:  We don't bother with doors in mazes. Phasing 
     * monsters don't need to look for doors. There are no doors in mazes
     * and throne rooms. 
     */

    if (levtype != MAZELEV && levtype != THRONE && rer != NULL && off(*th, CANINWALL))
    {
        if (flee)
            rundoor = (rer == ree);
        else
            rundoor = (rer != ree);
    }
    else
        rundoor = FALSE;

    if (rundoor)
    {
        coord   d_exit;   /* A particular door */
        int exity, exitx;   /* Door's coordinates */

        if (th->t_doorgoal != -1)
        { /* Do we already have the goal? */
            this = rer->r_exit[th->t_doorgoal];
            dist = 0;   /* Indicate that we have our door */
        }
        else
            for (i = 0; i < rer->r_nexits; i++)
            {   /* Loop through doors */
                d_exit = rer->r_exit[i];
                exity = d_exit.y;
                exitx = d_exit.x;

                /* Avoid secret doors */
                if (mvwinch(stdscr, exity, exitx) == DOOR)
                {
                    /* Were we just on this door? */
                    if (ce(d_exit, th->t_oldpos))
                        last_door = i;
                    else
                    {
                        dist = DISTANCE(th->t_chasee->t_pos, d_exit);

                        /*
                         * If fleeing, we want to
                         * maximize distance from
                         * door to what we flee, and
                         * minimize distance from
                         * door to us.
                         */

                        if (flee)
                            dist-=DISTANCE(th->t_pos,d_exit);

                        /*
                         * Maximize distance if
                         * fleeing, otherwise
                         * minimize it
                         */

                        if ((flee && (dist > maxdist)) ||
                            (!flee && (dist < mindist)))
                        {
                            th->t_doorgoal = i; /* Use this door */
                            this = d_exit;
                            mindist = maxdist = dist;
                        }
                    }
                }
            }

        /* Could we not find a door? */
        if (dist == INT_MIN)
        {
            /* If we were on a door, go ahead and use it */
            if (last_door != -1)
            {
                th->t_doorgoal = last_door;
                this = th->t_oldpos;
                dist = 0;   /* Indicate that we found a door */
            }
        }

        /* Indicate that we do not want to flee from the door */
        if (dist != INT_MIN)
            flee = FALSE;
    }
    else
        th->t_doorgoal = -1;    /* Not going to any door */

    /*
     * this now contains what we want to run to this time so we run to
     * it.  If we hit it we either want to fight it or stop running
     */

    if (!chase(th, &this, flee))
    {
        if (ce(th->t_nxtpos, hero))
        {
            /* merchants try to sell something */

            if (on(*th, CANSELL))
            {
                sell(th);
                return;
            }
            else if (off(*th, ISFRIENDLY) && off(*th, ISCHARMED)
                    && (off(*th, CANFLY) || (on(*th, CANFLY) && rnd(2))))
                    attack(th, pick_weap(th), FALSE);
                return;
        }
        else if (on(*th, NOMOVE))
            stoprun = TRUE;
    }

    if (!curr_mons)
        return;     /* Did monster get itself killed? */

    if (on(*th, NOMOVE))
        return;

    /* If we have a scavenger, it can pick something up */

    if ((item = find_obj(th->t_nxtpos.y, th->t_nxtpos.x)) != NULL)
    {
		struct linked_list *node, *top = item;
        struct object *obt;
		
		while(top)
		{
			/* grab all objects that qualify */
			
			struct object *obj = OBJPTR(item);
			
			obt = OBJPTR(top);
			node = obt->next_obj;
			
			if (on(*th, ISSCAVENGE) ||
                ((on(*th, CANWIELD) || on(*th, CANSHOOT)) &&
                (obj->o_type == WEAPON || obj->o_type == ARMOR)) ||
                (on(*th, CANCAST) && is_magic(obj))) 
			{
                rem_obj(top, FALSE);
                attach(th->t_pack, top);
            }
			
			top = node;
		}
		
		light(&hero);
    }

    mvwaddch(cw, th->t_pos.y, th->t_pos.x, th->t_oldch);
    sch = CCHAR( mvwinch(cw, th->t_nxtpos.y, th->t_nxtpos.x) );

    /* Get old and new room of monster */
    old_room = roomin(th->t_pos);
    new_room = roomin(th->t_nxtpos);

    /* If the monster can illuminate rooms, check for a change */
    if (on(*th, HASFIRE))
    {
        /* Is monster entering a room? */
        if (old_room != new_room && new_room != NULL)
        {
            new_room->r_flags |= HASFIRE;
            new_room->r_fires++;
            if (cansee(th->t_nxtpos.y, th->t_nxtpos.x) && new_room->r_fires==1)
                light(&hero);
        }

        /* Is monster leaving a room? */
        if (old_room != new_room && old_room != NULL)
        {
            if (--(old_room->r_fires) <= 0)
            {
                old_room->r_flags &= ~HASFIRE;
                if (cansee(th->t_pos.y, th->t_pos.x))
                    light(&th->t_pos);
            }
        }
    }

    /*
     * If monster is entering player's room and player can see it, stop
     * the player's running.
     */

    if (new_room != old_room && new_room != NULL &&
        new_room == ree && cansee(th->t_nxtpos.y, th->t_nxtpos.x) &&
        (off(*th, ISINVIS) || (off(*th, ISSHADOW) || rnd(10) == 0) ||
         on(player, CANSEE)) && off(*th, CANSURPRISE))
        running = FALSE;

    if (rer != NULL && (rer->r_flags & ISDARK) &&
        !(rer->r_flags & HASFIRE) && sch == FLOOR &&
         DISTANCE(th->t_nxtpos, th->t_pos) < see_dist &&
        off(player, ISBLIND))
        th->t_oldch = ' ';
    else
        th->t_oldch = sch;

    if (cansee(th->t_nxtpos.y, th->t_nxtpos.x) &&
      off(*th, ISINWALL) &&
      ((off(*th, ISINVIS) && (off(*th, ISSHADOW) || rnd(100) < 10)) ||
      on(player, CANSEE)) &&
      off(*th, CANSURPRISE))
        mvwaddch(cw, th->t_nxtpos.y, th->t_nxtpos.x, th->t_type);

    mvwaddch(mw, th->t_pos.y, th->t_pos.x, ' ');
    mvwaddch(mw, th->t_nxtpos.y, th->t_nxtpos.x, th->t_type);

    /* Record monster's last position (if new one is different) */

    if (!ce(th->t_nxtpos, th->t_pos))
        th->t_oldpos = th->t_pos;

    th->t_pos = th->t_nxtpos; /* Mark the monster's new position */

    /* If the monster is on a trap, trap it */

    sch = CCHAR(mvinch(th->t_nxtpos.y, th->t_nxtpos.x));

    if (isatrap(sch))
    {
        debug("Monster trapped by %c.", sch);

        if (cansee(th->t_nxtpos.y, th->t_nxtpos.x))
            th->t_oldch = sch;

        be_trapped(th, th->t_nxtpos);
    }

    /* And stop running if need be */

    if (stoprun && ce(th->t_pos, th->t_chasee->t_pos))
    {
        th->t_ischasing = FALSE;
        turn_off(*th, ISRUN);
    }
}
Exemplo n.º 18
0
/*! \brief Actions for one entity
 * \date    20040310 PH added TARGET movemode, broke out chase into separate function
 *
 * Process an individual active entity.  If the entity in question
 * is #0 (main character) and the party is not automated, then allow
 * for player input.
 *
 * \param   target_entity Index of entity
 * \date    20040310 PH added TARGET movemode, broke out chase into separate function
 */
static void process_entity(t_entity target_entity)
{
    s_entity *ent = &g_ent[target_entity];
    s_player *player = 0;

    ent->scount = 0;

    if (!ent->active)
    {
        return;
    }

    if (!ent->moving)
    {
        if (target_entity == 0 && !autoparty)
        {
            player_move();
            if (ent->moving && display_desc == 1)
            {
                display_desc = 0;
            }
            return;
        }
        switch (ent->movemode)
        {
            case MM_STAND:
                return;
            case MM_WANDER:
                wander(target_entity);
                break;
            case MM_SCRIPT:
                entscript(target_entity);
                break;
            case MM_CHASE:
                chase(target_entity);
                break;
            case MM_TARGET:
                target(target_entity);
                break;
        }
    }
    else                         /* if (.moving==0) */
    {
        if (ent->tilex * TILE_W > ent->x)
        {
            ++ent->x;
        }
        if (ent->tilex * TILE_W < ent->x)
        {
            --ent->x;
        }
        if (ent->tiley * TILE_H > ent->y)
        {
            ++ent->y;
        }
        if (ent->tiley * TILE_H < ent->y)
        {
            --ent->y;
        }
        ent->movcnt--;

        if (ent->framectr < 20)
        {
            ent->framectr++;
        }
        else
        {
            ent->framectr = 0;
        }

        if (ent->movcnt == 0)
        {
            ent->moving = 0;
            if (target_entity < PSIZE)
            {
                player = &party[pidx[target_entity]];
                if (steps < STEPS_NEEDED)
                {
                    steps++;
                }
                if (player->sts[S_POISON] > 0)
                {
                    if (player->hp > 1)
                    {
                        player->hp--;
                    }
                    play_effect(21, 128);
                }
                if (player->eqp[EQP_SPECIAL] == I_REGENERATOR)
                {
                    if (player->hp < player->mhp)
                    {
                        player->hp++;
                    }
                }
            }
            if (target_entity == 0)
            {
                zone_check();
            }
        }

        if (target_entity == 0 && vfollow == 1)
        {
            calc_viewport(0);
        }
    }
}
Exemplo n.º 19
0
/*
 * do_chase:
 *	Make one thing chase another.
 */
int
do_chase(THING *th)
{
    coord *cp;
    struct room *rer, *ree;	/* room of chaser, room of chasee */
    int mindist = 32767, curdist;
    int stoprun = FALSE;	/* TRUE means we are there */
    int door;
    THING *obj;
    coord this;			/* Temporary destination for chaser */

    rer = th->t_room;		/* Find room of chaser */
    if (on(*th, ISGREED) && rer->r_goldval == 0)
	th->t_dest = &hero;	/* If gold has been taken, run after hero */
    if (th->t_dest == &hero)	/* Find room of chasee */
	ree = proom;
    else
	ree = roomin(th->t_dest);
    /*
     * We don't count doors as inside rooms for this routine
     */
    door = (chat(th->t_pos.y, th->t_pos.x) == DOOR);
    /*
     * If the object of our desire is in a different room,
     * and we are not in a corridor, run to the door nearest to
     * our goal.
     */
over:
    if (rer != ree)
    {
	for (cp = rer->r_exit; cp < &rer->r_exit[rer->r_nexits]; cp++)
	{
	    curdist = dist_cp(th->t_dest, cp);
	    if (curdist < mindist)
	    {
		this = *cp;
		mindist = curdist;
	    }
	}
	if (door)
	{
	    rer = &passages[flat(th->t_pos.y, th->t_pos.x) & F_PNUM];
	    door = FALSE;
	    goto over;
	}
    }
    else
    {
	this = *th->t_dest;
	/*
	 * For dragons check and see if (a) the hero is on a straight
	 * line from it, and (b) that it is within shooting distance,
	 * but outside of striking range.
	 */
	if (th->t_type == 'D' && (th->t_pos.y == hero.y || th->t_pos.x == hero.x
	    || abs(th->t_pos.y - hero.y) == abs(th->t_pos.x - hero.x))
	    && dist_cp(&th->t_pos, &hero) <= BOLT_LENGTH * BOLT_LENGTH
	    && !on(*th, ISCANC) && rnd(DRAGONSHOT) == 0)
	{
	    delta.y = sign(hero.y - th->t_pos.y);
	    delta.x = sign(hero.x - th->t_pos.x);
	    if (has_hit)
		endmsg();
	    fire_bolt(&th->t_pos, &delta, "flame");
	    running = FALSE;
	    count = 0;
	    quiet = 0;
	    if (to_death && !on(*th, ISTARGET))
	    {
		to_death = FALSE;
		kamikaze = FALSE;
	    }
	    return(0);
	}
    }
    /*
     * This now contains what we want to run to this time
     * so we run to it.  If we hit it we either want to fight it
     * or stop running
     */
    if (!chase(th, &this))
    {
	if (ce(this, hero))
	{
	    return( attack(th) );
	}
	else if (ce(this, *th->t_dest))
	{
	    for (obj = lvl_obj; obj != NULL; obj = next(obj))
		if (th->t_dest == &obj->o_pos)
		{
		    detach(lvl_obj, obj);
		    attach(th->t_pack, obj);
		    chat(obj->o_pos.y, obj->o_pos.x) =
			(th->t_room->r_flags & ISGONE) ? PASSAGE : FLOOR;
		    th->t_dest = find_dest(th);
		    break;
		}
	    if (th->t_type != 'F')
		stoprun = TRUE;
	}
    }
    else
    {
	if (th->t_type == 'F')
	    return(0);
    }
    relocate(th, &ch_ret);
    /*
     * And stop running if need be
     */
    if (stoprun && ce(th->t_pos, *(th->t_dest)))
	th->t_flags &= ~ISRUN;
    return(0);
}
Exemplo n.º 20
0
int
main(int argc, char *argv[])
{
	struct	sigaction sa;
	int	ch, i;

	if (pledge("stdio rpath wpath cpath tty", NULL) == -1)
		err(1, "pledge");

#ifdef LOGGING
	const char	*home;

	home = getenv("HOME");
	if (home == NULL || *home == '\0')
		err(1, "getenv");

	snprintf(logpath, sizeof(logpath), "%s/%s", home, ".snake.log");
	logfile = fopen(logpath, "a");
#endif

	while ((ch = getopt(argc, argv, "hl:stw:")) != -1)
		switch ((char)ch) {
		case 'w':	/* width */
			ccnt = strtonum(optarg, 1, INT_MAX, NULL);
			break;
		case 'l':	/* length */
			lcnt = strtonum(optarg, 1, INT_MAX, NULL);
			break;
		case 's': /* score */
			if (readscores(0))
				snscore(0);
			else
				printf("no scores so far\n");
			return 0;
			break;
		case 't': /* slow terminal */
			fast = 0;
			break;
		case 'h':
		default:
			fprintf(stderr, "usage: %s [-st] [-l length] "
			    "[-w width]\n", getprogname());
			return 1;
		}

	readscores(1);
	penalty = loot = 0;
	initscr();
#ifdef KEY_LEFT
	keypad(stdscr, TRUE);
#endif
	nonl();
	cbreak();
	noecho();

	if (!lcnt || lcnt > LINES - 2)
		lcnt = LINES - 2;
	if (!ccnt || ccnt > COLS - 3)
		ccnt = COLS - 3;

	i = lcnt < ccnt ? lcnt : ccnt;
	if (i < 4) {
		endwin();
		errx(1, "screen too small for a fair game.");
	}
	/*
	 * chunk is the amount of money the user gets for each $.
	 * The formula below tries to be fair for various screen sizes.
	 * We only pay attention to the smaller of the 2 edges, since
	 * that seems to be the bottleneck.
	 * This formula is a hyperbola which includes the following points:
	 *	(24, $25)	(original scoring algorithm)
	 *	(12, $40)	(experimentally derived by the "feel")
	 *	(48, $15)	(a guess)
	 * This will give a 4x4 screen $99/shot.  We don't allow anything
	 * smaller than 4x4 because there is a 3x3 game where you can win
	 * an infinite amount of money.
	 */
	if (i < 12)
		i = 12;	/* otherwise it isn't fair */
	/*
	 * Compensate for border.  This really changes the game since
	 * the screen is two squares smaller but we want the default
	 * to be $25, and the high scores on small screens were a bit
	 * much anyway.
	 */
	i += 2;
	chunk = (675.0 / (i + 6)) + 2.5;	/* min screen edge */

	memset(&sa, 0, sizeof sa);
	sigemptyset(&sa.sa_mask);
	sa.sa_handler = stop;
	sigaction(SIGINT, &sa, NULL);

	snrand(&finish);
	snrand(&you);
	snrand(&money);
	snrand(&snake[0]);

	for (i = 1; i < 6; i++)
		chase(&snake[i], &snake[i - 1]);
	setup();
	mainloop();
	return 0;
}
Exemplo n.º 21
0
int
do_chase(struct thing *th)
{
    struct room *rer, *ree;	/* room of chaser, room of chasee */
    int mindist = 32767, i, dist;
    int stoprun = FALSE;	/* TRUE means we are there */
    int sch;
    coord this;				/* Temporary destination for chaser */

    rer = roomin(&th->t_pos);	/* Find room of chaser */
    ree = roomin(th->t_dest);	/* Find room of chasee */
    /*
     * We don't count doors as inside rooms for this routine
     */
    if (CMVWINCH(stdscr, th->t_pos.y, th->t_pos.x) == DOOR)
	rer = NULL;
    this = *th->t_dest;
    /*
     * If the object of our desire is in a different room, 
     * than we are and we ar not in a corridor, run to the
     * door nearest to our goal.
     */
    if (rer != NULL && rer != ree)
	for (i = 0; i < rer->r_nexits; i++)	/* loop through doors */
	{
	    dist = DISTANCE(th->t_dest->y, th->t_dest->x,
			    rer->r_exit[i].y, rer->r_exit[i].x);
	    if (dist < mindist)			/* minimize distance */
	    {
		this = rer->r_exit[i];
		mindist = dist;
	    }
	}
    /*
     * this now contains what we want to run to this time
     * so we run to it.  If we hit it we either want to fight it
     * or stop running
     */
    if (!chase(th, &this))
    {
	if (ce(this, hero))
	{
	    return( attack(th) );
	}
	else if (th->t_type != 'F')
	    stoprun = TRUE;
    }
    else if (th->t_type == 'F')
	return(0);
    mvwaddrawch(cw, th->t_pos.y, th->t_pos.x, th->t_oldch);
    sch = CMVWINCH(cw, ch_ret.y, ch_ret.x);
    if (rer != NULL && (rer->r_flags & ISDARK) && sch == FLOOR
	&& DISTANCE(ch_ret.y, ch_ret.x, th->t_pos.y, th->t_pos.x) < 3
	&& off(player, ISBLIND))
	    th->t_oldch = ' ';
    else
	th->t_oldch = sch;

    if (cansee(unc(ch_ret)) && !on(*th, ISINVIS))
        mvwaddrawch(cw, ch_ret.y, ch_ret.x, th->t_type);
    mvwaddrawch(mw, th->t_pos.y, th->t_pos.x, ' ');
    mvwaddrawch(mw, ch_ret.y, ch_ret.x, th->t_type);
    th->t_pos = ch_ret;
    /*
     * And stop running if need be
     */
    if (stoprun && ce(th->t_pos, *(th->t_dest)))
	th->t_flags &= ~ISRUN;

    return(0);
}
Exemplo n.º 22
0
/*
 * do_chase:
 *	Make one thing chase another.
 */
void
do_chase(struct thing *th, int flee)
{
    register struct room *rer, *ree,	/* room of chaser, room of chasee */
			*old_room,	/* old room of monster */
			*new_room;	/* new room of monster */
    register int mindist = MAXINT, maxdist = MININT, dist = MININT, i,
		 last_door = -1;	/* Door we just came from */
    register int stoprun = FALSE,	/* TRUE means we are there */
		  rundoor;		/* TRUE means run to a door */
	int mdead = 0;
    register int sch;
    coord this;				/* Temporary destination for chaser */

    /* Make sure the monster can move */
    if (th->t_no_move != 0) {
	th->t_no_move--;
	return;
    }

    rer = roomin(&th->t_pos);	/* Find room of chaser */
    ree = roomin(th->t_dest);	/* Find room of chasee */

    /*
     * We don't count doors as inside rooms for this routine
     */
    if (mvwinch(stdscr, th->t_pos.y, th->t_pos.x) == DOOR)
	rer = NULL;
    this = *th->t_dest;

    /*
     * If we are not in a corridor and not a Xorn, then if we are running
     * after the player, we run to a door if he is not in the same room.
     * If we are fleeing, we run to a door if he IS in the same room.
     * Note:  We don't bother with doors in mazes.
     */
    if (levtype != MAZELEV && rer != NULL && off(*th, CANINWALL)) {
	if (flee) rundoor = (rer == ree);
	else rundoor = (rer != ree);
    }
    else rundoor = FALSE;

    if (rundoor) {
	coord exit;	/* A particular door */
	int exity, exitx;	/* Door's coordinates */

	if (th->t_doorgoal != -1) {	/* Do we already have the goal? */
	    this = rer->r_exit[th->t_doorgoal];
	    dist = 0;	/* Indicate that we have our door */
	}

	else for (i = 0; i < rer->r_nexits; i++) {	/* Loop through doors */
	    exit = rer->r_exit[i];
	    exity = exit.y;
	    exitx = exit.x;

	    /* Avoid secret doors */
	    if (mvwinch(stdscr, exity, exitx) == DOOR) {
		/* Were we just on this door? */
		if (ce(exit, th->t_oldpos)) last_door = i;

		else {
		    dist = DISTANCE(th->t_dest->y, th->t_dest->x, exity, exitx);

		    /* If fleeing, we want to maximize distance from door to
		     * what we flee, and minimize distance from door to us.
		     */
		    if (flee)
		       dist -= DISTANCE(th->t_pos.y, th->t_pos.x, exity, exitx);

		    /* Maximize distance if fleeing, otherwise minimize it */
		    if ((flee && (dist > maxdist)) ||
			(!flee && (dist < mindist))) {
			th->t_doorgoal = i;	/* Use this door */
			this = exit;
			mindist = maxdist = dist;
		    }
		}
	    }
	}

	/* Could we not find a door? */
	if (dist == MININT) {
	    /* If we were on a door, go ahead and use it */
	    if (last_door != -1) {
		th->t_doorgoal = last_door;
		this = th->t_oldpos;
		dist = 0;	/* Indicate that we found a door */
	    }
	}

	/* Indicate that we do not want to flee from the door */
	if (dist != MININT) flee = FALSE;
    }

    else th->t_doorgoal = -1;	/* Not going to any door */
    /*
     * this now contains what we want to run to this time
     * so we run to it.  If we hit it we either want to fight it
     * or stop running
     */
    if (!chase(th, &this, flee, &mdead)) {
	if (ce(ch_ret, hero)) {
	    /* merchants try to sell something */
	    if (on(*th, CANSELL)) 
		sell(th);
	    else if (on(*th, ISCHARMED))
		{}				/* future enhancements */
	    else if (on(*th, ISFRIENDLY))
		{}
	    else
		attack(th, NULL, FALSE);
	    return;
	}
	else if (on(*th, NOMOVE))
	    stoprun = TRUE;
    }

    if (on(*th, ISDEAD))
		return;	/* Did monster get itself killed? */

    if (on(*th, NOMOVE)) 
	return;

    /* If we have a scavenger, it can pick something up */
    if (on(*th, ISSCAVENGE)) {
	register struct linked_list *item;

	if ((item = find_obj(ch_ret.y, ch_ret.x)) != NULL) {
	    register int floor = (roomin(&ch_ret) == NULL) ? PASSAGE : FLOOR;

	    detach(lvl_obj, item);
	    mvaddch(ch_ret.y, ch_ret.x, floor);
	    mvwaddch(cw, ch_ret.y, ch_ret.x, floor);
	    attach(th->t_pack, item);
	}
    }

    mvwaddch(cw, th->t_pos.y, th->t_pos.x, th->t_oldch);
    sch = CCHAR( mvwinch(cw, ch_ret.y, ch_ret.x) );

    /* Get old and new room of monster */
    old_room=roomin(&th->t_pos);
    new_room=roomin(&ch_ret);

    /* If the monster can illuminate rooms, check for a change */
    if (on(*th, HASFIRE)) {
	/* Is monster entering a room? */
	if (old_room != new_room && new_room != NULL) {
	    new_room->r_flags |= HASFIRE;
	    new_room->r_fires++;
	    if (cansee(ch_ret.y, ch_ret.x) && new_room->r_fires == 1)
		light(&hero);
	}

	/* Is monster leaving a room? */
	if (old_room != new_room && old_room != NULL) {
	    if (--(old_room->r_fires) <= 0) {
		old_room->r_flags &= ~HASFIRE;
		if (cansee(th->t_pos.y, th->t_pos.x)) light(&th->t_pos);
	    }
	}
    }

    /* If monster is entering player's room and player can see it,
     * stop the player's running.
     */
    if (new_room != old_room && new_room != NULL &&
	new_room == ree && cansee(unc(ch_ret)) &&
	(off(*th, ISINVIS) || (off(*th, ISSHADOW) || rnd(10) == 0) ||
	on(player, CANSEE)) && off(*th, CANSURPRISE))
		running = FALSE;

    if (rer != NULL && (rer->r_flags & ISDARK) && 
	!(rer->r_flags & HASFIRE) && sch == FLOOR &&
	DISTANCE(ch_ret.y, ch_ret.x, th->t_pos.y, th->t_pos.x) < see_dist &&
	off(player, ISBLIND))
	    th->t_oldch = ' ';
    else
	th->t_oldch = sch;

    if (cansee(unc(ch_ret)) &&
	off(*th, ISINWALL) &&
	((off(*th, ISINVIS) && (off(*th, ISSHADOW) || rnd(100) < 10)) ||
	 on(player, CANSEE)) &&
	off(*th, CANSURPRISE))
        mvwaddch(cw, ch_ret.y, ch_ret.x, th->t_type);
    mvwaddch(mw, th->t_pos.y, th->t_pos.x, ' ');
    mvwaddch(mw, ch_ret.y, ch_ret.x, th->t_type);

    /* Record monster's last position (if new one is different) */
    if (!ce(ch_ret, th->t_pos)) th->t_oldpos = th->t_pos;
    th->t_pos = ch_ret;		/* Mark the monster's new position */

    /* If the monster is on a trap, trap it */
    sch = CCHAR( mvinch(ch_ret.y, ch_ret.x) );
    if (isatrap(sch)) {
	debug("Monster trapped by %c.", sch);
	if (cansee(ch_ret.y, ch_ret.x)) th->t_oldch = sch;
	be_trapped(th, &ch_ret);
    }


    /*
     * And stop running if need be
     */
    if (stoprun && ce(th->t_pos, *(th->t_dest)))
	turn_off(*th, ISRUN);
}