Esempio n. 1
0
static inline unsigned int 
is_alive(struct field * f, unsigned int x, unsigned int y)
{
    unsigned int count;
    unsigned int i, j;
    unsigned char *p;

    count = 0;

    for (i = x - 1; i <= x + 1; i++) {
	for (j = y - 1; j <= y + 1; j++) {
	    if (y != j || x != i) {
		count += cell_value(*cell_at(f, i, j), f->max_age);
	    }
	}
    }

    p = cell_at(f, x, y);
    if (*p) {
	if (count == 2 || count == 3) {
	    return ((*p) + 1);
	} else {
	    return (0);
	}
    } else {
	if (count == 3) {
	    return (1);
	} else {
	    return (0);
	}
    }
}
Esempio n. 2
0
static void 
populate_edges(struct field * f, unsigned int p)
{
    unsigned int i;

    for (i = f->width; i--;) {
	*cell_at(f, i, 0) = random_cell(p);
	*cell_at(f, i, f->height - 1) = random_cell(p);
    }

    for (i = f->height; i--;) {
	*cell_at(f, f->width - 1, i) = random_cell(p);
	*cell_at(f, 0, i) = random_cell(p);
    }
}
Esempio n. 3
0
void level::define_connect_status(const unsigned short x, const unsigned short y)
{
	cell& cell_curr = cell_at(x, y);
	if (cell_curr.active() || cell_curr.rotation_in_progress())
		return;	//Already connected or rotate in progress

	cell_curr.set_active(true);

	//to up
	if (cell_curr.top_connected()) {
		if (_wrap_mode || y > 0) {
			const unsigned short next_y = y > 0 ? y - 1 : _size_cell - 1;
			cell& cell_next = cell_at(x, next_y);
			if (cell_next.bottom_connected())
				define_connect_status(x, next_y);
		}
	}

	//to down
	if (cell_curr.bottom_connected()) {
		if (_wrap_mode || y < _size_cell - 1) {
			const unsigned short next_y = (y + 1) % _size_cell;
			cell& cell_next = cell_at(x, next_y);
			if (cell_next.top_connected())
				define_connect_status(x, next_y);
		}
	}

	//to left
	if (cell_curr.left_connected()) {
		if (_wrap_mode || x > 0) {
			const unsigned short next_x = x > 0 ? x - 1 : _size_cell - 1;
			cell& cell_next = cell_at(next_x, y);
			if (cell_next.right_connected())
				define_connect_status(next_x, y);
		}
	}

	//to right
	if (cell_curr.right_connected()) {
		if (_wrap_mode || x < _size_cell - 1) {
			const unsigned short next_x = (x + 1) % _size_cell;
			cell& cell_next = cell_at(next_x, y);
			if (cell_next.left_connected())
				define_connect_status(next_x, y);
		}
	}
}
Esempio n. 4
0
void level::install_sender()
{
	do {
		_senderX = static_cast<unsigned short>(mtrandom::random(0, static_cast<int>(_size_cell)));
		_senderY = static_cast<unsigned short>(mtrandom::random(0, static_cast<int>(_size_cell)));

	} while (!_wrap_mode && (_senderX == 0 || _senderX == _size_cell - 1 || _senderY == 0 || _senderY == _size_cell - 1));


	cell& srv = cell_at(_senderX, _senderY);
	srv.set_type_sender();

	//Define zero point (sender output cell)
	_zeroX = _senderX;
	_zeroY = _senderY;
	switch (mtrandom::random(0, 4)) {
		case 0:
			_zeroX = (_zeroX + 1) % _size_cell;
			break;
		case 1:
			_zeroX = _zeroX == 0 ? _size_cell - 1 : _zeroX - 1;
			break;
		case 2:
			_zeroY = (_zeroY + 1) % _size_cell;
			break;
		case 3:
			_zeroY = _zeroY == 0 ? _size_cell - 1 : _zeroY - 1;
			break;
		default:
			assert(false);
			break;
	}

	make_connection(_senderX, _senderY, _zeroX, _zeroY);
}
Esempio n. 5
0
struct world *init_world(struct world_init *init) {
  if (init==NULL)
    return NULL;

  struct world *ret = malloc(sizeof(*ret));
  if (ret==NULL)
    return NULL;

