AI-Pathfinding-AStar-Rectangle

 view release on metacpan or  search on metacpan

Rectangle.xs  view on Meta::CPAN

}

void
inline init_move_offset(pmap map, int * const moves, int trim){
    const int dx = 1;
    const int dy = map->width + 2;
    moves[0] = 0;
    moves[5] = 0;
    moves[1] = -dx + dy;
    moves[2] =     + dy;
    moves[3] = +dx + dy;
    moves[4] = -dx     ;
    moves[6] = +dx     ;
    moves[7] = -dx - dy;
    moves[8] =     - dy;
    moves[9] = +dx - dy;
    if (trim){
        moves[0] = moves[8];
        moves[5] = moves[9];
    }
}

bool
inline on_the_map(pmap newmap, int x, int y){
    if (x< newmap->start_x  ||y< newmap->start_y ){
        return 0;
    }
    else if (x - newmap->start_x >= (int )newmap->width || y - newmap->start_y >= (int)newmap->height){
        return 0;
    }
    return 1;
}
int 
inline get_offset(pmap newmap, int x, int y){
    return ( (y - newmap->start_y + 1)*(newmap->width+2) + (x-newmap->start_x+1));
}

int 
inline get_offset_abs(pmap newmap, int x, int y){
    return ( (y + 1)*(newmap->width+2) + (x + 1));
}
void
inline get_xy(pmap newmap, int offset, int *x,int *y){
   *x = offset % ( newmap->width + 2) + newmap->start_x - 1;
   *y = offset / ( newmap->width + 2) + newmap->start_y - 1;
}

MODULE = AI::Pathfinding::AStar::Rectangle		PACKAGE = AI::Pathfinding::AStar::Rectangle		

void 
clone(pmap self)
PREINIT:
SV *string;
SV *clone;
    PPCODE:
        string = SvRV(ST(0));
	clone = sv_newmortal();
	sv_setsv( clone, string );
	clone = newRV_inc( clone );

	sv_bless( clone, SvSTASH( string ));
	XPUSHs( sv_2mortal(clone));
	

void 
clone_rect(pmap self, IV begin_x, IV begin_y, IV end_x, IV end_y)
PREINIT:
SV *clone;
struct map_like re_map;
pmap newmap;
size_t map_size;
    PPCODE:
	if (!on_the_map( self, begin_x, begin_y ))
	    croak_xs_usage( cv, "left corner of  rectangle is out of the map" );
	if (!on_the_map( self, end_x, end_y ))
	    croak_xs_usage( cv, "rigth corner of rectangle is out of the map" );
	if ( ! ( begin_x <= end_x ))
	    croak_xs_usage( cv, "attemp made to make zero width rectangle" );
	if ( ! ( begin_y <= end_y ))
	    croak_xs_usage( cv, "attemp made to make zero height rectangle" );
	
	
	clone = sv_newmortal();
	sv_setpvn( clone, "", 0 );

	re_map.width  = end_x - begin_x + 1;
	re_map.height  = end_y - begin_y + 1;
	map_size = sizeof(struct map_like)+(re_map.width + 2) * (re_map.height+2) *sizeof( char );
	SvGROW( clone, map_size ); 

	/* Initializing */
        newmap = (pmap) SvPV_nolen( clone );
        Zero(newmap, map_size, char);
        newmap->width = re_map.width;
        newmap->height = re_map.height;
	newmap->start_x = begin_x;
	newmap->start_y = begin_y;

        SvCUR_set(clone, map_size);
	/*Copy passability */
	if (1) {
	    int x, y;
	    for ( x = begin_x; x <= end_x ; ++x ){
		for ( y = begin_y; y <= end_y; ++y ){
		    newmap->map[ get_offset( newmap, x, y )]=
			self->map[ get_offset( self, x, y )];
		}
	    }

	};
	
	/*Prepare for return full object */
	clone = newRV_inc( clone );
	sv_bless( clone, SvSTASH( SvRV(ST(0) )));
	XPUSHs( sv_2mortal(clone));

void 
new(self, options)
SV * self;
SV * options;
    INIT:
    SV * object;
    struct map_like re_map;
    pmap newmap;
    size_t map_size;
    SV *RETVALUE;
    PPCODE:
        if (!(SvROK(options) && (is_hash(SvRV(options))))){
            croak("Not hashref: USAGE: new( {width=>10, height=>20})");            
        }
        if (!check_options(&re_map, (HV *) SvRV(options))){
            croak("Not enough params: USAGE: new( {width=>10, height=>20})");            
            croak("Fail found mandatory param");
        }
        object  = sv_2mortal(newSVpvn("",0));


        SvGROW(object, map_size = sizeof(struct map_like)+(re_map.width + 2) * (re_map.height+2));

        newmap = (pmap) SvPV_nolen(object);

        Zero(newmap, map_size, char);

        newmap->width = re_map.width;
        newmap->height = re_map.height;
        SvCUR_set(object, map_size);
        RETVALUE = sv_2mortal( newRV_inc(object ));
        sv_bless(RETVALUE, gv_stashpv( SvPV_nolen( self ), GV_ADD));
        XPUSHs(RETVALUE);

void 
start_x(pmap self, int newpos_x = 0 )
    PPCODE:
    if (items>1){
	    self->start_x = newpos_x;
	    XPUSHs(ST(0));
    }
    else {
	mXPUSHi(self->start_x);
    };
    


        

void 
start_y(pmap self, int newpos_y = 0 )
    PPCODE:
    if (items>1){
	self->start_y = newpos_y;
	XPUSHs(ST(0));
    }
    else {
	mXPUSHi(self->start_y);
    }

void 
width(pmap newmap)
    PPCODE:
    XPUSHs(sv_2mortal(newSViv(newmap->width)));

void 
height(pmap newmap)
    PPCODE:
    mXPUSHi(newmap->height);

void
begin_y( pmap self )
PPCODE:
    mXPUSHi(self->start_y);

void
end_y( pmap self )
PPCODE:
    mXPUSHi(self->start_y + (signed) self->height -1) ;

void
begin_x( pmap self )
PPCODE:
    mXPUSHi( self->start_x );

void
end_x( pmap self )
PPCODE:
    mXPUSHi( self->start_x + (signed) self->width -1 );

void 
last_x(pmap self)



( run in 1.225 second using v1.01-cache-2.11-cpan-6aa56a78535 )