def test_get_elevation_empty_tile_and_not_on_map(self): elevations = {Point(0, 0): 1, Point(1, 0): 2, Point(0, 1): -1, } tiles = [Tile(point=point, elevation=elevation) for point, elevation in elevations.items()] map_ = Map(2, 2, tiles) self.assertEqual(map_.get_elevation(Point(1, 1)), float('-inf')) self.assertEqual(map_.get_elevation(Point(-1, -1)), float('-inf'))
def test_init_if_tiles_do_not_fill_points(self): tiles = get_tiles_without_points(3, 2) test_map = Map(3, 3, tiles) for point in Point(0, 0).to_rectangle(3, 2): self.assertIs(test_map.get_tile(point), tiles.pop(0)) for point in Point(0, 2).to_rectangle(3, 1): self.assertFalse(test_map.has_tile(point))
def test_init_pointed_tiles(self): width = 5 height = 3 tiles = get_tiles_with_points(width, height) test_map = Map(width, height, tiles) for point in Point(0, 0).to_rectangle(width, height): self.assertIs(test_map.get_tile(point), tiles.pop(0))
def test_get_elevation(self): elevations = {Point(0, 0): 1, Point(1, 0): 2, Point(0, 1): -1, Point(1, 1): 0} tiles = [Tile(point=point, elevation=elevation) for point, elevation in elevations.items()] map_ = Map(2, 2, tiles) self.assertEqual(map_.get_elevation(Point(0, 0)), 1) self.assertEqual(map_.get_elevation(Point(1, 0)), 2) self.assertEqual(map_.get_elevation(Point(0, 1)), -1) self.assertEqual(map_.get_elevation(Point(1, 1)), 0)
def test_init_mixed_tiles(self): width = 2 height = 2 tiles = [Tile(point=Point(0, 0)), Tile(), Tile(), Tile(point=Point(1, 1))] self.assertFalse(tiles[1].has_point()) test_map = Map(width, height, tiles) for tile in tiles: self.assertTrue(tile.has_point()) for point in Point(0, 0).to_rectangle(width, height): self.assertIs(test_map.get_tile(point), tiles.pop(0))
def test_get_movement_points_not_affected_by_unit_on_origin(self): map_ = Map(2, 2, [Tile() for _ in range(4)]) origin = Point(0, 0) map_.place_unit(Soldier(), origin) answer = MovementCalculator(map_).get_movement_points(origin, 100) expected = { Point(0, 0): 0, Point(0, 1): 1, Point(1, 0): 1, Point(1, 1): 2 } self.assertEqual(answer, expected)
def test_allies_in_range_melee_weapon(self): points_to_elevation = { Point(1, 0): -3, Point(0, 1): 4, Point(1, 1): 0, Point(2, 1): -4, Point(1, 2): 3 } tiles = [ Tile(elevation=elevation, point=point) for point, elevation in points_to_elevation.items() ] the_map = Map(3, 3, tiles) origin, below, above = self.a_units far_below = Soldier() far_above = Soldier() self.team_a.add_player(far_above) self.team_a.add_player(far_below) origin.equip_weapon(MeleeWeapon(10, 10, 10, 10)) the_map.place_unit(origin, Point(1, 1)) the_map.place_unit(below, Point(1, 0)) the_map.place_unit(above, Point(1, 2)) the_map.place_unit(far_above, Point(0, 1)) the_map.place_unit(far_below, Point(2, 1)) tf = TargetFinder(the_map, [self.team_a, self.team_b]) answer = tf.allies_in_range(origin) expected = {below: (1, 1), above: (1, -1)} self.assertEqual(answer, expected)
def setUp(self): self.map_length = 20 self.map = Map(self.map_length, self.map_length, [Tile() for _ in range(self.map_length**2)]) self.team_a = Team(Point(self.map_length - 1, 0), self.map) self.team_b = Team(Point(0, self.map_length - 1), self.map) team_size = 3 self.a_units = [Soldier() for _ in range(team_size)] self.b_units = [Soldier() for _ in range(team_size)] for a_unit, b_unit in zip(self.a_units, self.b_units): self.team_a.add_player(a_unit) self.team_b.add_player(b_unit)
def test_get_attackers(self): points_to_elevation = { Point(0, 0): 0, Point(1, 0): 5, Point(2, 0): 0, Point(0, 1): 1, Point(1, 1): 1, Point(2, 1): 2, Point(0, 2): 2, Point(1, 2): 3, Point(2, 2): 3 } tiles = [ Tile(elevation=elevation, point=point) for point, elevation in points_to_elevation.items() ] the_map = Map(3, 3, tiles) listener = PerimeterListener(the_map) melee_pt = Point(1, 1) ranged_pt = Point(0, 0) listener.set_perimeter(self.melee, melee_pt) listener.set_perimeter(self.ranged, ranged_pt) self.assertEqual(listener.get_attackers(Point(2, 2)), set()) self.assertEqual(listener.get_attackers(Point(0, 1)), {self.ranged, self.melee}) self.assertEqual(listener.get_attackers(Point(0, 2)), {self.ranged}) self.assertEqual(listener.get_attackers(Point(1, 2)), {self.melee})
def test_get_movement_points_non_uniform_terrain(self): terrain_mvs = { Point(0, 0): 1, Point(1, 0): 2, Point(0, 1): 4, Point(1, 1): 3 } tiles = [ Tile(point=point, terrain_mv=terrain) for point, terrain in terrain_mvs.items() ] map_ = Map(2, 2, tiles) origin = Point(0, 0) expected = { Point(0, 0): 0, Point(1, 0): 1, Point(0, 1): 1, Point(1, 1): 3 } self.assertEqual( MovementCalculator(map_).get_movement_points(origin, 5), expected) origin = Point(0, 1) expected = { Point(0, 0): 4, Point(1, 0): 5, Point(0, 1): 0, Point(1, 1): 4 } self.assertEqual( MovementCalculator(map_).get_movement_points(origin, 5), expected)
def test_is_obstacle_higher_than_start_y_axis_pos_direction_false(self): elevations = { Point(0, 0): 0, Point(1, 0): 2, Point(2, 0): 0, Point(0, 1): 0, Point(1, 1): 0, Point(2, 1): 0, Point(0, 2): 0, Point(1, 2): 2, Point(2, 2): 0, Point(0, 3): 0, Point(1, 3): 2, Point(2, 3): 0 } tiles = [ Tile(point=point, elevation=elevation) for point, elevation in elevations.items() ] map_ = Map(3, 4, tiles) sighting_tool = LineOfSight(map_) start = Point(1, 3) finish = Point(1, 0) self.assertFalse( sighting_tool.is_obstacle_higher_than_start(start, finish))
def test_can_sight_target_target_lower(self): elevations = { Point(0, 0): 4, Point(1, 0): 2, Point(2, 0): 0, Point(0, 1): 4, Point(1, 1): 5, Point(2, 1): 1, Point(0, 2): 1, Point(1, 2): 1, Point(2, 2): 4, Point(0, 3): 4, Point(1, 3): 1, Point(2, 3): 4 } tiles = [ Tile(point=point, elevation=elevation) for point, elevation in elevations.items() ] map_ = Map(3, 4, tiles) sighting_tool = LineOfSight(map_) target = Point(2, 0) shooter_miss_1 = Point(0, 1) shooter_miss_2 = Point(0, 3) shooter_hit_1 = Point(0, 0) shooter_hit_2 = Point(2, 3) self.assertFalse(sighting_tool.can_sight_target( target, shooter_miss_1)) self.assertFalse(sighting_tool.can_sight_target( target, shooter_miss_2)) self.assertTrue(sighting_tool.can_sight_target(target, shooter_hit_1)) self.assertTrue(sighting_tool.can_sight_target(target, shooter_hit_2))
def test_can_sight_target_missing_tile(self): elevations = { Point(0, 0): 1, Point(1, 0): 0, Point(2, 0): 0, Point(0, 1): 0, Point(1, 1): 3, Point(2, 1): 5, Point(1, 2): 1, Point(0, 3): 2, Point(1, 3): 0, Point(2, 3): 0 } tiles = [ Tile(point=point, elevation=elevation) for point, elevation in elevations.items() ] map_ = Map(3, 4, tiles) sighting_tool = LineOfSight(map_) target_true = Point(0, 0) shooter_true = Point(0, 3) self.assertTrue( sighting_tool.can_sight_target(target_true, shooter_true)) target_false = Point(2, 3) shooter_false = Point(2, 0) self.assertFalse( sighting_tool.can_sight_target(target_false, shooter_false))
def test_is_target_above_shooter_false(self): elevations = { Point(0, 0): 0, Point(1, 0): 2, Point(2, 0): 3, Point(0, 1): 0, Point(1, 1): 2, Point(2, 1): 0, Point(0, 2): 4, Point(1, 2): 3, Point(2, 2): 4, Point(0, 3): 0, Point(1, 3): 4, Point(2, 3): 0 } tiles = [ Tile(point=point, elevation=elevation) for point, elevation in elevations.items() ] map_ = Map(3, 4, tiles) sighting_tool = LineOfSight(map_) target_below = Point(1, 0) target_equal = Point(1, 2) shooter = Point(2, 0) self.assertFalse( sighting_tool.is_target_above_shooter(target_below, shooter)) self.assertFalse( sighting_tool.is_target_above_shooter(target_equal, shooter))
def test_init(self): tiles = [Tile() for _ in range(9)] the_map = Map(3, 3, tiles) team = Team(Point(0, 0), the_map) self.assertEqual(team.deployed, []) self.assertEqual(team.undeployed, []) self.assertEqual(team.home, Point(0, 0))
def test_rm_perimeter_one_unit(self): points_to_elevation = { Point(0, 0): 0, Point(1, 0): 5, Point(2, 0): 0, Point(0, 1): 1, Point(1, 1): 1, Point(2, 1): 2, Point(0, 2): 2, Point(1, 2): 3, Point(2, 2): 3 } tiles = [ Tile(elevation=elevation, point=point) for point, elevation in points_to_elevation.items() ] the_map = Map(3, 3, tiles) listener = PerimeterListener(the_map) melee_pt = Point(1, 1) listener.set_perimeter(self.melee, melee_pt) empty = {pt: set() for pt in points_to_elevation} non_empty = {pt: set() for pt in points_to_elevation} non_empty[Point(0, 1)] = {self.melee} non_empty[Point(2, 1)] = {self.melee} non_empty[Point(1, 2)] = {self.melee} self.assertEqual(listener._watchers_at_point, non_empty) listener.rm_perimeter(self.melee) self.assertEqual(listener._watchers_at_point, empty)
def test_get_movement_points_elevations_and_terrains(self): elevation_terrain = { Point(0, 0): (0, 3), Point(1, 0): (0, 4), Point(0, 1): (1, 5), Point(1, 1): (2, 6) } tiles = [ Tile(point=point, elevation=el_terrain[0], terrain_mv=el_terrain[1]) for point, el_terrain in elevation_terrain.items() ] map_ = Map(2, 2, tiles) origin = Point(0, 1) expected = { Point(0, 0): 5, Point(1, 0): 8, Point(0, 1): 0, Point(1, 1): 6 } self.assertEqual( MovementCalculator(map_).get_movement_points(origin, 10), expected) origin = Point(0, 0) expected = { Point(0, 0): 0, Point(1, 0): 3, Point(0, 1): 4, Point(1, 1): 9 } self.assertEqual( MovementCalculator(map_).get_movement_points(origin, 10), expected)
def test_is_obstacle_higher_than_start_slope_lt_neg_one_true(self): elevations = { Point(0, 0): 1, Point(1, 0): 0, Point(2, 0): 0, Point(0, 1): 0, Point(1, 1): 3, Point(2, 1): 0, Point(0, 2): 0, Point(1, 2): 1, Point(2, 2): 1, Point(0, 3): 2, Point(1, 3): 0, Point(2, 3): 0 } tiles = [ Tile(point=point, elevation=elevation) for point, elevation in elevations.items() ] map_ = Map(3, 4, tiles) sighting_tool = LineOfSight(map_) start = Point(0, 3) finish = Point(1, 0) self.assertTrue( sighting_tool.is_obstacle_higher_than_start(start, finish))
def test_set_perimeter_two_units(self): points_to_elevation = { Point(0, 0): 0, Point(1, 0): 5, Point(2, 0): 0, Point(0, 1): 1, Point(1, 1): 1, Point(2, 1): 2, Point(0, 2): 2, Point(1, 2): 3, Point(2, 2): 3 } tiles = [ Tile(elevation=elevation, point=point) for point, elevation in points_to_elevation.items() ] the_map = Map(3, 3, tiles) listener = PerimeterListener(the_map) melee_pt = Point(1, 1) ranged_pt = Point(0, 0) listener.set_perimeter(self.melee, melee_pt) listener.set_perimeter(self.ranged, ranged_pt) expected = {key: set() for key in points_to_elevation} expected[Point(0, 1)] = {self.ranged, self.melee} expected[Point(1, 0)] = {self.ranged} expected[Point(0, 2)] = {self.ranged} expected[Point(1, 1)] = {self.ranged} expected[Point(2, 1)] = {self.melee} expected[Point(1, 2)] = {self.melee} self.assertEqual(listener._watchers_at_point, expected)
def test_get_movement_points_with_path_chooses_smallest_move_pts_different_order( self): elevations = { Point(0, 0): 2, Point(1, 0): 0, Point(0, 1): 1, Point(1, 1): 0 } tiles = [ Tile(point=point, elevation=elevation) for point, elevation in elevations.items() ] map_ = Map(2, 2, tiles) origin = Point(0, 1) expected = { Point(0, 0): (2, [S]), Point(1, 0): (2, [E, S]), # point(1, 0) has two different ways from 0,1 Point(0, 1): (0, []), Point(1, 1): (1, [E]) } # one way costs 2 and one way costs 3 self.assertEqual( MovementCalculator(map_).get_movement_points_with_path(origin, 10), expected)
def test_get_movement_points_with_path_with_impassable_tile_in_place(self): elevations = { Point(0, 0): 2, Point(1, 0): 0, Point(2, 0): 3, Point(0, 1): 1, Point(1, 1): 9, Point(2, 1): 2, Point(0, 2): 2, Point(1, 2): 0, Point(2, 2): 1 } tiles = [ Tile(point=point, elevation=elevation) if elevation != 9 else ImpassableTile(point=point) for point, elevation in elevations.items() ] map_ = Map(3, 3, tiles) origin = Point(1, 2) expected = { Point(0, 0): (6, [W, S, S]), Point(1, 0): (7, [W, S, S, E]), Point(2, 0): (6, [E, S, S]), Point(0, 1): (4, [W, S]), Point(2, 1): (4, [E, S]), Point(0, 2): (3, [W]), Point(1, 2): (0, []), Point(2, 2): (2, [E]) } self.assertEqual( MovementCalculator(map_).get_movement_points_with_path(origin, 10), expected)
def test_get_movement_points_with_path_non_uniform_terrain(self): terrain_mvs = { Point(0, 0): 1, Point(1, 0): 2, Point(0, 1): 4, Point(1, 1): 3 } tiles = [ Tile(point=point, terrain_mv=terrain) for point, terrain in terrain_mvs.items() ] map_ = Map(2, 2, tiles) origin = Point(0, 0) expected = { Point(0, 0): (0, []), Point(1, 0): (1, [E]), Point(0, 1): (1, [N]), Point(1, 1): (3, [E, N]) } self.assertEqual( MovementCalculator(map_).get_movement_points_with_path(origin, 5), expected) origin = Point(0, 1) expected = { Point(0, 0): (4, [S]), Point(1, 0): (5, [S, E]), Point(0, 1): (0, []), Point(1, 1): (4, [E]) } self.assertEqual( MovementCalculator(map_).get_movement_points_with_path(origin, 5), expected)
def test_get_movement_points_with_path_only_to_max_mv(self): map_ = Map(3, 3, [Tile() for _ in range(9)]) answer = MovementCalculator(map_).get_movement_points_with_path( Point(0, 0), 1) expected = { Point(0, 0): (0, []), Point(0, 1): (1, [N]), Point(1, 0): (1, [E]) } self.assertEqual(answer, expected)
def test_get_movement_points_only_includes_distances_on_map(self): map_ = Map(2, 2, [Tile() for _ in range(4)]) answer = MovementCalculator(map_).get_movement_points(Point(0, 0), 100) expected = { Point(0, 0): 0, Point(0, 1): 1, Point(1, 0): 1, Point(1, 1): 2 } self.assertEqual(answer, expected)
def test_get_movement_points_with_path_obstacle_lte_max_mv_will_continue_around_corner( self): elevations = { Point(0, 0): 0, Point(1, 0): 0, Point(2, 0): 0, Point(3, 0): 0, Point(0, 1): 3, Point(1, 1): 4, Point(2, 1): 0, Point(3, 1): 0, Point(0, 2): 0, Point(1, 2): 0, Point(2, 2): 0, Point(3, 2): 0 } tiles = [ Tile(point=point, elevation=elevation) for point, elevation in elevations.items() ] map_ = Map(4, 3, tiles) origin = Point(1, 2) expected_four = { Point(1, 0): (4, [E, S, S, W]), Point(2, 0): (3, [E, S, S]), Point(3, 0): (4, [E, S, S, E]), Point(2, 1): (2, [E, S]), Point(3, 1): (3, [E, S, E]), Point(0, 2): (1, [W]), Point(1, 2): (0, []), Point(2, 2): (1, [E]), Point(3, 2): (2, [E, E]) } expected_five = { Point(0, 0): (5, [E, S, S, W, W]), Point(1, 0): (4, [E, S, S, W]), Point(2, 0): (3, [E, S, S]), Point(3, 0): (4, [E, S, S, E]), Point(0, 1): (5, [W, S]), Point(1, 1): (5, [S]), Point(2, 1): (2, [E, S]), Point(3, 1): (3, [E, S, E]), Point(0, 2): (1, [W]), Point(1, 2): (0, []), Point(2, 2): (1, [E]), Point(3, 2): (2, [E, E]) } ranger = MovementCalculator(map_) self.assertEqual(ranger.get_movement_points_with_path(origin, 5), expected_five) self.assertEqual(ranger.get_movement_points_with_path(origin, 4), expected_four)
def test_get_movement_points_with_path_obstacle_max_mv_lte_map_size(self): elevations = { Point(0, 0): 0, Point(1, 0): 0, Point(2, 0): 0, Point(3, 0): 0, Point(0, 1): 0, Point(1, 1): 9, Point(2, 1): 0, Point(3, 1): 0, Point(0, 2): 0, Point(1, 2): 0, Point(2, 2): 0, Point(3, 2): 0 } tiles = [ Tile(point=point, elevation=elevation) for point, elevation in elevations.items() ] map_ = Map(4, 3, tiles) origin = Point(1, 2) expected_four = { Point(0, 0): (3, [W, S, S]), Point(1, 0): (4, [W, S, S, E]), Point(2, 0): (3, [E, S, S]), Point(3, 0): (4, [E, S, S, E]), Point(0, 1): (2, [W, S]), Point(2, 1): (2, [E, S]), Point(3, 1): (3, [E, S, E]), Point(0, 2): (1, [W]), Point(1, 2): (0, []), Point(2, 2): (1, [E]), Point(3, 2): (2, [E, E]) } expected_three = { Point(0, 0): (3, [W, S, S]), Point(2, 0): (3, [E, S, S]), Point(0, 1): (2, [W, S]), Point(2, 1): (2, [E, S]), Point(3, 1): (3, [E, S, E]), Point(0, 2): (1, [W]), Point(1, 2): (0, []), Point(2, 2): (1, [E]), Point(3, 2): (2, [E, E]) } calculator = MovementCalculator(map_) # pretty_print(expected) # pretty_print(MovementCalculator(map_).get_movement_points_with_path(origin, 10)) self.assertEqual(calculator.get_movement_points_with_path(origin, 4), expected_four) self.assertEqual(calculator.get_movement_points_with_path(origin, 3), expected_three)
def test_get_movement_points_with_path_only_includes_distances_on_map( self): map_ = Map(2, 2, [Tile() for _ in range(4)]) answer = MovementCalculator(map_).get_movement_points_with_path( Point(0, 0), 100) expected = { Point(0, 0): (0, []), Point(0, 1): (1, [N]), Point(1, 0): (1, [E]), Point(1, 1): (2, [E, N]) } self.assertEqual(answer, expected)
def test_get_movement_points_obstacle_lte_max_mv_will_continue_around_corner( self): elevations = { Point(0, 0): 0, Point(1, 0): 0, Point(2, 0): 0, Point(3, 0): 0, Point(0, 1): 3, Point(1, 1): 4, Point(2, 1): 0, Point(3, 1): 0, Point(0, 2): 0, Point(1, 2): 0, Point(2, 2): 0, Point(3, 2): 0 } tiles = [ Tile(point=point, elevation=elevation) for point, elevation in elevations.items() ] map_ = Map(4, 3, tiles) origin = Point(1, 2) expected_four = { Point(1, 0): 4, Point(2, 0): 3, Point(3, 0): 4, Point(2, 1): 2, Point(3, 1): 3, Point(0, 2): 1, Point(1, 2): 0, Point(2, 2): 1, Point(3, 2): 2 } expected_five = { Point(0, 0): 5, Point(1, 0): 4, Point(2, 0): 3, Point(3, 0): 4, Point(0, 1): 5, Point(1, 1): 5, Point(2, 1): 2, Point(3, 1): 3, Point(0, 2): 1, Point(1, 2): 0, Point(2, 2): 1, Point(3, 2): 2 } ranger = MovementCalculator(map_) self.assertEqual(ranger.get_movement_points(origin, 5), expected_five) self.assertEqual(ranger.get_movement_points(origin, 4), expected_four)
def test_get_movement_points_with_path_non_uniform_elevation(self): points_to_elevation = { Point(0, 0): 0, Point(1, 0): 1, Point(2, 0): 2, Point(0, 1): 1, Point(1, 1): 2, Point(2, 1): 3, Point(0, 2): 2, Point(1, 2): 3, Point(2, 2): 4 } tiles = [ Tile(elevation=elevation, point=point) for point, elevation in points_to_elevation.items() ] the_map = Map(3, 3, tiles) origin_1 = Point(1, 1) expected_1 = { Point(0, 0): (2, [S, W]), Point(1, 0): (1, [S]), Point(2, 0): (3, [S, E]), Point(0, 1): (1, [W]), Point(1, 1): (0, []), Point(2, 1): (2, [E]), Point(0, 2): (3, [W, N]), Point(1, 2): (2, [N]), Point(2, 2): (4, [E, N]) } answer = MovementCalculator(the_map).get_movement_points_with_path( origin_1, 5) self.assertEqual(answer, expected_1) origin_2 = Point(2, 1) expected_2 = { Point(0, 0): (3, [S, W, W]), Point(1, 0): (2, [S, W]), Point(2, 0): (1, [S]), Point(0, 1): (2, [W, W]), Point(1, 1): (1, [W]), Point(2, 1): (0, []), Point(0, 2): (4, [W, W, N]), Point(1, 2): (3, [W, N]), Point(2, 2): (2, [N]) } answer = MovementCalculator(the_map).get_movement_points_with_path( origin_2, 5) self.assertEqual(expected_2, answer)
def test_get_movement_points_with_path_regression_test_two(self): elevations = { Point(0, 0): 0, Point(1, 0): 11, Point(2, 0): 0, Point(0, 1): 0, Point(1, 1): 11, Point(2, 1): 0, Point(0, 2): 0, Point(1, 2): 11, Point(2, 2): 0, Point(0, 3): 0, Point(1, 3): 11, Point(2, 3): 0, Point(0, 4): 0, Point(1, 4): 0, Point(2, 4): 0 } tiles = [ Tile(point=point, elevation=elevation * 10) for point, elevation in elevations.items() ] map_ = Map(3, 5, tiles) origin = Point(0, 0) expected = { Point(0, 0): (0, []), Point(0, 1): (1, [N]), Point(0, 2): (2, [N, N]), Point(0, 3): (3, [N, N, N]), Point(0, 4): (4, [N, N, N, N]), } self.assertEqual( MovementCalculator(map_).get_movement_points_with_path(origin, 4), expected) expected = { Point(0, 0): (0, []), Point(0, 1): (1, [N]), Point(0, 2): (2, [N, N]), Point(0, 3): (3, [N, N, N]), Point(0, 4): (4, [N, N, N, N]), Point(1, 4): (5, [N, N, N, N, E]), Point(2, 4): (6, [N, N, N, N, E, E]), Point(2, 3): (7, [N, N, N, N, E, E, S]), } self.assertEqual( MovementCalculator(map_).get_movement_points_with_path(origin, 7), expected)