  ret->init = init;
  ret->cells = malloc(init->size_x * init->size_y * sizeof(struct world_cell));
  memset(ret->cells, 0, init->size_x * init->size_y * sizeof(struct world_cell));
  if (ret->cells==NULL) {
    free(ret);
    return NULL;
  }

  uint16_t x, y, k;
  for (y=0; y<init->size_y; y++)
    for (x=0; x<init->size_x; x++)
      for (k=0; k<init->n_sources; k++)
        cell_at(ret, x, y)->values[init->sources[k].property] +=
          propagated_value_at(init->sources[k].intensity,
            init->sources[k].x, init->sources[k].y, x, y,
            world_property_propagation[init->sources[k].property]);

  return ret;
}
Esempio n. 6
0
void dump_world(const struct world *world) {
  printf("Dumping world: size_x=%d, size_y=%d, start_x=%d, start_y=%d\n",
      world->init->size_x, world->init->size_y,
      world->init->start_x, world->init->start_y);
  printf("A world with %d cells: \n", world->init->size_x * world->init->size_y);
  
  uint16_t x, y, k;
  printf("    ");
  for (x=0; x<world->init->size_x; x++)
    printf(" %03d", x);
  printf("\n");
  printf("    ");
  for (x=0; x<world->init->size_x; x++)
    printf(" ===");
  printf("\n");
  for (y=0; y<world->init->size_y; y++) {
    for (k=0; k<WORLD_PROPERTY_COUNT; k++) {
      if (k==0)
        printf(" %03d", y);
      else
        printf("    ");
      for (x=0; x<world->init->size_x; x++) {
        struct world_cell *cell = cell_at(world, x, y);
        if (cell->values[k]!=0)
          printf(" %03d", cell->values[k]);
        else
          printf(" ...");
      }
      printf("\n");
    }
  }
}
Esempio n. 7
0
const char *cell_info (struct world *world, struct position *pos)
{
	static char info[100];
	static char *team[NUM_COLONIES] = { "friendly", "enemy" };
	static char *direction[6] = { "left", "down left", "down right", "right", "up right", "up left" };
	char *s;
	struct cell *cell;

	cell = cell_at (world, pos);
	if (!cell) return "(pointer out of range)";

	s = info;
	s += sprintf (s, "cell (%d/%d)", pos->x, pos->y); 
	if (cell->rocky) s += sprintf (s, " (rock)"); 
	if (cell->home_of_colony != -1) s += sprintf (s, " (#%d %s homebase)", cell->home_of_colony, team [cell->home_of_colony]); 
	if (cell->food) s += sprintf (s, " (%d food)", cell->food); 
	if (cell->ant) {
		s += sprintf (s, " (%s ant", team [cell->ant->colony]); 
		s += sprintf (s, ", heading %s", direction [cell->ant->direction]); 
		s += sprintf (s, ", id %d, state %d", cell->ant->id, cell->ant->state); 
		s += sprintf (s, ")");
	}

	return info;
}
Esempio n. 8
0
int display_world (struct world *world)
{
	int ret; 
	struct position p;
	struct cell *cell;
	int team;

	if ((ret=display_map (world)) != 0) return ret;

	for (p.x=0;p.x<world->size_x;p.x++) {
		for (p.y=0;p.y<world->size_y;p.y++) {
			cell = cell_at (world, &p);

			if (cell->food > 0)
				v_set_food (&p, cell);	
			for (team=0; team<NUM_COLONIES; team++) {
				if (cell->markers[team] > 0) {
					v_set_marker (&p, cell->markers);
				}
			}
			if (cell->ant) {
				v_set_ant (cell->ant);
			}
		}
	}

	return v_redisplay_everything ();
}
Esempio n. 9
0
static int display_map (struct world *world)
/* Helper function to genereate ASCII map from world. and feed it into 
   v_load_map. 
*/

