Beispiel #1
0
void do_sell( CHAR_DATA *ch, char *argument )
{
    char buf[MAX_STRING_LENGTH];
    char arg[MAX_INPUT_LENGTH];
    CHAR_DATA *keeper;
    OBJ_DATA *obj;
    int cost;

    one_argument( argument, arg );

    if ( arg[0] == '\0' )
    {
	send_to_char( "Sell what?\n\r", ch );
	return;
    }

    if ( ( keeper = find_keeper( ch ) ) == NULL )
	return;

    if ( ( obj = get_obj_carry( ch, arg ) ) == NULL )
    {
	act( AT_TELL, "$n tells you 'You don't have that item.'", keeper, NULL, ch, TO_VICT );
	ch->reply = keeper;
	return;
    }
    /* Bug report and solution thanks to [email protected] */
    if ( !can_see_obj( keeper, obj) ) 
    {
        send_to_char("What are you trying to sell me? I don't buy thin air!\n\r", ch );
        return;
    }


    if ( !can_drop_obj( ch, obj ) )
    {
	send_to_char( "You can't let go of it!\n\r", ch );
	return;
    }

    if ( obj->timer > 0 )
    {
	act( AT_TELL, "$n tells you, '$p is depreciating in value too quickly...'", keeper, obj, ch, TO_VICT );
	return;
    }

    if ( ( cost = get_cost( ch, keeper, obj, FALSE ) ) <= 0 )
    {
	act( AT_ACTION, "$n looks uninterested in $p.", keeper, obj, ch, TO_VICT );
	return;
    }

    if ( cost > keeper->gold )
    {
	act( AT_TELL, "$n makes a credit transaction.", keeper, obj, ch, TO_VICT );
        lower_economy( ch->in_room->area, cost-keeper->gold );
    }
    
    separate_obj( obj );
    act( AT_ACTION, "$n sells $p.", ch, obj, NULL, TO_ROOM );
    sprintf( buf, "You sell $p for %d credit%s.",
	cost, cost == 1 ? "" : "s" );
    act( AT_ACTION, buf, ch, obj, NULL, TO_CHAR );
    ch->gold     += cost;
    keeper->gold -= cost;
    if ( keeper->gold < 0 )
	keeper->gold = 0;

    if ( obj->item_type == ITEM_TRASH )
	extract_obj( obj );
    else  if ( IS_SET( obj->extra_flags , ITEM_CONTRABAND) )
   {
       long ch_exp;
       
       ch_exp = UMIN( obj->cost*10 , ( exp_level( ch->skill_level[SMUGGLING_ABILITY]+1) - exp_level( ch->skill_level[SMUGGLING_ABILITY])  ) / 10  );
       ch_printf( ch, "You receive %ld smuggling experience for unloading your contraband.\n\r " , ch_exp );
       gain_exp( ch, ch_exp , SMUGGLING_ABILITY );
       if ( obj->item_type == ITEM_SPICE || obj->item_type == ITEM_RAWSPICE )
	 extract_obj( obj );
       else
       {
         REMOVE_BIT( obj->extra_flags , ITEM_CONTRABAND );
         obj_from_char( obj );
         obj_to_char( obj, keeper );
       }
   }
    else if ( obj->item_type == ITEM_SPICE || obj->item_type == ITEM_RAWSPICE )
	extract_obj( obj );
    else
    {
	obj_from_char( obj );
	obj_to_char( obj, keeper );
    }

    return;
}
Beispiel #2
0
void do_buy( CHAR_DATA *ch, char *argument )
{
    char arg[MAX_INPUT_LENGTH];
    int maxgold;
    bool debit;
    OBJ_DATA *obj;    

    argument = one_argument( argument, arg );

    if ( arg[0] == '\0' )
    {
	send_to_char( "Buy what?\n\r", ch );
	return;
    }

    if ( IS_SET(ch->in_room->room_flags, ROOM_PET_SHOP) )
    {
	char buf[MAX_STRING_LENGTH];
	CHAR_DATA *pet;
	ROOM_INDEX_DATA *pRoomIndexNext;
	ROOM_INDEX_DATA *in_room;

   if ( argument[0] == '\0' )
      debit = FALSE;
   else if ( !str_cmp( "atm", argument ) || !str_cmp( "debit", argument ) )
   {
      bool has_card = FALSE;
      
      for ( obj = ch->last_carrying; obj; obj = obj->prev_content )        
      {
          if ( obj->item_type == ITEM_DEBIT_CARD )
            has_card = TRUE;
      }   
      
     if ( has_card == TRUE )
      debit = TRUE;
     else
     {
       send_to_char( "You don't even have your card with you!\n\r", ch );
       return;    
     }    
    }

	if ( IS_NPC(ch) )
	    return;

	pRoomIndexNext = get_room_index( ch->in_room->vnum + 1 );
	if ( !pRoomIndexNext )
	{
	    bug( "Do_buy: bad pet shop at vnum %d.", ch->in_room->vnum );
	    send_to_char( "Sorry, you can't buy that here.\n\r", ch );
	    return;
	}

	in_room     = ch->in_room;
	ch->in_room = pRoomIndexNext;
	pet         = get_char_room( ch, arg );
	ch->in_room = in_room;

	if ( pet == NULL || !IS_NPC( pet ) || !IS_SET(pet->act, ACT_PET) )
	{
	    send_to_char( "Sorry, you can't buy that here.\n\r", ch );
	    return;
	}

	if (( ch->gold < 10 * pet->top_level * pet->top_level ) && debit == FALSE)
	{
	    send_to_char( "You can't afford it.\n\r", ch );
	    return;
	}
	else if ( (ch->pcdata->bank < 10 * pet->top_level * pet->top_level) && debit == TRUE )
	{
	  send_to_char( "You dont have enough money in your bank account for it.\n\r", ch );
          return;    
        } 

	maxgold = 10 * pet->top_level * pet->top_level;
        if ( debit == FALSE )
	  ch->gold	-= maxgold; /* this was already here, btw */
	else
	  ch->pcdata->bank  -= maxgold;

	boost_economy( ch->in_room->area, maxgold );
	pet		= create_mobile( pet->pIndexData );
	SET_BIT(pet->act, ACT_PET);
	SET_BIT(pet->affected_by, AFF_CHARM);

	argument = one_argument( argument, arg );
	if ( arg[0] != '\0' )
	{
	    sprintf( buf, "%s %s", pet->name, arg );
	    STRFREE( pet->name );
	    pet->name = STRALLOC( buf );
	}

	sprintf( buf, "%sA neck tag says 'I belong to %s'.\n\r",
	    pet->description, ch->name );
	STRFREE( pet->description );
	pet->description = STRALLOC( buf );

	char_to_room( pet, ch->in_room );
	add_follower( pet, ch );
	send_to_char( "Enjoy your pet.\n\r", ch );
    	act( AT_ACTION, "$n bought $N as a pet.", ch, NULL, pet, TO_ROOM );
	return;
    }
    else
    {
	CHAR_DATA *keeper;
	int cost;
	int noi = 1;		/* Number of items */
	sh_int mnoi = 20;	/* Max number of items to be bought at once */

	if ( ( keeper = find_keeper( ch ) ) == NULL )
	    return;

	maxgold = keeper->top_level * 10;

	if ( is_number( arg ) )
	{
	    noi = atoi( arg );
	    argument = one_argument( argument, arg );
	    if ( noi > mnoi )
	    {
		act( AT_TELL, "$n tells you 'I don't sell that many items at"
		  " once.'", keeper, NULL, ch, TO_VICT );
		ch->reply = keeper;
		return;
	    }
	}

    if ( argument[0] == '\0' )
      debit = FALSE;
    else if ( !str_cmp( "atm", argument ) || !str_cmp( "debit", argument ) )
    {
      bool has_card = FALSE;
      
      for ( obj = ch->last_carrying; obj; obj = obj->prev_content )        
      {
          if ( obj->item_type == ITEM_DEBIT_CARD )
            has_card = TRUE;
      }   
      
      if ( has_card == TRUE )
       debit = TRUE;
      else
      {
        send_to_char( "You don't even have your card with you!\n\r", ch );
        return;    
      }    
     }  

	obj  = get_obj_carry( keeper, arg );
	
	if ( !obj && arg[0] == '#' )
        {     
              int onum, oref;
              bool ofound = FALSE;
              
              onum =0;
              oref = atoi(arg+1);
              for ( obj = keeper->last_carrying; obj; obj = obj->prev_content )
	      { 
	        if ( obj->wear_loc == WEAR_NONE
	        &&   can_see_obj( ch, obj ) )
	            onum++;
                if ( onum == oref ) 
                {
                    ofound = TRUE;
                    break;
                }
                else if ( onum > oref )
                   break;
	      }
	      if (!ofound)
	         obj = NULL;
        }
	if (keeper->home != NULL && obj->cost > 0)
          cost= obj->cost;
	cost = ( get_cost( ch, keeper, obj, TRUE ) * noi );

	if( !IS_NPC(ch) && ch->pcdata->learned[gsn_bargain] > 0 && ch->pcdata->learned[gsn_bargain] > number_percent())
	 {
	   ch_printf(ch,"You are able to bargain from %d credits to %d credits!\n\r", cost, (cost/3)+(cost/2));
	   cost = (cost/3) + (cost/2);
	   if(number_percent() > 50)
	    learn_from_success(ch, gsn_bargain);
	 }

	if ( cost <= 0 || !can_see_obj( ch, obj ) )
	{
	    act( AT_TELL, "$n tells you 'I don't sell that -- try 'list'.'",
		keeper, NULL, ch, TO_VICT );
	    ch->reply = keeper;
	    return;
	}

	if ( !IS_OBJ_STAT( obj, ITEM_INVENTORY ) && ( noi > 1 ) )
	{
	    interpret( keeper, "laugh" );
	    act( AT_TELL, "$n tells you 'I don't have enough of those in stock"
	     " to sell more than one at a time.'", keeper, NULL, ch, TO_VICT );
	    ch->reply = keeper;
	    return;
	}
	
	if ( ch->gold < cost && debit == FALSE)
	{
	    act( AT_TELL, "$n tells you 'You can't afford to buy $p.'",
		keeper, obj, ch, TO_VICT );
	    ch->reply = keeper;
	    return;
	}
	
        if ( ch->pcdata->bank < cost && debit == TRUE)
	{
	    send_to_char( "You are almost slide your card through, but you remember you don't have enough money!\n\r", ch );
	    return;	    
        }  

	if ( IS_SET(obj->extra_flags, ITEM_PROTOTYPE) 
             && get_trust( ch ) < LEVEL_IMMORTAL )
	{
	    act( AT_TELL, "$n tells you 'This is a only a prototype!  I can't sell you that...'", 
		keeper, NULL, ch, TO_VICT );
      	    ch->reply = keeper;
	    return;
	}

	if ( ch->carry_number + get_obj_number( obj ) > can_carry_n( ch ) )
	{
	    send_to_char( "You can't carry that many items.\n\r", ch );
	    return;
	}

	if ( ch->carry_weight + ( get_obj_weight( obj ) * noi )
		+ (noi > 1 ? 2 : 0) > can_carry_w( ch ) )
	{
	    send_to_char( "You can't carry that much weight.\n\r", ch );
	    return;
	}

	if ( noi == 1 )
	{
	    if ( !IS_OBJ_STAT( obj, ITEM_INVENTORY ) )  
	       separate_obj( obj );
	    act( AT_ACTION, "$n buys $p.", ch, obj, NULL, TO_ROOM );
    	    act( AT_ACTION, "You buy $p.", ch, obj, NULL, TO_CHAR );
	}
        else
	{
	    sprintf( arg, "$n buys %d $p%s.", noi,
		( obj->short_descr[strlen(obj->short_descr)-1] == 's'
		? "" : "s" ) );
	    act( AT_ACTION, arg, ch, obj, NULL, TO_ROOM );
	    sprintf( arg, "You buy %d $p%s.", noi,
		( obj->short_descr[strlen(obj->short_descr)-1] == 's'
		? "" : "s" ) );
	    act( AT_ACTION, arg, ch, obj, NULL, TO_CHAR );
	    act( AT_ACTION, "$N puts them into a bag and hands it to you.",
		ch, NULL, keeper, TO_CHAR );
	}

        if ( debit == FALSE )
	  ch->gold     -= cost; /* this line was already here, btw */
        else if ( debit == TRUE )
          ch->pcdata->bank     -= cost;
	keeper->gold += cost;

	if ( keeper->gold > maxgold )
	{
	    boost_economy( keeper->in_room->area, keeper->gold - maxgold/2 );
	    keeper->gold = maxgold/2;
	    act( AT_ACTION, "$n puts some credits into a large safe.", keeper, NULL, NULL, TO_ROOM );
	}

	if ( IS_OBJ_STAT( obj, ITEM_INVENTORY ) )
	{
	    OBJ_DATA *buy_obj, *bag;

	    buy_obj = create_object( obj->pIndexData, obj->level );

	    /*
	     * Due to grouped objects and carry limitations in SMAUG
	     * The shopkeeper gives you a bag with multiple-buy,
	     * and also, only one object needs be created with a count
	     * set to the number bought.		-Thoric
	     */
	    if ( noi > 1 )
	    {
		bag = create_object( get_obj_index( OBJ_VNUM_SHOPPING_BAG ), 1 );
		/* perfect size bag ;) */
		bag->value[0] = bag->weight + (buy_obj->weight * noi);
		buy_obj->count = noi;
		obj->pIndexData->count += (noi - 1);
		numobjsloaded += (noi - 1);
		obj_to_obj( buy_obj, bag );
		obj_to_char( bag, ch );
	    }
	    else
		obj_to_char( buy_obj, ch );
	}
        else
	{
	    obj_from_char( obj );
	    obj_to_char( obj, ch );
	}

	return;
    }
}
Beispiel #3
0
void do_list( CHAR_DATA *ch, char *argument )
{
    if ( IS_SET(ch->in_room->room_flags, ROOM_PET_SHOP) )
    {
	ROOM_INDEX_DATA *pRoomIndexNext;
	CHAR_DATA *pet;
	bool found;

	pRoomIndexNext = get_room_index( ch->in_room->vnum + 1 );
	if ( !pRoomIndexNext )
	{
	    bug( "Do_list: bad pet shop at vnum %d.", ch->in_room->vnum );
	    send_to_char( "You can't do that here.\n\r", ch );
	    return;
	}

	found = FALSE;
	for ( pet = pRoomIndexNext->first_person; pet; pet = pet->next_in_room )
	{
	    if ( IS_SET(pet->act, ACT_PET) && IS_NPC(pet) )
	    {
		if ( !found )
		{
		    found = TRUE;
		    send_to_char( "Pets for sale:\n\r", ch );
		}
		ch_printf( ch, "[%2d] %8d - %s\n\r",
			pet->top_level,
			10 * pet->top_level * pet->top_level,
			pet->short_descr );
	    }
	}
	if ( !found )
	    send_to_char( "Sorry, we're out of pets right now.\n\r", ch );
	return;
    }
    else
    {
	char arg[MAX_INPUT_LENGTH];
	CHAR_DATA *keeper;
	OBJ_DATA *obj;
	int cost;
	int oref = 0;
	bool found;

	one_argument( argument, arg );

	if ( ( keeper = find_keeper( ch ) ) == NULL )
	    return;

	found = FALSE;
	for ( obj = keeper->last_carrying; obj; obj = obj->prev_content )
	{
	    if ( obj->wear_loc == WEAR_NONE
	    &&   can_see_obj( ch, obj ) )
	    {
	       oref++;
	       if ( ( cost = get_cost( ch, keeper, obj, TRUE ) ) > 0
	       && ( arg[0] == '\0' || nifty_is_name( arg, obj->name ) ) )
	       {
	       	if (keeper->home != NULL)
		  cost = obj->cost;
		if ( !found )
		{
		    found = TRUE;
		    ch_printf( ch, "%s[Price] {ref} Item\n\r", color_str( AT_LIST, ch) );
		}
		ch_printf( ch, "%s[%5d] {%3d} %s%s%s.\n\r",
		    color_str(AT_LIST, ch), cost, oref, capitalize( obj->short_descr ), color_str(AT_LIST, ch),
		    IS_SET(obj->extra_flags, ITEM_HUTT_SIZE) ? " (hutt size)" :
		    ( IS_SET(obj->extra_flags, ITEM_LARGE_SIZE) ? " (large)" :
		    ( IS_SET(obj->extra_flags, ITEM_HUMAN_SIZE) ? " (medium)" :
		    ( IS_SET(obj->extra_flags, ITEM_SMALL_SIZE) ? " (small)" :
		    "" ) ) ) );
	       }
	    }
	}

	if ( !found )
	{
	    if ( arg[0] == '\0' )
		send_to_char( "You can't buy anything here.\n\r", ch );
	    else
		send_to_char( "You can't buy that here.\n\r", ch );
	}
	return;
    }
}
      void solve_bipartite_matching()
      {
         for(size_t max_match=0; max_match<nel; ++max_match)
         {
            size_t x, y, root=MINUS_ONE;                           //just counters and root vertex
            std::vector<size_t> q(nel);
            size_t wr = 0, rd = 0;                                 //q - queue for bfs, wr,rd - write and read
            //pos in queue
            S.assign(nel, false);                             //init set S
            T.assign(nel, false);                             //init set T
            prev.assign(nel, MINUS_ONE);                      //init set prev - for the alternating tree
            for (x = 0; x < nel; x++)                         //finding root of the tree
               if (xy[x] == MINUS_ONE)
               {
                  q[wr++] = root = x;
                  prev[x] = MINUS_TWO;
                  S[x] = true;
                  break;
               }

            for (y = 0; y < nel; y++)                          //initializing slack array
            {
               //std::cerr << "root " << root << " y " << y << std::endl;
               slack[y] = lx[root] + ly[y] - get_cost(root,y);
               slackx[y] = root;
            }
            //second part of augment() function
            bool found= false;
            while (!found)                                          //main cycle
            {
               while (rd < wr && !found)                            //building tree with bfs cycle
               {
                  x = q[rd++];                                      //current vertex from X part
                  for (y = 0; y < nel && !found;)              //iterate through all edges in equality graph
                  {
                     if (get_cost(x,y) == lx[x] + ly[y] &&  !T[y])
                     {
                        if (yx[y] == MINUS_ONE)
                        {
                           found= true;               //an exposed vertex in Y found, so
                        }
                        //augmenting path exists!
                        else
                        {
                           T[y] = true;                                //else just add y to T,
                           q[wr++] = yx[y];                            //add vertex yx[y], which is matched
                           //with y, to the queue
                           add_to_tree(yx[y], x);                      //add edges (x,y) and (y,yx[y]) to the tree
                           ++y;
                        }
                     }
                     else
                        ++y;
                  }
               }
               if (!found)
               {

                  update_labels();                                     //augmenting path not found, so improve labeling
                  wr = rd = 0;
                  for (y = 0; y < nel && !found;)
                  {
                     //in this cycle we add edges that were added to the equality graph as a
                     //result of improving the labeling, we add edge (slackx[y], y) to the tree if
                     //and only if !T[y] &&  slack[y] == 0, also with this edge we add another one
                     //(y, yx[y]) or augment the matching, if y was exposed
                     if (!T[y] &&  slack[y] == 0)
                     {
                        if (yx[y] == MINUS_ONE)                               //exposed vertex in Y found - augmenting path exists!
                        {
                           x = slackx[y];
                           found = true;
                        }
                        else
                        {
                           T[y] = true;                                //else just add y to T,
                           if (!S[yx[y]])
                           {
                              q[wr++] = yx[y];                         //add vertex yx[y], which is matched with
                              //y, to the queue
                              add_to_tree(yx[y], slackx[y]);           //and add edges (x,y) and (y,
                              //yx[y]) to the tree
                           }
                           ++y;
                        }
                     }
                     else
                        ++y;
                  }
               }
            }

            assert(found);
            //in this cycle we inverse edges along augmenting path
            for (size_t cx = x, cy = y, ty; cx != MINUS_TWO; cx = prev[cx], cy = ty)
            {
               ty = xy[cx];
               yx[cy] = cx;
               xy[cx] = cy;
            }
         }

      }
