1+ /*
2+ * BreakHack - A dungeone crawler RPG
3+ * Copyright (C) 2025 Linus Probert <linus.probert@gmail.com>
4+ *
5+ * This program is free software: you can redistribute it and/or modify
6+ * it under the terms of the GNU General Public License as published by
7+ * the Free Software Foundation, either version 3 of the License, or
8+ * (at your option) any later version.
9+ *
10+ * This program is distributed in the hope that it will be useful,
11+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+ * GNU General Public License for more details.
14+ *
15+ * You should have received a copy of the GNU General Public License
16+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
17+ */
18+
19+ #include <SDL3/SDL.h>
20+ #include "cmocka_include.h"
21+ #include "../src/roommatrix.h"
22+ #include "../src/defines.h"
23+
24+ typedef struct {
25+ SDL_Window * window ;
26+ SDL_Renderer * renderer ;
27+ RoomMatrix * rm ;
28+ } TestState ;
29+
30+ static int
31+ setup (void * * state )
32+ {
33+ SDL_SetHint (SDL_HINT_VIDEO_DRIVER , "offscreen" );
34+ SDL_SetHint (SDL_HINT_RENDER_DRIVER , "software" );
35+
36+ if (!SDL_Init (SDL_INIT_VIDEO ))
37+ return -1 ;
38+
39+ SDL_Window * window = SDL_CreateWindow ("test" , 1 , 1 , 0 );
40+ if (!window ) {
41+ SDL_Quit ();
42+ return -1 ;
43+ }
44+
45+ SDL_Renderer * renderer = SDL_CreateRenderer (window , NULL );
46+ if (!renderer ) {
47+ SDL_DestroyWindow (window );
48+ SDL_Quit ();
49+ return -1 ;
50+ }
51+
52+ TestState * s = malloc (sizeof (TestState ));
53+ s -> window = window ;
54+ s -> renderer = renderer ;
55+ s -> rm = roommatrix_create (renderer );
56+
57+ * state = s ;
58+ return 0 ;
59+ }
60+
61+ static int
62+ teardown (void * * state )
63+ {
64+ TestState * s = * state ;
65+ roommatrix_destroy (s -> rm );
66+ SDL_DestroyRenderer (s -> renderer );
67+ SDL_DestroyWindow (s -> window );
68+ SDL_Quit ();
69+ free (s );
70+ return 0 ;
71+ }
72+
73+ /* Center of the matrix, all spaces open: self + 8 neighbours = 9 */
74+ static void
75+ test_surrounding_all_open (void * * state )
76+ {
77+ RoomMatrix * rm = ((TestState * )* state )-> rm ;
78+
79+ Position center = POS (3 * TILE_DIMENSION , 3 * TILE_DIMENSION );
80+ Position out [9 ];
81+ size_t n = roommatrix_get_surrounding_spaces (rm , & center , out , 9 );
82+
83+ assert_int_equal (n , 9 );
84+ }
85+
86+ /* One occupied neighbour is excluded */
87+ static void
88+ test_surrounding_occupied_excluded (void * * state )
89+ {
90+ RoomMatrix * rm = ((TestState * )* state )-> rm ;
91+
92+ SPACE_SET_FLAG (& rm -> spaces [3 ][2 ], TILE_OCCUPIED );
93+
94+ Position center = POS (3 * TILE_DIMENSION , 3 * TILE_DIMENSION );
95+ Position out [9 ];
96+ size_t n = roommatrix_get_surrounding_spaces (rm , & center , out , 9 );
97+
98+ assert_int_equal (n , 8 );
99+
100+ SPACE_CLEAR_FLAG (& rm -> spaces [3 ][2 ], TILE_OCCUPIED );
101+ }
102+
103+ /* A lethal tile is also not walkable and must be excluded */
104+ static void
105+ test_surrounding_lethal_excluded (void * * state )
106+ {
107+ RoomMatrix * rm = ((TestState * )* state )-> rm ;
108+
109+ SPACE_SET_FLAG (& rm -> spaces [3 ][4 ], TILE_LETHAL );
110+
111+ Position center = POS (3 * TILE_DIMENSION , 3 * TILE_DIMENSION );
112+ Position out [9 ];
113+ size_t n = roommatrix_get_surrounding_spaces (rm , & center , out , 9 );
114+
115+ assert_int_equal (n , 8 );
116+
117+ SPACE_CLEAR_FLAG (& rm -> spaces [3 ][4 ], TILE_LETHAL );
118+ }
119+
120+ /* Corner (0,0): self + 3 in-bounds neighbours = 4 */
121+ static void
122+ test_surrounding_at_corner (void * * state )
123+ {
124+ RoomMatrix * rm = ((TestState * )* state )-> rm ;
125+
126+ Position corner = POS (0 , 0 );
127+ Position out [9 ];
128+ size_t n = roommatrix_get_surrounding_spaces (rm , & corner , out , 9 );
129+
130+ assert_int_equal (n , 4 );
131+ }
132+
133+ int
134+ main (void )
135+ {
136+ const struct CMUnitTest tests [] = {
137+ cmocka_unit_test_setup_teardown (test_surrounding_all_open , setup , teardown ),
138+ cmocka_unit_test_setup_teardown (test_surrounding_occupied_excluded , setup , teardown ),
139+ cmocka_unit_test_setup_teardown (test_surrounding_lethal_excluded , setup , teardown ),
140+ cmocka_unit_test_setup_teardown (test_surrounding_at_corner , setup , teardown ),
141+ };
142+
143+ return cmocka_run_group_tests (tests , NULL , NULL );
144+ }
0 commit comments