{
	char *tmp_map;
	char c;
	struct position p;
	struct cell *cell;
	int ret; 

	tmp_map = (char *)malloc (world->size_x*world->size_y);
	memset (tmp_map, ' ', world->size_x*world->size_y);

	for (p.x=0;p.x<world->size_x;p.x++) {
		for (p.y=0;p.y<world->size_y;p.y++) {
			cell = cell_at (world, &p);
			if (cell->home_of_colony != -1) {
				c = colony_home_chars[cell->home_of_colony];		
			} else if (cell->rocky) {
				c = ROCK_CELL;
			} else c = EMPTY_CELL;
			tmp_map[p.y*world->size_x+p.x] = c;
		}
	}

	ret = v_load_map (world->size_x, world->size_y, tmp_map);
	free (tmp_map);
	return ret;
}
Esempio n. 10
0
File: grid.c Progetto: cmr/minesweep
/**
 * Set the value of a grid cell.
 *
 * @param grid Grid to set cell on
 * @param square Value to set. Valid inputs: @a SQUARE_BOMB, @a SQUARE_EMPTY
 */
void grid_set(grid_t *grid, int x, int y, square_t square) {
	assert(square_is_bomb(square) || square_value(square) == 0);
	assert(grid != NULL);
	assert(grid->data != NULL);
	assert(x != 0);
	assert(y != 0);

	if (x > grid->width || y > grid->height) {
		/* Don't overflow into wrong row or, worse, unallocated memory */
		return;
	}
	*cell_at(x, y) = square;

	/* Increment adjacent cells */
	incr_cell(x-1, y-1);
	incr_cell(x, y-1);
	incr_cell(x+1, y-1);

	incr_cell(x-1, y);
	incr_cell(x+1, y);

	incr_cell(x-1, y+1);
	incr_cell(x, y+1);
	incr_cell(x+1, y+1);
}
Esempio n. 11
0
bool level::make_route(const unsigned short x, const unsigned short y)
{
	unsigned short next_x = 0, next_y = 0;	//Next coordinates

	bool result = false;

	int try_counter = 5;
	while (try_counter && !result) {
		short i, j;
		do {
			i = 1 - static_cast<unsigned short>(mtrandom::random(0, 3));
			j = 1 - static_cast<unsigned short>(mtrandom::random(0, 3));
		} while ((i && j) || (!i && !j));	//Diagonal


		if (!_wrap_mode) {
			if ((j < 0 && x == 0) || (j > 0 && x == _size_cell - 1) ||
				(i < 0 && y == 0) || (i > 0 && y == _size_cell - 1)) {
					--try_counter;
					continue;
			}
		}

		const unsigned short cp_x = (j < 0 && x == 0) ? _size_cell - 1 : (x + j) % _size_cell;
		const unsigned short cp_y = (i < 0 && y == 0) ? _size_cell - 1 : (y + i) % _size_cell;

		cell& cell = cell_at(cp_x, cp_y);
		if (!cell.is_used() && cell.can_add_tube()) {
			result = true;
			next_x = cp_x;
			next_y = cp_y;
		}

		--try_counter;
	}

	if (!result)
		return false;	//min point - we don't have a route

	make_connection(x, y, next_x, next_y);
	cell_at(x, y).set_used(true);

	if (cell_at(next_x, next_y).tube_type() == cell::tt_joiner || (next_x == _zeroX && next_y == _zeroY))
		return true;

	return make_route(next_x, next_y);
}
Esempio n. 12
0
uint8_t value_at(const struct world *world, uint16_t x, uint16_t y,
  enum world_property_names k)
{
  struct world_cell *cell = cell_at(world, x, y);
  if (cell==NULL)
    return -1;
  return cell->values[k];
}
Esempio n. 13
0
void level::rotate(const unsigned short x, const unsigned short y, const bool dir)
{
	cell& c = cell_at(x, y);
	if (c.cell_type() != cell::ct_free) {
		c.rotate(dir);
		define_connect_status();
	}
}
Esempio n. 14
0
File: grid.c Progetto: cmr/minesweep
static inline void incr_cell_f(grid_t *grid, int x, int y) {
	/* 0-1 is UINT_MAX, so when setting cells on the edges of the grid, this
	 * won't modify other rows or, even worse, unallocated pages.
	 * Not an assert because it's vital to proper functioning.
	 */
	assert(grid != NULL);
	assert(grid->data != NULL);

	if (x >= grid->width  || x <= 0) {
		return;
	}
	if (y >= grid->height || y <= 0) {
		return;
	}

	if (!square_is_bomb(*cell_at(x, y))) {
		square_value(*cell_at(x, y)) += 1;
	}
}
Esempio n. 15
0
void level::make_connection(const unsigned short curr_x, const unsigned short curr_y, const unsigned short next_x, const unsigned short next_y)
{
	assert(curr_x == next_x || curr_y == next_y);
	assert(curr_x != next_x || curr_y != next_y);

	cell& cell_curr = cell_at(curr_x, curr_y);
	cell& cell_next = cell_at(next_x, next_y);

	//Wrapping
	if (next_x == 0 && curr_x == _size_cell - 1) {
		cell_curr.add_tube(cell::cs_right);
		cell_next.add_tube(cell::cs_left);
	}
	else if (next_x == _size_cell - 1 && curr_x == 0) {
		cell_curr.add_tube(cell::cs_left);
		cell_next.add_tube(cell::cs_right);
	}
	else if (next_y == 0 && curr_y == _size_cell - 1) {
		cell_curr.add_tube(cell::cs_bottom);
		cell_next.add_tube(cell::cs_top);
	}
	else if (next_y == _size_cell - 1 && curr_y == 0) {
		cell_curr.add_tube(cell::cs_top);
		cell_next.add_tube(cell::cs_bottom);
	}
	//Non-wrapping
	else if (next_x < curr_x) {
		cell_curr.add_tube(cell::cs_left);
		cell_next.add_tube(cell::cs_right);
	}
	else if (next_x > curr_x) {
		cell_curr.add_tube(cell::cs_right);
		cell_next.add_tube(cell::cs_left);
	}
	else if (next_y < curr_y) {
		cell_curr.add_tube(cell::cs_top);
		cell_next.add_tube(cell::cs_bottom);
	}
	else if (next_y > curr_y) {
		cell_curr.add_tube(cell::cs_bottom);
		cell_next.add_tube(cell::cs_top);
	}
}
Esempio n. 16
0
File: grid.c Progetto: cmr/minesweep
/**
 * Get the value of a grid cell.
 *
 * @param grid Grid to get cell from
 * @returns The square at (x,y)
 */
