Esempio n. 1
0
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);
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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);
}
Esempio n. 5
0
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++;
	}
}
Esempio n. 6
0
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);
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
int random_int_range_wrapper(int *min, int *max)
  {
  return random_int_range(*min, *max);
  }