add random spawn positions default tip

Thu, 21 Aug 2025 22:13:51 +0200

author
Mike Becker <universe@uap-core.de>
date
Thu, 21 Aug 2025 22:13:51 +0200
changeset 273
966bfca56b9d
parent 272
6ed9fb9662c0

add random spawn positions

demo/snake/Makefile file | annotate | diff | comparison | revisions
demo/snake/snake.c file | annotate | diff | comparison | revisions
src/ascension/util.h file | annotate | diff | comparison | revisions
src/util.c file | annotate | diff | comparison | revisions
--- a/demo/snake/Makefile	Wed Aug 20 23:51:40 2025 +0200
+++ b/demo/snake/Makefile	Thu Aug 21 22:13:51 2025 +0200
@@ -59,7 +59,7 @@
  ../../src/ascension/text.h ../../src/ascension/font.h \
  ../../src/ascension/mesh.h ../../src/ascension/texture.h \
  ../../src/ascension/sprite.h ../../src/ascension/2d.h \
- ../../src/ascension/shader.h
+ ../../src/ascension/shader.h ../../src/ascension/util.h
 	@echo "Compiling $<"
 	$(CC) -o $@ $(CFLAGS) -c $<
 
--- a/demo/snake/snake.c	Wed Aug 20 23:51:40 2025 +0200
+++ b/demo/snake/snake.c	Thu Aug 21 22:13:51 2025 +0200
@@ -30,6 +30,7 @@
 #include <ascension/sprite.h>
 #include <ascension/2d.h>
 #include <ascension/shader.h>
+#include <ascension/util.h>
 
 #include <cx/printf.h>
 #include <cx/linked_list.h>
@@ -368,7 +369,6 @@
     // remark: some calculations are repeated here, but they are cheap enough
     {
         const asc_vec2u tile_coords = game_field_tile_at_position(node->position);
-        // TODO: player should have been destroyed before leaving the field
         if (tile_coords.x > GAME_FIELD_SIZE || tile_coords.y > GAME_FIELD_SIZE) return;
         if (game_field_tile_chown(tile_coords, player)) {
             // new owner of the tile!
@@ -416,6 +416,15 @@
     pl->reset_position = true;
 }
 
+static void player_position_random(Player *pl) {
+    // TODO: check if the spawn location is viable when there is more action on the board
+    player_position(
+        pl,
+        4 + asc_util_rand(GAME_FIELD_SIZE - 8),
+        4 + asc_util_rand(GAME_FIELD_SIZE - 8)
+    );
+}
+
 static void player_destroy(CxAllocator *allocator, Player *player) {
     cxListFree(player->trace);
     cxFree(allocator, player);
@@ -435,7 +444,7 @@
     );
     asc_scene_add_node(MAIN_SCENE, node);
     Player *player = asc_scene_node_allocate_data(node, sizeof(Player));
-    player_position(player, 12, 8);
+    player_position_random(player);
     player->speed = 3.f; // start with 3 tiles/sec
     player->number = 1;
     player->health = 100;
@@ -572,7 +581,7 @@
             asc_scene_node_show(text_game_over);
             if (asc_key_pressed(ASC_KEY(R))) {
                 // TODO: re-load the "level"
-                player_position(game.players[0], 12, 8);
+                player_position_random(game.players[0]);
                 player_set_health(game.players[0], 100);
                 game.state = GAME_STATE_PLAYING;
                 asc_scene_node_hide(text_game_over);
--- a/src/ascension/util.h	Wed Aug 20 23:51:40 2025 +0200
+++ b/src/ascension/util.h	Thu Aug 21 22:13:51 2025 +0200
@@ -29,6 +29,7 @@
 #define ASC_UTIL_H
 
 #include <cx/string.h>
+#include <stdint.h>
 
 cxmutstr asc_util_gen_name(const char *prefix);
 
@@ -48,4 +49,22 @@
     int: asc_util_check_and_set_int, \
     unsigned: asc_util_check_and_set_unsigned)(&(v), x)
 
+/**
+ * Seeds or re-seeds the PRNG.
+ *
+ * @note You do not @em need to call this function before generating numbers,
+ * as the PRNG will be initialized automatically as if you had called asc_util_seed_rand(0).
+ *
+ * @param seed the seed or zero when some sort of clock time should be used as a seed
+ */
+void asc_util_seed_rand(uint64_t seed);
+
+/**
+ * Returns a positive number less than @p n from the PRNG.
+ *
+ * @param n the upper bound
+ * @return a positive number less than n
+ */
+uint32_t asc_util_rand(uint32_t n);
+
 #endif //ASC_UTIL_H
--- a/src/util.c	Wed Aug 20 23:51:40 2025 +0200
+++ b/src/util.c	Thu Aug 21 22:13:51 2025 +0200
@@ -28,10 +28,22 @@
 #include "ascension/util.h"
 
 #include <cx/printf.h>
-#include <inttypes.h>
-#include <assert.h>
+#include <SDL3/SDL_stdinc.h>
 
 cxmutstr asc_util_gen_name(const char *prefix) {
     static unsigned counter = 0;
     return cx_asprintf("%s_gen%u", prefix, ++counter);
 }
+
+void asc_util_seed_rand(uint64_t seed) {
+    SDL_srand(seed);
+}
+
+uint32_t asc_util_rand(uint32_t n) {
+    if (n > INT32_MAX) {
+        // TODO: this probably uses quality of the generated numbers
+        return SDL_rand_bits() % n;
+    } else {
+        return SDL_rand((int32_t) n);
+    }
+}

mercurial