square_t grid_get(grid_t *grid, int x, int y) {
	assert(grid != NULL);
	assert(x <= grid->width);
	assert(y <= grid->height);
	assert(x > 0);
	assert(y > 0);
	assert(grid->data != NULL);

	return *cell_at(x, y);
}
Esempio n. 17
0
static void 
populate_field(struct field * f, unsigned int p)
{
    unsigned int x, y;

    for (x = 0; x < f->width; x++) {
	for (y = 0; y < f->height; y++) {
	    *cell_at(f, x, y) = random_cell(p);
	}
    }
}
Esempio n. 18
0
File: grid.c Progetto: cmr/minesweep
/**
 * Randomly place bombs on a grid.
 *
 * @param grid Grid to place bombs on
 * @param bombs Number of bombs to place
 */
void grid_add_bombs(grid_t *grid, unsigned int bombs) {
	int x, y;
	while (bombs != 0) {
		do {
			x = (random() % grid->width) + 1;
			y = (random() % grid->height) + 1;
		} while (square_is_bomb(*cell_at(x, y)));

		grid_set(grid, x, y, SQUARE_BOMB);
		bombs--;
	}
}
Esempio n. 19
0
int show_state_in_editor (struct world *world)
{
	struct position *pos;
	struct cell *cell;

	v_query_pointer (pos);

	cell = cell_at (world, pos);
	if (!cell) return -1;

	return 0;
}
Esempio n. 20
0
bool level::install_receiver()
{
	//Get free cells
	vector< pair<unsigned short, unsigned short> > free_cells;
	for (unsigned short x = 0; x < _size_cell; ++x) {
		for (unsigned short y = 0; y < _size_cell; ++y) {
			cell& c = cell_at(x, y);
			if (c.cell_type() == cell::ct_free)
				free_cells.push_back(make_pair(x, y));
			c.set_used(false);

		}
	}
	if (free_cells.empty())
		return true;	//No more free cells

	bool result = false;

	int try_counter = _size_cell * 2;
	while (try_counter-- && !result) {
		//Backup current map state
		const cells backup = _cells;
		const int free_cell_ind = mtrandom::random(0, static_cast<int>(free_cells.size()));
		const unsigned short free_x = free_cells[free_cell_ind].first;
		const unsigned short free_y = free_cells[free_cell_ind].second;
		cell& rcv = cell_at(free_x, free_y);
		rcv.set_type_receiver();

		result = make_route(free_x, free_y);

		if (!result)	//Restore map
			_cells = backup;
	}

	return result;
}
Esempio n. 21
0
File: grid.c Progetto: cmr/minesweep
/**
 * Reveal a sqaure.
 *
 * @param grid Grid to reveal cell on
 * @returns Value of the cell at (x,y). Result will be -(value + 1) if there
 * is a bomb in the cell
 */