static void add_neighbours_to_queue(carmen_roadmap_t *roadmap, int id, 
				    int goal_id, double *fwd_utilities,
				    double *open_list, queue state_queue)
{
  int i;
  double new_util;
  double parent_utility;
  double cost, heuristic;
  carmen_roadmap_vertex_t *node_list;
  carmen_roadmap_edge_t *edges;
  int neighbour_id;
  double best_known_answer;
  int best_known_edge;

  node_list = (carmen_roadmap_vertex_t *)(roadmap->nodes->list);
  parent_utility = fwd_utilities[id];
  assert (parent_utility < 1e5);
  if (node_list[id].edges->length == 0) 
    construct_edges(roadmap, id);

  edges = (carmen_roadmap_edge_t *)node_list[id].edges->list;
  assert(node_list[id].edges->length > 0);

  best_known_answer = FLT_MAX;
  best_known_edge = -1;
  for (i = 0; i < node_list[id].edges->length; i++) {   
    neighbour_id = edges[i].id;
    if (node_list[neighbour_id].utility > FLT_MAX/2)
      continue;
    cost = get_cost(node_list+neighbour_id, node_list+id, roadmap);
    new_util = parent_utility+cost+node_list[neighbour_id].utility;
    if (best_known_answer > new_util) {
      best_known_answer = new_util;
      best_known_edge = i;
    }
  }

  for (i = 0; i < node_list[id].edges->length; i++) {   
    neighbour_id = edges[i].id;
    if (open_list[neighbour_id] == -2)
      continue;
    cost = get_cost(node_list+neighbour_id, node_list+id, roadmap);
    if (node_list[neighbour_id].utility < FLT_MAX/2) {
      if (i != best_known_edge)
	continue;
      new_util = parent_utility+cost+node_list[neighbour_id].utility;
    } else {
      heuristic = hypot(node_list[goal_id].x - node_list[neighbour_id].x,
			node_list[goal_id].y - node_list[neighbour_id].y);
      new_util = parent_utility + cost + heuristic;
    }

    if (0 && id == 576)
      carmen_warn("considering %d : %f : %f %f %f : %f \n", neighbour_id,
		  cost, fwd_utilities[neighbour_id], parent_utility, cost,
		  node_list[id].utility);

    if (cost > 1e5)
      continue;
    assert(new_util < 1e5);

    if (open_list[neighbour_id] >= 0) {
      //      assert (open_list[neighbour_id] <= new_util);
      if (open_list[neighbour_id] > new_util) {
	//	carmen_warn("Lowering cost\n");
	lower_cost(neighbour_id, id, cost, new_util, state_queue);
	open_list[neighbour_id] = new_util;
      }
      continue;
    }

    open_list[neighbour_id] = new_util;
    if (0)
      carmen_warn("pushed %d parent %d : %f %f %f\n", neighbour_id, id,
		  cost, fwd_utilities[id], parent_utility+cost);
    push_state(neighbour_id, id, cost, new_util, state_queue);
  } /* End of for (i = 0...) */
}
Beispiel #6
0
// Take one step forward in the search and return the resulting state
int AStar::search_step(void)
{
	// Break if the search is not initialised or the search is finished
	if(search_state != SEARCH_STATE_SEARCHING)
		return search_state;

	// If the open list is empty, there is no solution,
	// set state to failed and return
	if(open.empty())
		return search_state = SEARCH_STATE_FAILED;
	
	steps++;

	// Get the best node from the open list (pop the heap)
	Node* n = open.front();
	std::pop_heap(open.begin(), open.end(), NodeCmp());
	open.pop_back();

	// Check if this was the goal, if it was we're done
	if(n == goal)
	{
		// If the goal and start is not the same node,
		// reconstruct the solution path
		if(n != start)
		{
			// Set the child pointers in each node 
			// (except goal which has no child)
			Node* child_node = goal;
			Node* parent_node = goal->parent;

			do {
				// set pointer
				parent_node->child = child_node;
				// move on to next
				child_node  = parent_node;
				parent_node = parent_node->parent;
			} while(child_node != start); // start is always the first node
		}

		return search_state = SEARCH_STATE_SUCCEEDED;

	} else { // if not the goal

		// We now need to get the successors (neigbours) of this node,
		// the neighbours are placed in the list successors
		get_successors(n);
		
		// Handle each successor
		for(NodeListIterator succ = successors.begin(); succ != successors.end(); succ++)
		{
			// Calculate the cost from start to this node
			float newg = n->g + get_cost(n,(*succ));

			// Now we need to find whether the node is already on the open or 
			// closed lists. If it is but the node that is already on them is
			// better (lower g) then we can forget about this successor

			// First linear search of open list to find node
			// TODO: Improve to better complexity than linear

			NodeListIterator open_it;
			for(open_it = open.begin(); open_it != open.end(); open_it++){
				if((*open_it) == (*succ))
					break;
			}

			if((open_it != open.end()) && ((*open_it)->g <= newg))
				continue;


			// Now do the same check on closed list

			NodeListIterator closed_it;
			for(closed_it = closed.begin(); closed_it != closed.end(); closed_it++){
				if((*closed_it) == (*succ))
					break;
			}

			if((closed_it != closed.end()) && ((*closed_it)->g <= newg))
				continue;

			// This node is the best node so far so
			// lets keep it and set up its A* data

			(*succ)->parent = n;
			(*succ)->g = newg;
			(*succ)->h = estimate_cost_to_goal((*succ));
			(*succ)->f = (*succ)->g + (*succ)->h;
			(*succ)->visited = true;

			// Remove successor from closed if it was on it
			if(closed_it != closed.end())
				closed.erase(closed_it);

			// If not in open yet, push node onto open
			// else make sure to keep the heap structure
			if(open_it == open.end()){
				open.push_back((*succ));
				std::push_heap(open.begin(), open.end(), NodeCmp());
			} else {
				std::make_heap(open.begin(), open.end(), NodeCmp());
			}
		}

		// Push n onto closed, as we have expanded it now
		closed.push_back(n);
	}

 	return search_state; // return the resulting state of this search step
}
int
main ()
{
  long i, j, k;
  long l, r, u, d;
  long now;
  Node start, g;
  long count;
  long step;
  char buf[32];
  long x;
  long pre_x;
  long dif;
  long max = 0;

  scanf ("%ld %ld %ld", &H, &W, &T);

  for (i = 1; i <= H; i++)
    {
      scanf ("%s", buf);
      for (j = 1; j <= W; j++)
	{
	  s[i][j] = buf[j - 1];
	  if (s[i][j] == 'S')
	    {
	      start.h = i;
	      start.w = j;
	      start.n = (i - 1) * W + j;
	    }
	  if (s[i][j] == 'G')
	    {
	      g.h = i;
	      g.w = j;
	      g.n = (i - 1) * W + j;
	    }
	}
    }

  x = T / 2;
  dif = T / 2;
  while (1)
    {
      init ();
      for (i = 1; i <= H; i++)
	{
	  for (j = 1; j <= W; j++)
	    {
	      now = (i - 1) * W + j;
	      l = now - 1;
	      r = now + 1;
	      u = now - W;
	      d = now + W;

	      if (j > 1)
		{
		  dis[l][now] = get_cost (s[i][j], x);
		}
	      if (j < W)
		{
		  dis[r][now] = get_cost (s[i][j], x);
		}
	      if (i > 1)
		{
		  dis[u][now] = get_cost (s[i][j], x);
		}
	      if (i < H)
		{
		  dis[d][now] = get_cost (s[i][j], x);
		}
	    }
	}
      for (k = 1; k <= H * W; k++)
	for (i = 1; i <= H * W; i++)
	  for (j = 1; j <= H * W; j++)
	    dis[i][j] = min (dis[i][j], dis[i][k] + dis[k][j]);

      if (dis[start.n][g.n] <= T)
	{
	  if (max < x)
	    max = x;
	  x += (dif / 2);
	}
      else
	{
	  x -= (dif / 2);
	}
      if (dif <= 0)
	break;
      dif /= 2;
    }

  x = max + 1;
  while (1)
    {
      init ();
      for (i = 1; i <= H; i++)
	{
	  for (j = 1; j <= W; j++)
	    {
	      now = (i - 1) * W + j;
	      l = now - 1;
	      r = now + 1;
	      u = now - W;
	      d = now + W;

	      if (j > 1)
		{
		  dis[l][now] = get_cost (s[i][j], x);
		}
	      if (j < W)
		{
		  dis[r][now] = get_cost (s[i][j], x);
		}
	      if (i > 1)
		{
		  dis[u][now] = get_cost (s[i][j], x);
		}
	      if (i < H)
		{
		  dis[d][now] = get_cost (s[i][j], x);
		}
	    }
	}
      for (k = 1; k <= H * W; k++)
	for (i = 1; i <= H * W; i++)
	  for (j = 1; j <= H * W; j++)
	    dis[i][j] = min (dis[i][j], dis[i][k] + dis[k][j]);

      if (dis[start.n][g.n] <= T)
	{
	  if (max < x)
	    max = x;
	  x++;
	}
      else
	{
	  break;
	}
    }

  printf ("%ld\n", max);

  return 0;
}
Beispiel #8
0
int Generic_map::get_cost(Tripoint p)
{
  return get_cost(p.x, p.y, p.z);
}
Beispiel #9
0
bool Generic_map::blocked(int x, int y, int z)
{
  return (get_cost(x, y, z) <= 0);
}
Beispiel #10
0
int Generic_map::get_cost(Point p)
{
  return get_cost(p.x, p.y, 0);
}
Beispiel #11
0
void do_sell( CHAR_DATA * ch, char *argument )
{
  char buf[MAX_STRING_LENGTH];
  char arg[MAX_INPUT_LENGTH];
  CHAR_DATA *keeper = NULL;
  OBJ_DATA *obj = NULL;
  int cost = 0;

  one_argument( argument, arg );

  if( arg[0] == '\0' )
  {
    send_to_char( "Sell what?\r\n", ch );
    return;
  }

  if( ( keeper = find_keeper( ch ) ) == NULL )
    return;

  if( ( obj = get_obj_carry( ch, arg ) ) == NULL )
  {
    act( AT_TELL, "$n tells you 'You don't have that item.'",
	keeper, NULL, ch, TO_VICT );
    ch->reply = keeper;
    return;
  }

  if( !can_drop_obj( ch, obj ) )
  {
    send_to_char( "You can't let go of it!\r\n", ch );
    return;
  }

  if( obj->timer > 0 )
  {
    act( AT_TELL,
	"$n tells you, '$p is depreciating in value too quickly...'",
	keeper, obj, ch, TO_VICT );
    return;
  }

  if( ( cost = get_cost( ch, keeper, obj, FALSE ) ) <= 0 )
  {
    act( AT_ACTION, "$n looks uninterested in $p.", keeper, obj, ch,
	TO_VICT );
    return;
  }

  if( cost > keeper->gold )
  {
    act( AT_TELL, "$n makes a credit transaction.", keeper, obj, ch,
	TO_VICT );
  }

  separate_obj( obj );
  act( AT_ACTION, "$n sells $p.", ch, obj, NULL, TO_ROOM );
  sprintf( buf, "You sell $p for %d credit%s.", cost, cost == 1 ? "" : "s" );
  act( AT_ACTION, buf, ch, obj, NULL, TO_CHAR );
  ch->gold += cost;
  keeper->gold -= cost;
  if( keeper->gold < 0 )
    keeper->gold = 0;

  if( obj->item_type == ITEM_TRASH )
    extract_obj( obj );
  else
  {
    obj_from_char( obj );
    obj_to_char( obj, keeper );
  }

  return;
}
Beispiel #12
0
void do_buy( CHAR_DATA * ch, char *argument )
{
  char arg[MAX_INPUT_LENGTH];
  int maxgold = 0;

  argument = one_argument( argument, arg );

  if( arg[0] == '\0' )
  {
    send_to_char( "Buy what?\r\n", ch );
    return;
  }

  /* in case of different shop types */
  {
    CHAR_DATA *keeper = NULL;
    OBJ_DATA *obj = NULL;
    int cost = 0;
    int noi = 1;		/* Number of items */
    short mnoi = 20;		/* Max number of items to be bought at once */

    if( ( keeper = find_keeper( ch ) ) == NULL )
      return;

    maxgold = keeper->top_level * 10;

    if( is_number( arg ) )
    {
      noi = atoi( arg );
      argument = one_argument( argument, arg );

      if( noi > mnoi )
      {
	act( AT_TELL, "$n tells you 'I don't sell that many items at"
	    " once.'", keeper, NULL, ch, TO_VICT );
	ch->reply = keeper;
	return;
      }
    }

    obj = get_obj_carry( keeper, arg );

    if( !obj && arg[0] == '#' )
    {
      int onum = 0, oref = atoi( arg + 1 );
      bool ofound = FALSE;

      for( obj = keeper->last_carrying; obj; obj = obj->prev_content )
      {
	if( obj->wear_loc == WEAR_NONE && can_see_obj( ch, obj ) )
	  onum++;

	if( onum == oref )
	{
	  ofound = TRUE;
	  break;
	}
	else if( onum > oref )
	  break;
      }
      if( !ofound )
	obj = NULL;
    }

    cost = ( get_cost( ch, keeper, obj, TRUE ) * noi );
    if( cost <= 0 || !can_see_obj( ch, obj ) )
    {
      act( AT_TELL, "$n tells you 'I don't sell that -- try 'list'.'",
	  keeper, NULL, ch, TO_VICT );
      ch->reply = keeper;
      return;
    }

    if( !IS_OBJ_STAT( obj, ITEM_INVENTORY ) && ( noi > 1 ) )
    {
      char buf[MAX_STRING_LENGTH];
      snprintf( buf, MAX_STRING_LENGTH, "%s", "laugh" );
      interpret( keeper, buf );
      act( AT_TELL, "$n tells you 'I don't have enough of those in stock"
	  " to sell more than one at a time.'", keeper, NULL, ch,
	  TO_VICT );
      ch->reply = keeper;
      return;
    }

    if( ch->gold < cost )
    {
      act( AT_TELL, "$n tells you 'You can't afford to buy $p.'",
	  keeper, obj, ch, TO_VICT );
      ch->reply = keeper;
      return;
    }

    if( IS_SET( obj->extra_flags, ITEM_PROTOTYPE ) && IS_IMMORTAL( ch ) )
    {
      act( AT_TELL,
	  "$n tells you 'This is a only a prototype!  I can't sell you that...'",
	  keeper, NULL, ch, TO_VICT );
      ch->reply = keeper;
      return;
    }

    if( ch->carry_number + get_obj_number( obj ) > can_carry_n( ch ) )
    {
      send_to_char( "You can't carry that many items.\r\n", ch );
      return;
    }

    if( ch->carry_weight + ( get_obj_weight( obj ) * noi )
	+ ( noi > 1 ? 2 : 0 ) > can_carry_w( ch ) )
    {
      send_to_char( "You can't carry that much weight.\r\n", ch );
      return;
    }

    if( noi == 1 )
    {
      if( !IS_OBJ_STAT( obj, ITEM_INVENTORY ) )
	separate_obj( obj );
      act( AT_ACTION, "$n buys $p.", ch, obj, NULL, TO_ROOM );
      act( AT_ACTION, "You buy $p.", ch, obj, NULL, TO_CHAR );
    }
    else
    {
      sprintf( arg, "$n buys %d $p%s.", noi,
	  ( obj->short_descr[strlen( obj->short_descr ) - 1] == 's'
	    ? "" : "s" ) );
      act( AT_ACTION, arg, ch, obj, NULL, TO_ROOM );
      sprintf( arg, "You buy %d $p%s.", noi,
	  ( obj->short_descr[strlen( obj->short_descr ) - 1] == 's'
	    ? "" : "s" ) );
      act( AT_ACTION, arg, ch, obj, NULL, TO_CHAR );
      act( AT_ACTION, "$N puts them into a bag and hands it to you.",
	  ch, NULL, keeper, TO_CHAR );
    }

    ch->gold -= cost;
    keeper->gold += cost;

    if( keeper->gold > maxgold )
    {
      keeper->gold = maxgold / 2;
      act( AT_ACTION, "$n puts some credits into a large safe.", keeper,
	  NULL, NULL, TO_ROOM );
    }

    if( IS_OBJ_STAT( obj, ITEM_INVENTORY ) )
    {
      OBJ_DATA *buy_obj = create_object( obj->pIndexData );
      OBJ_DATA *bag = NULL;

      /*
       * Due to grouped objects and carry limitations in SMAUG
       * The shopkeeper gives you a bag with multiple-buy,
       * and also, only one object needs be created with a count
       * set to the number bought.                -Thoric
       */
      if( noi > 1 )
      {
	bag = create_object( get_obj_index( OBJ_VNUM_SHOPPING_BAG ) );
	/* perfect size bag ;) */
	bag->value[0] = bag->weight + ( buy_obj->weight * noi );
	buy_obj->count = noi;
	obj->pIndexData->count += ( noi - 1 );
	numobjsloaded += ( noi - 1 );
	obj_to_obj( buy_obj, bag );
	obj_to_char( bag, ch );
      }
      else
	obj_to_char( buy_obj, ch );
    }
    else
    {
      obj_from_char( obj );
      obj_to_char( obj, ch );
    }

    return;
  }
}
bool placement_problem::operator<(placement_problem const & o) const{
    if(is_feasible() and o.is_feasible()) return get_cost() < o.get_cost();
    else return (not is_feasible()) and o.is_feasible(); // Unfeasible first
}
Beispiel #14
0
void player_move(int direction)
{
    int dx = 0;
    int dy = 0;
    switch(direction) {
        case DIRECTION_NORTH:
            dy = -1;
            break;
        case DIRECTION_SOUTH:
            dy = 1;
            break;
        case DIRECTION_EAST:
            dx = 1;
            break;
        case DIRECTION_WEST:
            dx = -1;
            break;
        case DIRECTION_NORTHEAST:
            dx = 1;
            dy = -1;
            break;
        case DIRECTION_NORTHWEST:
            dx = -1;
            dy = -1;
            break;
        case DIRECTION_SOUTHEAST:
            dx = 1;
            dy = 1;
            break;
        case DIRECTION_SOUTHWEST:
            dx = -1;
            dy = 1;
            break;
        case DIRECTION_UP:
            if(z > 0 && is_up_stairs(x, y, current_map))
                z--;
            return;
        case DIRECTION_DOWN:
            if(z < LEVEL_COUNT - 1 && is_down_stairs(x, y, current_map))
                z++;
            return;
    }
    int res = can_move(x + dx, y + dy, current_map);
    if(res == 1) {
        x += dx;
        y += dy;
        int cost = 1 + get_cost(x, y, current_map);
        if(dx != 0 && dy != 0)
            cost *= 1.5;
        ep_current -= cost;
        if(ep_current <= 0)
            add_message(COLOR_EP_CRIT, "Out of energy, you fall to the ground.");
        else
            describe_ground(x, y, current_map);
    } else if(res == 2) {
        actor* act = get_actor_at(x + dx, y + dy, current_map);
        int astr = str;
        for(int i = 0; i < SLOT_COUNT; ++i)
            if(equipment[i])
                astr += equipment[i]->str;
        int dmg = damage_actor(act, astr);
        char* damage_text = 0;
        if(dmg > 0) {
            int len = snprintf(0, 0, "You hit the %s for %d damage", act->name, dmg);
            damage_text = calloc(len + 1, sizeof(char));
            snprintf(damage_text, len + 1, "You hit the %s for %d damage", act->name, dmg);
        } else {
            int len = snprintf(0, 0, "You miss the %s", act->name);
            damage_text = calloc(len + 1, sizeof(char));
            snprintf(damage_text, len + 1, "You miss the %s", act->name);
        }
        if(act->hp <= 0) {
            printf_message(COLOR_DEFAULT, "You kill the %s!", act->name);
            add_xp(act->xp);
        } else
            add_message(COLOR_DEFAULT, damage_text);
        free(damage_text);
    }
}