#!/usr/bin/env python from typing import Any, Callable, Iterator, List, Optional, Tuple, Union import numpy import numpy as np import pytest import tcod import tcod as libtcodpy pytestmark = [ pytest.mark.filterwarnings("ignore::DeprecationWarning"), pytest.mark.filterwarnings("ignore::PendingDeprecationWarning"), ] def test_console_behavior(console: tcod.Console) -> None: assert not console @pytest.mark.skip("takes too long") @pytest.mark.filterwarnings("ignore") def test_credits_long(console: tcod.console.Console) -> None: libtcodpy.console_credits() def test_credits(console: tcod.console.Console) -> None: libtcodpy.console_credits_render(0, 0, True) libtcodpy.console_credits_reset() def assert_char( console: tcod.console.Console, x: int, y: int, ch: Optional[Union[str, int]] = None, fg: Optional[Tuple[int, int, int]] = None, bg: Optional[Tuple[int, int, int]] = None, ) -> None: if ch is not None: if isinstance(ch, str): ch = ord(ch) assert console.ch[y, x] == ch if fg is not None: assert (console.fg[y, x] == fg).all() if bg is not None: assert (console.bg[y, x] == bg).all() @pytest.mark.filterwarnings("ignore") def test_console_defaults(console: tcod.console.Console, fg: Tuple[int, int, int], bg: Tuple[int, int, int]) -> None: libtcodpy.console_set_default_foreground(console, fg) libtcodpy.console_set_default_background(console, bg) libtcodpy.console_clear(console) assert_char(console, 0, 0, None, fg, bg) @pytest.mark.filterwarnings("ignore") def test_console_set_char_background(console: tcod.console.Console, bg: Tuple[int, int, int]) -> None: libtcodpy.console_set_char_background(console, 0, 0, bg, libtcodpy.BKGND_SET) assert_char(console, 0, 0, bg=bg) @pytest.mark.filterwarnings("ignore") def test_console_set_char_foreground(console: tcod.console.Console, fg: Tuple[int, int, int]) -> None: libtcodpy.console_set_char_foreground(console, 0, 0, fg) assert_char(console, 0, 0, fg=fg) @pytest.mark.filterwarnings("ignore") def test_console_set_char(console: tcod.console.Console, ch: int) -> None: libtcodpy.console_set_char(console, 0, 0, ch) assert_char(console, 0, 0, ch=ch) @pytest.mark.filterwarnings("ignore") def test_console_put_char(console: tcod.console.Console, ch: int) -> None: libtcodpy.console_put_char(console, 0, 0, ch, libtcodpy.BKGND_SET) assert_char(console, 0, 0, ch=ch) @pytest.mark.filterwarnings("ignore") def console_put_char_ex( console: tcod.console.Console, ch: int, fg: Tuple[int, int, int], bg: Tuple[int, int, int] ) -> None: libtcodpy.console_put_char_ex(console, 0, 0, ch, fg, bg) assert_char(console, 0, 0, ch=ch, fg=fg, bg=bg) @pytest.mark.filterwarnings("ignore") def test_console_printing(console: tcod.console.Console, fg: Tuple[int, int, int], bg: Tuple[int, int, int]) -> None: libtcodpy.console_set_background_flag(console, libtcodpy.BKGND_SET) assert libtcodpy.console_get_background_flag(console) == libtcodpy.BKGND_SET libtcodpy.console_set_alignment(console, libtcodpy.LEFT) assert libtcodpy.console_get_alignment(console) == libtcodpy.LEFT libtcodpy.console_print(console, 0, 0, "print") libtcodpy.console_print_ex(console, 0, 0, libtcodpy.BKGND_SET, libtcodpy.LEFT, "print ex") assert libtcodpy.console_print_rect(console, 0, 0, 8, 8, "print rect") > 0 assert ( libtcodpy.console_print_rect_ex(console, 0, 0, 8, 8, libtcodpy.BKGND_SET, libtcodpy.LEFT, "print rect ex") > 0 ) assert libtcodpy.console_get_height_rect(console, 0, 0, 8, 8, "get height") > 0 libtcodpy.console_set_color_control(libtcodpy.COLCTRL_1, fg, bg) @pytest.mark.filterwarnings("ignore") def test_console_rect(console: tcod.console.Console) -> None: libtcodpy.console_rect(console, 0, 0, 4, 4, False, libtcodpy.BKGND_SET) @pytest.mark.filterwarnings("ignore") def test_console_lines(console: tcod.console.Console) -> None: libtcodpy.console_hline(console, 0, 0, 4) libtcodpy.console_vline(console, 0, 0, 4) @pytest.mark.filterwarnings("ignore") def test_console_print_frame(console: tcod.console.Console) -> None: libtcodpy.console_print_frame(console, 0, 0, 9, 9) @pytest.mark.filterwarnings("ignore") def test_console_fade(console: tcod.console.Console) -> None: libtcodpy.console_set_fade(0, (0, 0, 0)) libtcodpy.console_get_fade() libtcodpy.console_get_fading_color() def assertConsolesEqual(a: tcod.console.Console, b: tcod.console.Console) -> bool: return bool((a.fg[:] == b.fg[:]).all() and (a.bg[:] == b.bg[:]).all() and (a.ch[:] == b.ch[:]).all()) @pytest.mark.filterwarnings("ignore") def test_console_blit(console: tcod.console.Console, offscreen: tcod.console.Console) -> None: libtcodpy.console_print(offscreen, 0, 0, "test") libtcodpy.console_blit(offscreen, 0, 0, 0, 0, console, 0, 0, 1, 1) assertConsolesEqual(console, offscreen) libtcodpy.console_set_key_color(offscreen, (0, 0, 0)) @pytest.mark.filterwarnings("ignore") def test_console_asc_read_write(console: tcod.console.Console, offscreen: tcod.console.Console, tmpdir: Any) -> None: libtcodpy.console_print(console, 0, 0, "test") asc_file = tmpdir.join("test.asc").strpath assert libtcodpy.console_save_asc(console, asc_file) assert libtcodpy.console_load_asc(offscreen, asc_file) assertConsolesEqual(console, offscreen) @pytest.mark.filterwarnings("ignore") def test_console_apf_read_write(console: tcod.console.Console, offscreen: tcod.console.Console, tmpdir: Any) -> None: libtcodpy.console_print(console, 0, 0, "test") apf_file = tmpdir.join("test.apf").strpath assert libtcodpy.console_save_apf(console, apf_file) assert libtcodpy.console_load_apf(offscreen, apf_file) assertConsolesEqual(console, offscreen) @pytest.mark.filterwarnings("ignore") def test_console_rexpaint_load_test_file(console: tcod.console.Console) -> None: xp_console = libtcodpy.console_from_xp("libtcod/data/rexpaint/test.xp") assert xp_console assert libtcodpy.console_get_char(xp_console, 0, 0) == ord("T") assert libtcodpy.console_get_char(xp_console, 1, 0) == ord("e") assert libtcodpy.console_get_char_background(xp_console, 0, 1) == libtcodpy.Color(255, 0, 0) assert libtcodpy.console_get_char_background(xp_console, 1, 1) == libtcodpy.Color(0, 255, 0) assert libtcodpy.console_get_char_background(xp_console, 2, 1) == libtcodpy.Color(0, 0, 255) @pytest.mark.filterwarnings("ignore") def test_console_rexpaint_save_load( console: tcod.console.Console, tmpdir: Any, ch: int, fg: Tuple[int, int, int], bg: Tuple[int, int, int], ) -> None: libtcodpy.console_print(console, 0, 0, "test") libtcodpy.console_put_char_ex(console, 1, 1, ch, fg, bg) xp_file = tmpdir.join("test.xp").strpath assert libtcodpy.console_save_xp(console, xp_file, 1) xp_console = libtcodpy.console_from_xp(xp_file) assert xp_console assertConsolesEqual(console, xp_console) assert libtcodpy.console_load_xp(None, xp_file) # type: ignore assertConsolesEqual(console, xp_console) @pytest.mark.filterwarnings("ignore") def test_console_rexpaint_list_save_load(console: tcod.console.Console, tmpdir: Any) -> None: con1 = libtcodpy.console_new(8, 2) con2 = libtcodpy.console_new(8, 2) libtcodpy.console_print(con1, 0, 0, "hello") libtcodpy.console_print(con2, 0, 0, "world") xp_file = tmpdir.join("test.xp").strpath assert libtcodpy.console_list_save_xp([con1, con2], xp_file, 1) loaded_consoles = libtcodpy.console_list_load_xp(xp_file) assert loaded_consoles for a, b in zip([con1, con2], loaded_consoles): assertConsolesEqual(a, b) libtcodpy.console_delete(a) libtcodpy.console_delete(b) @pytest.mark.filterwarnings("ignore") def test_console_fullscreen(console: tcod.console.Console) -> None: libtcodpy.console_set_fullscreen(False) @pytest.mark.filterwarnings("ignore") def test_console_key_input(console: tcod.console.Console) -> None: libtcodpy.console_check_for_keypress() libtcodpy.console_is_key_pressed(libtcodpy.KEY_ENTER) @pytest.mark.filterwarnings("ignore") def test_console_fill_errors(console: tcod.console.Console) -> None: with pytest.raises(TypeError): libtcodpy.console_fill_background(console, [0], [], []) with pytest.raises(TypeError): libtcodpy.console_fill_foreground(console, [0], [], []) @pytest.mark.filterwarnings("ignore") def test_console_fill(console: tcod.console.Console) -> None: width = libtcodpy.console_get_width(console) height = libtcodpy.console_get_height(console) fill = [i % 256 for i in range(width * height)] libtcodpy.console_fill_background(console, fill, fill, fill) libtcodpy.console_fill_foreground(console, fill, fill, fill) libtcodpy.console_fill_char(console, fill) # verify fill bg, fg, ch = [], [], [] for y in range(height): for x in range(width): bg.append(libtcodpy.console_get_char_background(console, x, y)[0]) fg.append(libtcodpy.console_get_char_foreground(console, x, y)[0]) ch.append(libtcodpy.console_get_char(console, x, y)) assert fill == bg assert fill == fg assert fill == ch @pytest.mark.filterwarnings("ignore") def test_console_fill_numpy(console: tcod.console.Console) -> None: width = libtcodpy.console_get_width(console) height = libtcodpy.console_get_height(console) fill = numpy.zeros((height, width), dtype=numpy.intc) for y in range(height): fill[y, :] = y % 256 libtcodpy.console_fill_background(console, fill, fill, fill) # type: ignore libtcodpy.console_fill_foreground(console, fill, fill, fill) # type: ignore libtcodpy.console_fill_char(console, fill) # type: ignore # verify fill bg = numpy.zeros((height, width), dtype=numpy.intc) fg = numpy.zeros((height, width), dtype=numpy.intc) ch = numpy.zeros((height, width), dtype=numpy.intc) for y in range(height): for x in range(width): bg[y, x] = libtcodpy.console_get_char_background(console, x, y)[0] fg[y, x] = libtcodpy.console_get_char_foreground(console, x, y)[0] ch[y, x] = libtcodpy.console_get_char(console, x, y) fill = fill.tolist() assert fill == bg.tolist() assert fill == fg.tolist() assert fill == ch.tolist() @pytest.mark.filterwarnings("ignore") def test_console_buffer(console: tcod.console.Console) -> None: buffer = libtcodpy.ConsoleBuffer( libtcodpy.console_get_width(console), libtcodpy.console_get_height(console), ) buffer = buffer.copy() buffer.set_fore(0, 0, 0, 0, 0, "@") buffer.set_back(0, 0, 0, 0, 0) buffer.set(0, 0, 0, 0, 0, 0, 0, 0, "@") buffer.blit(console) @pytest.mark.filterwarnings("ignore:Console array attributes perform better") def test_console_buffer_error(console: tcod.console.Console) -> None: buffer = libtcodpy.ConsoleBuffer(0, 0) with pytest.raises(ValueError): buffer.blit(console) @pytest.mark.filterwarnings("ignore") def test_console_font_mapping(console: tcod.console.Console) -> None: libtcodpy.console_map_ascii_code_to_font(ord("@"), 1, 1) libtcodpy.console_map_ascii_codes_to_font(ord("@"), 1, 0, 0) libtcodpy.console_map_string_to_font("@", 0, 0) @pytest.mark.filterwarnings("ignore") def test_mouse(console: tcod.console.Console) -> None: libtcodpy.mouse_show_cursor(True) libtcodpy.mouse_is_cursor_visible() mouse = libtcodpy.mouse_get_status() repr(mouse) libtcodpy.mouse_move(0, 0) @pytest.mark.filterwarnings("ignore") def test_sys_time(console: tcod.console.Console) -> None: libtcodpy.sys_set_fps(0) libtcodpy.sys_get_fps() libtcodpy.sys_get_last_frame_length() libtcodpy.sys_sleep_milli(0) libtcodpy.sys_elapsed_milli() libtcodpy.sys_elapsed_seconds() @pytest.mark.filterwarnings("ignore") def test_sys_screenshot(console: tcod.console.Console, tmpdir: Any) -> None: libtcodpy.sys_save_screenshot(tmpdir.join("test.png").strpath) @pytest.mark.filterwarnings("ignore") def test_sys_custom_render(console: tcod.console.Console) -> None: if libtcodpy.sys_get_renderer() != libtcodpy.RENDERER_SDL: pytest.xfail(reason="Only supports SDL") escape = [] def sdl_callback(sdl_surface: Any) -> None: escape.append(True) libtcodpy.sys_register_SDL_renderer(sdl_callback) libtcodpy.console_flush() assert escape, "proof that sdl_callback was called" @pytest.mark.filterwarnings("ignore") def test_image(console: tcod.console.Console, tmpdir: Any) -> None: img = libtcodpy.image_new(16, 16) libtcodpy.image_clear(img, (0, 0, 0)) libtcodpy.image_invert(img) libtcodpy.image_hflip(img) libtcodpy.image_rotate90(img) libtcodpy.image_vflip(img) libtcodpy.image_scale(img, 24, 24) libtcodpy.image_set_key_color(img, (255, 255, 255)) libtcodpy.image_get_alpha(img, 0, 0) libtcodpy.image_is_pixel_transparent(img, 0, 0) libtcodpy.image_get_size(img) libtcodpy.image_get_pixel(img, 0, 0) libtcodpy.image_get_mipmap_pixel(img, 0, 0, 1, 1) libtcodpy.image_put_pixel(img, 0, 0, (255, 255, 255)) libtcodpy.image_blit(img, console, 0, 0, libtcodpy.BKGND_SET, 1, 1, 0) libtcodpy.image_blit_rect(img, console, 0, 0, 16, 16, libtcodpy.BKGND_SET) libtcodpy.image_blit_2x(img, console, 0, 0) libtcodpy.image_save(img, tmpdir.join("test.png").strpath) libtcodpy.image_delete(img) img = libtcodpy.image_from_console(console) libtcodpy.image_refresh_console(img, console) libtcodpy.image_delete(img) libtcodpy.image_delete(libtcodpy.image_load("libtcod/data/img/circle.png")) @pytest.mark.parametrize("sample", ["@", "\u2603"]) # Unicode snowman @pytest.mark.xfail(reason="Unreliable") @pytest.mark.filterwarnings("ignore") def test_clipboard(console: tcod.console.Console, sample: str) -> None: saved = libtcodpy.sys_clipboard_get() try: libtcodpy.sys_clipboard_set(sample) assert libtcodpy.sys_clipboard_get() == sample finally: libtcodpy.sys_clipboard_set(saved) # arguments to test with and the results expected from these arguments LINE_ARGS = (-5, 0, 5, 10) EXCLUSIVE_RESULTS = [(-4, 1), (-3, 2), (-2, 3), (-1, 4), (0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10)] INCLUSIVE_RESULTS = [(-5, 0)] + EXCLUSIVE_RESULTS @pytest.mark.filterwarnings("ignore") def test_line_step() -> None: """ libtcodpy.line_init and libtcodpy.line_step """ libtcodpy.line_init(*LINE_ARGS) for expected_xy in EXCLUSIVE_RESULTS: assert libtcodpy.line_step() == expected_xy assert libtcodpy.line_step() == (None, None) @pytest.mark.filterwarnings("ignore") def test_line() -> None: """ tests normal use, lazy evaluation, and error propagation """ # test normal results test_result: List[Tuple[int, int]] = [] def line_test(x: int, y: int) -> bool: test_result.append((x, y)) return True assert libtcodpy.line(*LINE_ARGS, py_callback=line_test) == 1 assert test_result == INCLUSIVE_RESULTS # test lazy evaluation test_result = [] def return_false(x: int, y: int) -> bool: test_result.append((x, y)) return False assert libtcodpy.line(*LINE_ARGS, py_callback=return_false) == 0 assert test_result == INCLUSIVE_RESULTS[:1] @pytest.mark.filterwarnings("ignore") def test_line_iter() -> None: """ libtcodpy.line_iter """ assert list(libtcodpy.line_iter(*LINE_ARGS)) == INCLUSIVE_RESULTS @pytest.mark.filterwarnings("ignore") def test_bsp() -> None: """ commented out statements work in libtcod-cffi """ bsp = libtcodpy.bsp_new_with_size(0, 0, 64, 64) repr(bsp) # test __repr__ on leaf libtcodpy.bsp_resize(bsp, 0, 0, 32, 32) assert bsp is not None # test getter/setters bsp.x = bsp.x bsp.y = bsp.y bsp.w = bsp.w bsp.h = bsp.h bsp.position = bsp.position bsp.horizontal = bsp.horizontal bsp.level = bsp.level # cover functions on leaf # self.assertFalse(libtcodpy.bsp_left(bsp)) # self.assertFalse(libtcodpy.bsp_right(bsp)) # self.assertFalse(libtcodpy.bsp_father(bsp)) assert libtcodpy.bsp_is_leaf(bsp) assert libtcodpy.bsp_contains(bsp, 1, 1) # self.assertFalse(libtcodpy.bsp_contains(bsp, -1, -1)) # self.assertEqual(libtcodpy.bsp_find_node(bsp, 1, 1), bsp) # self.assertFalse(libtcodpy.bsp_find_node(bsp, -1, -1)) libtcodpy.bsp_split_once(bsp, False, 4) repr(bsp) # test __repr__ with parent libtcodpy.bsp_split_once(bsp, True, 4) repr(bsp) # cover functions on parent assert libtcodpy.bsp_left(bsp) assert libtcodpy.bsp_right(bsp) # self.assertFalse(libtcodpy.bsp_father(bsp)) assert not libtcodpy.bsp_is_leaf(bsp) # self.assertEqual(libtcodpy.bsp_father(libtcodpy.bsp_left(bsp)), bsp) # self.assertEqual(libtcodpy.bsp_father(libtcodpy.bsp_right(bsp)), bsp) libtcodpy.bsp_split_recursive(bsp, None, 4, 2, 2, 1.0, 1.0) # cover bsp_traverse def traverse(node: tcod.bsp.BSP, user_data: Any) -> None: return None libtcodpy.bsp_traverse_pre_order(bsp, traverse) libtcodpy.bsp_traverse_in_order(bsp, traverse) libtcodpy.bsp_traverse_post_order(bsp, traverse) libtcodpy.bsp_traverse_level_order(bsp, traverse) libtcodpy.bsp_traverse_inverted_level_order(bsp, traverse) # test __repr__ on deleted node son = libtcodpy.bsp_left(bsp) libtcodpy.bsp_remove_sons(bsp) repr(son) libtcodpy.bsp_delete(bsp) @pytest.mark.filterwarnings("ignore") def test_map() -> None: map = libtcodpy.map_new(16, 16) assert libtcodpy.map_get_width(map) == 16 assert libtcodpy.map_get_height(map) == 16 libtcodpy.map_copy(map, map) libtcodpy.map_clear(map) libtcodpy.map_set_properties(map, 0, 0, True, True) assert libtcodpy.map_is_transparent(map, 0, 0) assert libtcodpy.map_is_walkable(map, 0, 0) libtcodpy.map_is_in_fov(map, 0, 0) libtcodpy.map_delete(map) @pytest.mark.filterwarnings("ignore") def test_color() -> None: color_a = libtcodpy.Color(0, 1, 2) assert list(color_a) == [0, 1, 2] assert color_a[0] == color_a.r assert color_a[1] == color_a.g assert color_a[2] == color_a.b color_a[1] = 3 color_a["b"] = color_a["b"] assert list(color_a) == [0, 3, 2] assert color_a == color_a color_b = libtcodpy.Color(255, 255, 255) assert color_a != color_b color = libtcodpy.color_lerp(color_a, color_b, 0.5) # type: ignore libtcodpy.color_set_hsv(color, 0, 0, 0) libtcodpy.color_get_hsv(color) # type: ignore libtcodpy.color_scale_HSV(color, 0, 0) def test_color_repr() -> None: Color = libtcodpy.Color col = Color(0, 1, 2) assert eval(repr(col)) == col @pytest.mark.filterwarnings("ignore") def test_color_math() -> None: color_a = libtcodpy.Color(0, 1, 2) color_b = libtcodpy.Color(0, 10, 20) assert color_a + color_b == libtcodpy.Color(0, 11, 22) assert color_b - color_a == libtcodpy.Color(0, 9, 18) assert libtcodpy.Color(255, 255, 255) * color_a == color_a assert color_a * 100 == libtcodpy.Color(0, 100, 200) @pytest.mark.filterwarnings("ignore") def test_color_gen_map() -> None: colors = libtcodpy.color_gen_map([(0, 0, 0), (255, 255, 255)], [0, 8]) assert colors[0] == libtcodpy.Color(0, 0, 0) assert colors[-1] == libtcodpy.Color(255, 255, 255) @pytest.mark.filterwarnings("ignore") def test_namegen_parse() -> None: libtcodpy.namegen_parse("libtcod/data/namegen/jice_celtic.cfg") assert libtcodpy.namegen_generate("Celtic female") assert libtcodpy.namegen_get_sets() libtcodpy.namegen_destroy() @pytest.mark.filterwarnings("ignore") def test_noise() -> None: noise = libtcodpy.noise_new(1) libtcodpy.noise_set_type(noise, libtcodpy.NOISE_SIMPLEX) libtcodpy.noise_get(noise, [0]) libtcodpy.noise_get_fbm(noise, [0], 4) libtcodpy.noise_get_turbulence(noise, [0], 4) libtcodpy.noise_delete(noise) @pytest.mark.filterwarnings("ignore") def test_random() -> None: rand = libtcodpy.random_get_instance() rand = libtcodpy.random_new() libtcodpy.random_delete(rand) rand = libtcodpy.random_new_from_seed(42) libtcodpy.random_set_distribution(rand, libtcodpy.DISTRIBUTION_LINEAR) libtcodpy.random_get_int(rand, 0, 1) libtcodpy.random_get_int_mean(rand, 0, 1, 0) libtcodpy.random_get_float(rand, 0, 1) libtcodpy.random_get_double(rand, 0, 1) libtcodpy.random_get_float_mean(rand, 0, 1, 0) libtcodpy.random_get_double_mean(rand, 0, 1, 0) backup = libtcodpy.random_save(rand) libtcodpy.random_restore(rand, backup) libtcodpy.random_delete(rand) libtcodpy.random_delete(backup) @pytest.mark.filterwarnings("ignore") def test_heightmap() -> None: h_map = libtcodpy.heightmap_new(16, 16) repr(h_map) noise = libtcodpy.noise_new(2) # basic operations libtcodpy.heightmap_set_value(h_map, 0, 0, 1) libtcodpy.heightmap_add(h_map, 1) libtcodpy.heightmap_scale(h_map, 1) libtcodpy.heightmap_clear(h_map) libtcodpy.heightmap_clamp(h_map, 0, 0) libtcodpy.heightmap_copy(h_map, h_map) libtcodpy.heightmap_normalize(h_map) libtcodpy.heightmap_lerp_hm(h_map, h_map, h_map, 0) libtcodpy.heightmap_add_hm(h_map, h_map, h_map) libtcodpy.heightmap_multiply_hm(h_map, h_map, h_map) # modifying the heightmap libtcodpy.heightmap_add_hill(h_map, 0, 0, 4, 1) libtcodpy.heightmap_dig_hill(h_map, 0, 0, 4, 1) libtcodpy.heightmap_rain_erosion(h_map, 1, 1, 1) libtcodpy.heightmap_kernel_transform(h_map, 3, [-1, 1, 0], [0, 0, 0], [0.33, 0.33, 0.33], 0, 1) libtcodpy.heightmap_add_voronoi(h_map, 10, 3, [1, 3, 5]) libtcodpy.heightmap_add_fbm(h_map, noise, 1, 1, 1, 1, 4, 1, 1) libtcodpy.heightmap_scale_fbm(h_map, noise, 1, 1, 1, 1, 4, 1, 1) libtcodpy.heightmap_dig_bezier(h_map, (0, 16, 16, 0), (0, 0, 16, 16), 1, 1, 1, 1) # read data libtcodpy.heightmap_get_value(h_map, 0, 0) libtcodpy.heightmap_get_interpolated_value(h_map, 0, 0) libtcodpy.heightmap_get_slope(h_map, 0, 0) libtcodpy.heightmap_get_normal(h_map, 0, 0, 0) libtcodpy.heightmap_count_cells(h_map, 0, 0) libtcodpy.heightmap_has_land_on_border(h_map, 0) libtcodpy.heightmap_get_minmax(h_map) libtcodpy.noise_delete(noise) libtcodpy.heightmap_delete(h_map) MAP = np.array( [ list(line) for line in ( "############", "# ### #", "# ### #", "# ### ####", "## #### # ##", "## ####", "############", ) ] ) MAP_HEIGHT, MAP_WIDTH = MAP.shape POINT_A = (2, 2) POINT_B = (9, 2) POINT_C = (9, 4) POINTS_AB = POINT_A + POINT_B # valid path POINTS_AC = POINT_A + POINT_C # invalid path @pytest.fixture() def map_() -> Iterator[tcod.map.Map]: map_ = tcod.map.Map(MAP_WIDTH, MAP_HEIGHT) map_.walkable[...] = map_.transparent[...] = MAP[...] == " " yield map_ libtcodpy.map_delete(map_) @pytest.fixture() def path_callback(map_: tcod.map.Map) -> Callable[[int, int, int, int, None], bool]: def callback(ox: int, oy: int, dx: int, dy: int, user_data: None) -> bool: if map_.walkable[dy, dx]: return True return False return callback @pytest.mark.filterwarnings("ignore") def test_map_fov(map_: tcod.map.Map) -> None: libtcodpy.map_compute_fov(map_, *POINT_A) @pytest.mark.filterwarnings("ignore") def test_astar(map_: tcod.map.Map) -> None: astar = libtcodpy.path_new_using_map(map_) assert not libtcodpy.path_compute(astar, *POINTS_AC) assert libtcodpy.path_size(astar) == 0 assert libtcodpy.path_compute(astar, *POINTS_AB) assert libtcodpy.path_get_origin(astar) == POINT_A assert libtcodpy.path_get_destination(astar) == POINT_B libtcodpy.path_reverse(astar) assert libtcodpy.path_get_origin(astar) == POINT_B assert libtcodpy.path_get_destination(astar) == POINT_A assert libtcodpy.path_size(astar) != 0 assert libtcodpy.path_size(astar) > 0 assert not libtcodpy.path_is_empty(astar) x: Optional[int] y: Optional[int] for i in range(libtcodpy.path_size(astar)): x, y = libtcodpy.path_get(astar, i) while (x, y) != (None, None): x, y = libtcodpy.path_walk(astar, False) libtcodpy.path_delete(astar) @pytest.mark.filterwarnings("ignore") def test_astar_callback(map_: tcod.map.Map, path_callback: Callable[[int, int, int, int, Any], bool]) -> None: astar = libtcodpy.path_new_using_function( libtcodpy.map_get_width(map_), libtcodpy.map_get_height(map_), path_callback, ) libtcodpy.path_compute(astar, *POINTS_AB) libtcodpy.path_delete(astar) @pytest.mark.filterwarnings("ignore") def test_dijkstra(map_: tcod.map.Map) -> None: path = libtcodpy.dijkstra_new(map_) libtcodpy.dijkstra_compute(path, *POINT_A) assert not libtcodpy.dijkstra_path_set(path, *POINT_C) assert libtcodpy.dijkstra_get_distance(path, *POINT_C) == -1 assert libtcodpy.dijkstra_path_set(path, *POINT_B) assert libtcodpy.dijkstra_size(path) assert not libtcodpy.dijkstra_is_empty(path) libtcodpy.dijkstra_reverse(path) x: Optional[int] y: Optional[int] for i in range(libtcodpy.dijkstra_size(path)): x, y = libtcodpy.dijkstra_get(path, i) while (x, y) != (None, None): x, y = libtcodpy.dijkstra_path_walk(path) libtcodpy.dijkstra_delete(path) @pytest.mark.filterwarnings("ignore") def test_dijkstra_callback(map_: tcod.map.Map, path_callback: Callable[[int, int, int, int, Any], bool]) -> None: path = libtcodpy.dijkstra_new_using_function( libtcodpy.map_get_width(map_), libtcodpy.map_get_height(map_), path_callback, ) libtcodpy.dijkstra_compute(path, *POINT_A) libtcodpy.dijkstra_delete(path) @pytest.mark.filterwarnings("ignore") def test_alpha_blend(console: tcod.console.Console) -> None: for i in range(256): libtcodpy.console_put_char(console, 0, 0, "x", libtcodpy.BKGND_ALPHA(i)) libtcodpy.console_put_char(console, 0, 0, "x", libtcodpy.BKGND_ADDALPHA(i)) if __name__ == "__main__": pytest.main()