int grid_reveal(grid_t *grid, int x, int y) {
	assert(grid != NULL);
	assert(grid->data != NULL);

	if (x > grid->width || y > grid->height) {
		return 0;
	}
	if (x < 1 || y < 1) {
		return 0;
	}

	square_t *cell = cell_at(x, y);
	int old_hidden = cell->hidden;
	cell->hidden = 0;

	if (cell->bomb) {
		return -(cell->value+1);
	}

	if (old_hidden == 0) {
		return cell->value;
	}

	/* Don't do a potentially expensive operation */

	if(cell->value == 0) {
		/* 0 cells have their neighbors revealed as well
		 * XXX: this code has a pathlogical case of large contiguous
		 * blocks of 0's. grid_reveal will be called for each square
		 * mulptile times. This is inefficient, and also has a high
		 * probability of blowing the stack for large grids.
		 */
		grid_reveal(grid, x-1, y-1);
		grid_reveal(grid, x, y-1);
		grid_reveal(grid, x+1, y-1);

		grid_reveal(grid, x-1, y);
		grid_reveal(grid, x+1, y);

		grid_reveal(grid, x-1, y+1);
		grid_reveal(grid, x, y+1);
		grid_reveal(grid, x+1, y+1);
	}

	return cell->value;
}
Esempio n. 22
0
bool level::load(const unsigned long id, const size sz, const bool wrap_mode, const string& state)
{
	assert(id >= 1 && id <= PW_MAX_LEVEL_NUMBER);
	assert(!state.empty());

	_id = id;
	sprintf(_id_text, "%08u", static_cast<unsigned int>(_id));
	_wrap_mode = wrap_mode;
	_size_type = sz;
	_size_cell = size_from_type(sz);
	const size_t cell_count = _size_cell * _size_cell;
	_cells.resize(cell_count);

	if (state.length() != cell_count * 2)
		return false;

	for (size_t i = 0; i < cell_count; ++i) {
		_cells[i].reset();

		unsigned char cell_state;
		cell_state = C2H(state[i * 2]);
		cell_state = cell_state << 4;
		cell_state |= C2H(state[i * 2 + 1]);

		if (!_cells[i].load(cell_state))
			return false;
	}

	for (unsigned short y = 0; y < _size_cell; ++y) {
		for (unsigned short x = 0; x < _size_cell; ++x) {
			cell& c = cell_at(x, y);
			if (c.cell_type() == cell::ct_sender) {
				_senderX = x;
				_senderY = y;
				break;
			}
		}
	}

	define_connect_status();
	_solved = false;

	return true;
}
Esempio n. 23
0
int update_everything (struct world *world)
{
	struct position p;
	struct cell *cell;
	int team;
	int need_display;

	for (p.x=0; p.x<world->size_x; p.x++) {
		for (p.y=0; p.y<world->size_y; p.y++) {
			cell = cell_at (world, &p);
			
			need_display = 0;
			if (cell->ant_needs_update) {
				if (cell->ant) {
					v_set_ant (cell->ant);
				} else {
					v_remove_ant (&p);
				}
				cell->ant_needs_update = 0;		
				need_display = 1;
			}
			if (cell->food_needs_update) {
				v_set_food (&p, cell->food);
				cell->food_needs_update = 0;
				need_display = 1;
			}
			if (cell->markers_need_update) {
				for (team=0; team<NUM_COLONIES; team++) {	
					v_set_marker (&p, team, cell->markers[team]);
				}
				cell->markers_need_update = 0;
				need_display = 1;
			}
			if (need_display) v_display_cell (&p);
		}
	}
			
	return 0;
}
Esempio n. 24
0
static void
draw_field(struct state *st, struct field * f)
{
    unsigned int x, y;
    unsigned int rx, ry = 0;	/* random amount to offset the dot */
    unsigned int size = 1 << f->cell_size;
    unsigned int mask = size - 1;
    unsigned int fg_count, bg_count;

    /* columns 0 and width-1 are off screen and not drawn. */
    for (y = 1; y < f->height - 1; y++) {
	fg_count = 0;
	bg_count = 0;

	/* rows 0 and height-1 are off screen and not drawn. */
	for (x = 1; x < f->width - 1; x++) {
	    rx = random();
	    ry = rx >> f->cell_size;
	    rx &= mask;
	    ry &= mask;

	    if (*cell_at(f, x, y)) {
		st->fg_points[fg_count].x = (short) x *size - rx - 1;
		st->fg_points[fg_count].y = (short) y *size - ry - 1;
		fg_count++;
	    } else {
		st->bg_points[bg_count].x = (short) x *size - rx - 1;
		st->bg_points[bg_count].y = (short) y *size - ry - 1;
		bg_count++;
	    }
	}
	XDrawPoints(st->dpy, st->window, st->fgc, st->fg_points, fg_count,
		    CoordModeOrigin);
	XDrawPoints(st->dpy, st->window, st->bgc, st->bg_points, bg_count,
		    CoordModeOrigin);
    }
}
Esempio n. 25
0
void level::reverse_lock(const unsigned short x, const unsigned short y)
{
	cell& c = cell_at(x, y);
	if (c.cell_type() != cell::ct_free)
		c.reverse_lock();
}
Esempio n. 26
0
 Cell* next_cell(const Cell* cell, geom2d::Direction d)
 {
     return cell_at(point(cell) + d.to_vector());
 }
