static void teleport_object (Object *object) { Game *game = object->game; void *dummy; do { object->x = random_int_range (game->universe_width * CELL_SIZE); object->y = random_int_range (game->universe_height * CELL_SIZE); } while (get_occupancy (game, object->x, object->y, &dummy) != OCC_EMPTY); }
ha_sharded_cluster_t * ha_sharded_cluster_new (const char *name) { ha_sharded_cluster_t *cluster; cluster = bson_malloc0(sizeof *cluster); cluster->next_port = random_int_range(40000, 41000); cluster->name = bson_strdup(name); return cluster; }
ha_replica_set_t * ha_replica_set_new (const char *name) { ha_replica_set_t *repl_set; repl_set = bson_malloc0(sizeof *repl_set); repl_set->name = bson_strdup(name); repl_set->next_port = random_int_range(30000, 40000); return repl_set; }
unsigned short Dice::roll() const { int total = random_int_range(die_count, (die_count * die_type)+1); //cout << "dice_type: " <<die_type << ", die_count: " << die_count << "\n"; total += plus_damage; if (total < 0) return 0; else return static_cast<unsigned short>(total); }
void clist_shuffle(clist *l) { unsigned int len = (int32_t)clist_length(l); unsigned int idx = 0; clist *tmp = l; while (tmp) { unsigned int ridx = random_int_range(0, len - 1); if (ridx != idx) { clist *swap = clist_nth(l, ridx); void *tmp_data = tmp->data; void *swap_data = swap->data; tmp->data = swap_data; swap->data = tmp_data; } tmp = tmp->next; idx++; } }
static void game_update_timer_callback (Game *game) { /* run players */ Object *object; for (object = game->objects[OBJECT_TYPE_USER]; object != NULL; ) { User *user = (User *) object; dsk_boolean destroy_user = DSK_FALSE; if (user->dead_count > 0) { user->dead_count -= 1; if (user->dead_count == 0) { teleport_object (&user->base); add_object_to_cell_list (object); } object = object->next_in_game; continue; } if (user->move_x || user->move_y) { int new_x = object->x + user->move_x; int new_y = object->y + user->move_y; void *obj; if (game->wrap) { new_x = mod (new_x, game->universe_width * CELL_SIZE); new_y = mod (new_y, game->universe_height * CELL_SIZE); } switch (get_occupancy (game, new_x, new_y, &obj)) { case OCC_EMPTY: move_object (object, new_x, new_y); break; case OCC_WALL: case OCC_USER: /* move blocked harmlessly */ break; case OCC_ENEMY: destroy_user = DSK_TRUE; break; case OCC_BULLET: destroy_user = DSK_TRUE; remove_object_from_cell_list (obj); remove_object_from_game_list (obj); break; case OCC_GENERATOR: destroy_user = DSK_TRUE; break; } } if (user->bullet_block > 0) user->bullet_block--; else if (user->bullet_x || user->bullet_y) { /* create bullet */ Bullet *bullet = dsk_malloc (sizeof (Bullet)); bullet->base.type = OBJECT_TYPE_BULLET; bullet->base.game = game; /* create bullet on top of the user, we'll move it in the next loop */ bullet->base.x = user->base.x; bullet->base.y = user->base.y; add_object_to_cell_list (&bullet->base); add_object_to_game_list (&bullet->base); bullet->move_x = user->bullet_x; bullet->move_y = user->bullet_y; user->bullet_block = BULLET_BLOCK_PERIOD; } if (destroy_user) { remove_object_from_cell_list (object); user->dead_count = DEAD_TIME; } object = object->next_in_game; } /* update bullets, kill stuff */ { unsigned bi; for (bi = 0; bi < BULLET_SPEED; bi++) { for (object = game->objects[OBJECT_TYPE_BULLET]; object != NULL; ) { Bullet *bullet = (Bullet *) object; int new_x, new_y; dsk_boolean destroy_bullet; retry: new_x = object->x + bullet->move_x; new_y = object->y + bullet->move_y; if (game->wrap) { new_x = mod (new_x, game->universe_width * CELL_SIZE); new_y = mod (new_y, game->universe_height * CELL_SIZE); } destroy_bullet = DSK_TRUE; void *obj; switch (get_occupancy (game, new_x, new_y, &obj)) { case OCC_EMPTY: move_object (object, new_x, new_y); destroy_bullet = DSK_FALSE; break; case OCC_WALL: if (bullet->move_x && bullet->move_y && game->diag_bullets_bounce) { void *dummy; dsk_boolean xflip = get_occupancy (game, new_x, object->y, &dummy) == OCC_WALL; dsk_boolean yflip = get_occupancy (game, object->x, new_y, &dummy) == OCC_WALL; if (!xflip && !yflip) xflip = yflip = DSK_TRUE; if (xflip) bullet->move_x = -bullet->move_x; if (yflip) bullet->move_y = -bullet->move_y; goto retry; } break; case OCC_USER: if (game->bullet_kills_player) { /* user dies */ User *user = obj; remove_object_from_cell_list (obj); user->dead_count = DEAD_TIME; } break; case OCC_ENEMY: /* destroy enemy */ remove_object_from_cell_list (obj); remove_object_from_game_list (obj); dsk_free (obj); break; case OCC_BULLET: /* destroy other bullet */ remove_object_from_cell_list (obj); remove_object_from_game_list (obj); dsk_free (obj); break; case OCC_GENERATOR: if (game->bullet_kills_generator) { Generator *gen = obj; Cell *cell = game->cells + (gen->x/CELL_SIZE) + (gen->y/CELL_SIZE) * game->universe_width; dsk_assert (cell->generator == gen); cell->generator = NULL; /* remove generator from list */ if (gen->prev_in_game) gen->prev_in_game->next_in_game = gen->next_in_game; else game->generators = gen->next_in_game; if (gen->next_in_game) gen->next_in_game->prev_in_game = gen->prev_in_game; cell->generator = NULL; dsk_free (gen); } break; } if (destroy_bullet) { Object *next = object->next_in_game; remove_object_from_cell_list (object); remove_object_from_game_list (object); dsk_free (bullet); object = next; } else object = object->next_in_game; } } } /* update enemies */ for (object = game->objects[OBJECT_TYPE_ENEMY]; object != NULL; ) { //Enemy *enemy = (Enemy *) object; int new_x, new_y; new_x = object->x; new_y = object->y; if (random_double () < ENEMY_MOVE_FRACTION) { new_x += random_int_range (3) - 1; new_y += random_int_range (3) - 1; } if (game->wrap) { new_x = mod (new_x, game->universe_width * CELL_SIZE); new_y = mod (new_y, game->universe_height * CELL_SIZE); } dsk_boolean destroy_enemy = DSK_FALSE; void *obj; switch (get_occupancy (game, new_x, new_y, &obj)) { case OCC_EMPTY: move_object (object, new_x, new_y); break; case OCC_WALL: break; case OCC_USER: /* enemy kills user */ remove_object_from_game_list (obj); remove_object_from_cell_list (obj); ((User*)obj)->dead_count = DEAD_TIME; break; case OCC_ENEMY: /* move suppressed */ break; case OCC_BULLET: /* destroy bullet */ remove_object_from_cell_list (obj); remove_object_from_game_list (obj); dsk_free (obj); destroy_enemy = DSK_TRUE; break; case OCC_GENERATOR: break; } if (destroy_enemy) { Object *next = object->next_in_game; remove_object_from_cell_list (object); remove_object_from_game_list (object); dsk_free (object); object = next; } else object = object->next_in_game; } /* run generators */ Generator *gen; for (gen = game->generators; gen; gen = gen->next_in_game) { if (random_double () < gen->generator_prob) { /* try generating enemy */ int positions[12][2] = { {-1,-1}, {-1,0}, {-1,1}, {-1,2}, {0,2}, {1,2}, {2,2}, {2,1}, {2,0}, {2,-1}, {1,-1}, {0,-1} }; unsigned p = random_int_range (12); int dx = positions[p][0]; int dy = positions[p][1]; unsigned x = gen->x + dx; unsigned y = gen->y + dy; void *dummy; if (get_occupancy (game, x, y, &dummy) == OCC_EMPTY) { /* create enemy */ Enemy *enemy = dsk_malloc (sizeof (Enemy)); enemy->base.type = OBJECT_TYPE_ENEMY; enemy->base.x = x; enemy->base.y = y; enemy->base.game = game; add_object_to_cell_list (&enemy->base); add_object_to_game_list (&enemy->base); } } } /* finish any requests that were waiting for a new frame */ while (game->pending_updates != NULL) { DskJsonValue *state_json; PendingUpdate *pu = game->pending_updates; game->pending_updates = pu->next; state_json = create_user_update (pu->user); respond_take_json (pu->request, state_json); dsk_free (pu); } game->latest_update += 1; game->timer = dsk_main_add_timer_millis (update_period_msecs, (DskTimerFunc) game_update_timer_callback, game); }
static Game * create_game (const char *name, unsigned width, unsigned height) { Game *game = dsk_malloc (sizeof (Game)); unsigned usize; unsigned i; game->name = dsk_strdup (name); game->next_game = all_games; all_games = game; game->universe_width = width; game->universe_height = height; usize = width * height; game->h_walls = generate_ones (usize); game->v_walls = generate_ones (usize); for (i = 0; i < N_OBJECT_TYPES; i++) game->objects[i] = NULL; game->generators = NULL; game->cells = dsk_malloc0 (sizeof (Cell) * width * height); game->latest_update = 0; game->wrap = DSK_TRUE; game->diag_bullets_bounce = DSK_TRUE; game->bullet_kills_player = DSK_TRUE; game->bullet_kills_generator = DSK_TRUE; game->pending_updates = NULL; /* Generate with Modified Kruskals Algorithm, see * http://en.wikipedia.org/wiki/Maze_generation_algorithm */ TmpWall *tmp_walls = dsk_malloc (sizeof (TmpWall) * usize * 2); TmpSetInfo *sets = dsk_malloc (sizeof (TmpSetInfo) * usize); /* connect the walls together in random order */ unsigned *scramble; scramble = dsk_malloc (sizeof (unsigned) * usize * 2); for (i = 0; i < usize * 2; i++) scramble[i] = i; for (i = 0; i < usize * 2; i++) swap_ints (scramble + random_int_range (usize * 2), scramble + random_int_range (usize * 2)); TmpWall *wall_list = NULL; for (i = 0; i < usize * 2; i++) { unsigned e = scramble[i]; unsigned h = e % 2; unsigned x = (e / 2) % width; unsigned y = e / (width * 2); if (!game->wrap) { if ((h && y == 0) || (!h && x == 0)) continue; } tmp_walls[e].prev = NULL; tmp_walls[e].next = wall_list; if (wall_list) wall_list->prev = tmp_walls + e; wall_list = tmp_walls + e; } for (i = 0; i < usize; i++) { sets[i].set_number = i; sets[i].next_in_set = sets + i; } while (wall_list != NULL) { /* Invariants: - the sets are in a ring by set number. - The wall_list only consists of walls that separate distinct sets. */ /* remove wall */ unsigned e = wall_list - tmp_walls; unsigned h = e % 2; unsigned x = (e / 2) % width; unsigned y = e / (width * 2); TmpSetInfo *si = sets + e / 2; TmpSetInfo *osi; if (h) { if (y == 0) osi = si + (height - 1) * width; else osi = si - width; game->h_walls[x + y * width] = 0; } else { if (x == 0) osi = si + width - 1; else osi = si - 1; game->v_walls[x + y * width] = 0; } dsk_assert (osi->set_number != si->set_number); TmpSetInfo *kring = osi->set_number < si->set_number ? osi : si; /* ring to keep */ TmpSetInfo *dring = osi->set_number < si->set_number ? si : osi; /* ring to change */ TmpSetInfo *dring_start = dring; /* combine sets (removing any walls that no longer separate different sets from the list of walls to remove) */ unsigned set = kring->set_number; do { unsigned x = (dring - sets) % width; unsigned y = (dring - sets) / width; int wall_idx; dring->set_number = set; #if 0 if (wall_list) { dsk_assert (wall_list->prev == NULL); TmpWall *t; for (t = wall_list; t; t = t->next) if (t->next) dsk_assert (t->next->prev == t); } #endif /* Maybe remove left wall from candidate set of walls. */ wall_idx = -1; if (x > 0 && (dring-1)->set_number == set) wall_idx = 2 * (x + y * width); else if (x == 0 && game->wrap && (dring+width-1)->set_number == set) wall_idx = 2 * (x + y * width); if (wall_idx >= 0) remove_tmp_wall (tmp_walls, wall_idx, &wall_list); /* Maybe remove right wall from candidate set of walls. */ wall_idx = -1; if (x < width - 1 && (dring+1)->set_number == set) wall_idx = 2 * ((x+1) + y * width); else if (x == width - 1 && game->wrap && (dring-width+1)->set_number == set) wall_idx = 2 * (0 + y * width); if (wall_idx >= 0) remove_tmp_wall (tmp_walls, wall_idx, &wall_list); /* Maybe remove top wall from candidate set of walls. */ wall_idx = -1; if (y > 0 && (dring-width)->set_number == dring->set_number) wall_idx = 2 * (x + y * width) + 1; else if (y == 0 && game->wrap && (dring+width*(height-1))->set_number == set) wall_idx = 2 * (x + y * width) + 1; if (wall_idx >= 0) remove_tmp_wall (tmp_walls, wall_idx, &wall_list); /* Maybe remove bottom wall from candidate set of walls. */ wall_idx = -1; if (y < height - 1 && (dring+width)->set_number == set) wall_idx = 2 * (x + (y+1) * width) + 1; else if (y == height - 1 && game->wrap && (dring-(height-1)*width)->set_number == set) wall_idx = 2 * (x + 0 * width) + 1; if (wall_idx >= 0) remove_tmp_wall (tmp_walls, wall_idx, &wall_list); dring = dring->next_in_set; } while (dring != dring_start); /* Merge the rings */ TmpSetInfo *old_dring_next = dring->next_in_set; dring->next_in_set = kring->next_in_set; kring->next_in_set = old_dring_next; } dsk_free (tmp_walls); dsk_free (sets); dsk_free (scramble); /* generate generators */ unsigned n_generators = 12 + rand () % 6; dsk_warning ("%u generators", n_generators); i = 0; while (i < n_generators) { unsigned idx = random_int_range (usize); Cell *cell = game->cells + idx; if (cell->generator == NULL) { cell->generator = dsk_malloc (sizeof (Generator)); cell->generator->game = game; cell->generator->x = (idx % width) * CELL_SIZE + CELL_SIZE/2; cell->generator->y = (idx / width) * CELL_SIZE + CELL_SIZE/2; dsk_warning ("created generator at %u,%u",cell->generator->x ,cell->generator->y); cell->generator->generator_prob = 0.01; cell->generator->next_in_game = game->generators; cell->generator->prev_in_game = NULL; if (game->generators) game->generators->prev_in_game = cell->generator; game->generators = cell->generator; i++; } } game->timer = dsk_main_add_timer_millis (update_period_msecs, (DskTimerFunc) game_update_timer_callback, game); return game; }
int random_int_range_wrapper(int *min, int *max) { return random_int_range(*min, *max); }