evolve4src/src/evolve_simulator/cell.cpp
void Opcode_CMOVE(KFORTH_MACHINE *kfm)
{
	CELL *cell, *c;
	ORGANISM *o;
	UNIVERSE *u;
	int x, y, xoffset, yoffset;
	int save_x, save_y;
	KFORTH_INTEGER value;
	int cnt;

	if( kfm->data_stack_size < 2 )
		return;

	cell = (CELL*) kfm->client_data;
	o = cell->organism;
	u = o->universe;

	value = kforth_data_stack_pop(kfm);
	yoffset = NORMALIZE_OFFSET(value);

	value = kforth_data_stack_pop(kfm);
	xoffset = NORMALIZE_OFFSET(value);

	x = cell->x + xoffset;
	y = cell->y + yoffset;

	if( ! grid_is_blank(u, x, y) ) {
		kforth_data_stack_push(kfm, 0);
		return;
	}

	/*
	 * Move cell to new location
	 */
	save_x = cell->x;
	save_y = cell->y;

	Grid_Clear(u, cell->x, cell->y);

	cell->x = x;
	cell->y = y;
	Grid_SetCell(u, cell);

	/*
	 * Make sure all cells in organism have at least 1 neighbor in the
	 * N, S, E, or W direction
	 */
	for(c=o->cells; c; c=c->next) {
		c->color = 0;
	}

	//cnt = mark_reachable_cells_recur(o->cells);
	cnt = mark_reachable_cells(o->cells);

	if( cnt != o->ncells ) {
		/*
		 * connectivity requirement is not true, so undo the move,
		 * and push 0 on data stack.
		 */
		Grid_Clear(u, cell->x, cell->y);
		cell->x = save_x;
		cell->y = save_y;
		Grid_SetCell(u, cell);
		kforth_data_stack_push(kfm, 0);
	} else {
		/* success! */
		kforth_data_stack_push(kfm, 1);
	}
}
/***********************************************************************
 * KFORTH NAME:		CMOVE
 * STACK BEHAVIOR:	(x y -- r)
 *
 * Move cell relative to organism. (x, y) specifies
 * a direction to move relative to current location.
 *
 * If successful r=1, else r=0.
 *
 * RULES:
 *	1. The destination location must be vacant
 *	2. After the move, the all cells must be connected in the N, S, E, or W direction
 *	   (a diagonal connection is not enough)
 *
 * Uses a scan line fill algorithm to analyse the organism after the cmove
 * to determine if its properly connected.
 */
KFORTH NAME:         CMOVE
STACK BEHAVIOR:      (x y -- r)

Move cell relative to organism. (x, y) specifies
a direction to move relative to current location.

If successful r=1, else r=0.

1. The destination location must be vacant
2. After the move, the all cells must be connected in the N, S, E, or W direction
(a diagonal connection is not enough)

Uses a scan line fill algorithm to analyse the organism after the cmove
to determine if its properly connected.
KFORTH NAME : CMOVE STACK BEHAVIOR : ( x y -- r ) Move cell relative to organism . ( x y ) specifies a direction to move relative to current location . If successful r = 1 else r = 0 . 1 . The destination location must be vacant 2 . After the move the all cells must be connected in the N S E or W direction ( a diagonal connection is not enough ) Uses a scan line fill algorithm to analyse the organism after the cmove to determine if its properly connected .
void Opcode_CMOVE(KFORTH_MACHINE *kfm)
{
	CELL *cell, *c;
	ORGANISM *o;
	UNIVERSE *u;
	int x, y, xoffset, yoffset;
	int save_x, save_y;
	KFORTH_INTEGER value;
	int cnt;
	if( kfm->data_stack_size < 2 )
		return;
	cell = (CELL*) kfm->client_data;
	o = cell->organism;
	u = o->universe;
	value = kforth_data_stack_pop(kfm);
	yoffset = NORMALIZE_OFFSET(value);
	value = kforth_data_stack_pop(kfm);
	xoffset = NORMALIZE_OFFSET(value);
	x = cell->x + xoffset;
	y = cell->y + yoffset;
	if( ! grid_is_blank(u, x, y) ) {
		kforth_data_stack_push(kfm, 0);
		return;
	}
	save_x = cell->x;
	save_y = cell->y;
	Grid_Clear(u, cell->x, cell->y);
	cell->x = x;
	cell->y = y;
	Grid_SetCell(u, cell);
	for(c=o->cells; c; c=c->next) {
		c->color = 0;
	}
	cnt = mark_reachable_cells(o->cells);
	if( cnt != o->ncells ) {
		Grid_Clear(u, cell->x, cell->y);
		cell->x = save_x;
		cell->y = save_y;
		Grid_SetCell(u, cell);
		kforth_data_stack_push(kfm, 0);
	} else {
		kforth_data_stack_push(kfm, 1);
	}
}
void Opcode_CMOVE ( KFORTH_MACHINE * kfm ) { CELL * cell , * c ; ORGANISM * o ; UNIVERSE * u ; int x , y , xoffset , yoffset ; int save_x , save_y ; KFORTH_INTEGER value ; int cnt ; if ( kfm -> data_stack_size < 2 ) return ; cell = ( CELL * ) kfm -> client_data ; o = cell -> organism ; u = o -> universe ; value = kforth_data_stack_pop ( kfm ) ; yoffset = NORMALIZE_OFFSET ( value ) ; value = kforth_data_stack_pop ( kfm ) ; xoffset = NORMALIZE_OFFSET ( value ) ; x = cell -> x + xoffset ; y = cell -> y + yoffset ; if ( ! grid_is_blank ( u , x , y ) ) { kforth_data_stack_push ( kfm , 0 ) ; return ; } save_x = cell -> x ; save_y = cell -> y ; Grid_Clear ( u , cell -> x , cell -> y ) ; cell -> x = x ; cell -> y = y ; Grid_SetCell ( u , cell ) ; for ( c = o -> cells ; c ; c = c -> next ) { c -> color = 0 ; } cnt = mark_reachable_cells ( o -> cells ) ; if ( cnt != o -> ncells ) { Grid_Clear ( u , cell -> x , cell -> y ) ; cell -> x = save_x ; cell -> y = save_y ; Grid_SetCell ( u , cell ) ; kforth_data_stack_push ( kfm , 0 ) ; } else { kforth_data_stack_push ( kfm , 1 ) ; } }
KFORTH NAME:         CMOVE
 STACK BEHAVIOR:      (x y -- r)
KFORTH NAME : CMOVE STACK BEHAVIOR : ( x y -- r )
/*
	 * Move cell to new location
	 */ /*
	 * Make sure all cells in organism have at least 1 neighbor in the
	 * N, S, E, or W direction
	 */ //cnt = mark_reachable_cells_recur(o->cells); /*
		 * connectivity requirement is not true, so undo the move,
		 * and push 0 on data stack.
		 */ /* success! */