Esempio n. 27
0
File: tape.c Progetto: jchmrt/etbi
/**
 * Return the value of the cell at OFFSET from the current cell in
 * TAPE.
 */
char
get_tape (tape *tape, int offset)
{
  char *cell = cell_at (tape, offset);
  return *cell;
}
Esempio n. 28
0
File: tape.c Progetto: jchmrt/etbi
/**
 * Set the cell in TAPE at OFFSET from the current cell to VALUE.
 */
void
set_tape (tape *tape, int offset, char value)
{
  char *cell = cell_at (tape, offset);
  *cell = value;
}
Esempio n. 29
0
int execute_step (struct world *world, int display, int move_forward)
{
	struct position new_pos;
	struct cell *cell;
	int ret;
	enum ant_action action;
	int new_direction, direction;
	int new_marker;

	if (!world->cursor) {
		fprintf (stderr, "Internal error: cursor is NULL\n");
		return -1;
	}

	if (move_forward) {
		skip_round_markers (world, 1);

		if (!world->cursor->next) {
			fprintf (stderr, "Already at the end of simulation\n");
			return -1;
		}
	} else {
		if (!world->cursor->prev) {
			fprintf (stderr, "Already at the beginning of simulation\n");
			return -1;
		}
		world->cursor = world->cursor->prev;
		skip_round_markers (world, 0);

		if (!world->cursor->ant) {
			fprintf (stderr, "Already at the beginning of simulation (file starts with round marker)\n");
			world->round--;
			return -1;
		}
		world->step--;
	}

	if (!world->cursor) {
		fprintf (stderr, "Internal error: cursor is NULL\n");
		return -1;
	}

	cell = cell_at (world, &world->cursor->ant->pos);
	if (world->cursor->ant != cell->ant) {
		fprintf (stderr, "Error in internal data structure: Ant not at cell.\n");
		return -1;
	}

	if (move_forward) {
		world->cursor->old_ant_state = cell->ant->state;
		cell->ant->state = world->cursor->new_ant_state;
	} else {
		cell->ant->state = world->cursor->old_ant_state;
	}
		
	action = world->cursor->action;
	if (!move_forward) {
		if (world->cursor->action_had_no_side_effects) {
			if (warnings) {
				fprintf (stderr, "Stepping back an action without side effects.\n");
			}
			return 0;
		}	
		action=reverse_action[action];  
	}	

	switch (action) {
	case MOVE_FORWARD: 
	case MOVE_BACKWARD: 
		new_pos = world->cursor->ant->pos;
		direction = world->cursor->ant->direction;	
		if (action == MOVE_BACKWARD) direction+=3;
		position_move (&new_pos, direction);

		if ((ret = verify_ant_position (world, &new_pos)) != 0) {
			if (warnings) {
				fprintf (stderr, "Ant crashing into another ant or rock!\n");
			}
			if (move_forward) {
				world->cursor->action_had_no_side_effects = 1;	
			}
			break;  /* this is a valid condition. */
		}

		if (display) {
			if ((ret=v_move_ant (world->cursor->ant, &new_pos, world->cursor->ant->direction)) != 0) {
				return ret;
			}
		}
		cell->ant = NULL;
		if (!display) cell->ant_needs_update = 1;

		world->cursor->ant->pos = new_pos;
		cell = cell_at (world, &new_pos);
		cell->ant = world->cursor->ant;
		if (!display) cell->ant_needs_update = 1;

		if ((ret=handle_dead_ants_around (&new_pos))!=0) return ret;
		break;

	case TURN_LEFT: 
	case TURN_RIGHT:
		new_direction = world->cursor->ant->direction;

		if (action == TURN_RIGHT) {
			new_direction++;
		} else {
			new_direction--;
		}
		if (new_direction < 0) new_direction+=6;
		if (new_direction > 5) new_direction-=6;
		
		if (display) {
			if ((ret=v_move_ant (world->cursor->ant, &world->cursor->ant->pos, new_direction)) != 0) {
				return ret;
			}
		}
		world->cursor->ant->direction = new_direction; 
		if (!display) cell->ant_needs_update = 1;

		break;

	case PICKUP_FOOD: 
		if (world->cursor->ant->carries_food) {
			if (warnings) {
				fprintf (stderr, "Ant carriing food attempts to pick up food.\n");
			}
			if (move_forward) {
				world->cursor->action_had_no_side_effects = 1;	
			}
			break;
		}
		if (cell->food == 0) {
			if (warnings) {
				fprintf (stderr, "Ant attepmts to pick up food but there is none.\n");
			}
			if (move_forward) {
				world->cursor->action_had_no_side_effects = 1;	
			}
			world->cursor->action_had_no_side_effects = 1;	
			break;
		}
			
		if (display) {
			if ((ret=v_ant_picks_up_food (world->cursor->ant, cell->food, cell->food-1)) != 0) {
				return ret;
			}
		}
		cell->food--;
		if (!display) cell->food_needs_update = 1;
		world->cursor->ant->carries_food++;
		break;
			
	case DROP_FOOD: 
		if (!world->cursor->ant->carries_food) {
			if (warnings) {
				fprintf (stderr, "Ant carriing no food attempts to drop food.\n");
			}
			if (move_forward) {
				world->cursor->action_had_no_side_effects = 1;	
			}
			world->cursor->action_had_no_side_effects = 1;	
			break;
		}
		cell = cell_at (world, &world->cursor->ant->pos);
			
		if (display) {
			if ((ret=v_ant_drops_food (world->cursor->ant, cell->food, cell->food+1)) != 0) {
				return ret;
			}
		}
		cell->food++;
		if (!display) cell->food_needs_update = 1;

		world->cursor->ant->carries_food--;
		break;

	case SET_MARKER: 
	case CLEAR_MARKER: 
		new_marker = cell->markers[world->cursor->ant->colony];

		if (action == SET_MARKER) {
			new_marker |= (1<<world->cursor->marker);
		} else {
			new_marker &= ~(1<<world->cursor->marker);
		} 
			
		if (new_marker == cell->markers[world->cursor->ant->colony]) { 
			if (warnings) {
				fprintf (stderr, "Ant setting/clearing marker but it is already set/cleared.\n");
			}
			if (move_forward) {
				world->cursor->action_had_no_side_effects = 1;	
			}
			break;
		}

		if (display) {
			if ((ret=v_ant_changes_marker (world->cursor->ant, cell->markers[world->cursor->ant->colony], new_marker)) != 0) {
				return ret;
			}
		}
			
		cell->markers[world->cursor->ant->colony] = new_marker;
		if (!display) cell->markers_need_update = 1;

		break;

	default:
		fprintf (stderr, "Illegal ant action\n");
		return -1;
	}
			

	if (move_forward) {
		if (world->cursor->next) world->cursor = world->cursor->next;
		world->step++;
	}  /* when moving backwards this already has been done at the beginning. */ 
	return 0;
}
Esempio n. 30
0
File: tape.c Progetto: jchmrt/etbi
/**
 * Alter the cell in TAPE at OFFSET from the current cell by CHANGE
 * amount.
 */
void
alter_tape (tape *tape, int offset, char change)
{
  char *cell = cell_at (tape, offset);
  *cell += change;
}