def parseBoard(name: str) -> GameBoard: bData = TMPL_BOARDS[name] shape = tuple(bData['shape']) board = GameBoard(shape, name) terrain = np.full(shape, TERRAIN_TYPE[bData['default']].level, dtype='uint8') for tName, tData in bData['terrain'].items(): level = TERRAIN_TYPE[tName].level for elem in tData: if 'line' in elem: e = elem['line'] fillLine(terrain, (e[0], e[1]), (e[2], e[3]), level) if 'region' in elem: start, end = elem['region'].split(',') terrain[parse_slice(start), parse_slice(end)] = level if 'row_alternate' in elem: low, high = elem['row_alternate'] for i in range(board.shape[0]): j = low if i % 2 == 0 else high terrain[i, j] = level board.addTerrain(terrain) return board
def testMoveOnRoad(self): shape = (1, 16) board = GameBoard(shape) t = buildFigure('Tank', (0, 0), RED) i = buildFigure('Infantry', (0, 15), RED) stateTank = GameState(shape) stateTank.addFigure(t) stateInf = GameState(shape) stateInf.addFigure(i) # movements without road nTankNoRoad = len(GM.buildMovements(board, stateTank, t)) nInfNoRoad = len(GM.buildMovements(board, stateInf, i)) # adding road road = np.zeros(shape, 'uint8') road[0, :] = TERRAIN_TYPE['ROAD'].level board.addTerrain(road) # test for vehicles nTankRoad = len(GM.buildMovements(board, stateTank, t)) nInfRoad = len(GM.buildMovements(board, stateInf, i)) # tank self.assertNotEqual(nTankRoad, nTankNoRoad, 'road has no influence for tank') self.assertEqual(nTankRoad, 8, 'invalid distance with road for tank') self.assertEqual(nTankNoRoad, 6, 'invalid distance without road for tank') self.assertEqual(nTankRoad - nTankNoRoad, 2, 'road does not increase by 2 the distance for tank') # infantry self.assertNotEqual(nInfRoad, nInfNoRoad, 'road has no influence on infantry') self.assertEqual(nInfRoad, 4, 'invalid distance with road for infantry') self.assertEqual(nInfNoRoad, 3, 'invalid distance without road for infantry') self.assertEqual( nInfRoad - nInfNoRoad, 1, 'road does not increase by 1 the distance for infantry') # test for road change board.terrain[0, 0] = 0 board.terrain[0, 15] = 0 nTankRoad = len(GM.buildMovements(board, stateTank, t)) nInfRoad = len(GM.buildMovements(board, stateInf, i)) self.assertEqual(nTankRoad, 8, 'invalid distance for tank') self.assertEqual(nInfRoad, 4, 'invalid distance for infantry')
class TestLOS(unittest.TestCase): def setUp(self): collect() self.shape = (8, 8) self.board = GameBoard(self.shape) self.state = GameState(self.shape) self.blue_tank = buildFigure('Tank', (4, 6), BLUE) self.red_tank = buildFigure('Tank', (4, 1), RED) self.red_inf = buildFigure('Infantry', (1, 4), RED) self.state.addFigure(self.red_tank, self.red_inf, self.blue_tank) los_on_target = self.state.getLOS(self.blue_tank) self.los_tank = los_on_target[self.red_tank.index] self.los_inf = los_on_target[self.red_inf.index] def testNoBlockers(self): self.assertTrue(GM.checkLine(self.board, self.state, self.los_tank), 'tank has no LOS on target') self.assertTrue(GM.checkLine(self.board, self.state, self.los_inf), 'infantry has no LOS on target') def testDirectBlock(self): blocker = np.zeros(self.shape, 'uint8') blocker[4, 4] = 1 # continuously adding 1 will cycle through the type of terrains # road self.board.addTerrain(blocker) self.assertTrue(GM.checkLine(self.board, self.state, self.los_tank), 'road: tank has no LOS on target') self.assertTrue(GM.checkLine(self.board, self.state, self.los_inf), 'road: infantry has no LOS on target') # isolated tree self.board.addTerrain(blocker) self.assertFalse(GM.checkLine(self.board, self.state, self.los_tank), 'tree: tank has LOS on target') self.assertTrue(GM.checkLine(self.board, self.state, self.los_inf), 'tree: infantry has no LOS on target') # forest self.board.addTerrain(blocker) self.assertFalse(GM.checkLine(self.board, self.state, self.los_tank), 'forest: tank has LOS on target') self.assertTrue(GM.checkLine(self.board, self.state, self.los_inf), 'forest: infantry has no LOS on target') # wooden building self.board.addTerrain(blocker) self.assertFalse(GM.checkLine(self.board, self.state, self.los_tank), 'urban: tank has LOS on target') self.assertTrue(GM.checkLine(self.board, self.state, self.los_inf), 'urban: infantry has no LOS on target') # concrete building self.board.addTerrain(blocker) self.assertFalse(GM.checkLine(self.board, self.state, self.los_tank), 'building: tank has LOS on target') self.assertTrue(GM.checkLine(self.board, self.state, self.los_inf), 'building: infantry has no LOS on target') def testForestBlock(self): blocker = np.zeros(self.shape, 'uint8') blocker[4, 4] = TERRAIN_TYPE['FOREST'].level blocker[3, 6] = TERRAIN_TYPE['FOREST'].level blocker[4, 6] = TERRAIN_TYPE['FOREST'].level blocker[5, 6] = TERRAIN_TYPE['FOREST'].level self.board.addTerrain(blocker) self.assertFalse(GM.checkLine(self.board, self.state, self.los_tank), 'forest: tank has LOS on target') self.assertFalse(GM.checkLine(self.board, self.state, self.los_inf), 'forest: infantry has LOS on target') def testForestMarginNoBlock(self): blocker = np.zeros(self.shape, 'uint8') blocker[4, 6] = TERRAIN_TYPE['FOREST'].level blocker[3, 7] = TERRAIN_TYPE['FOREST'].level blocker[4, 7] = TERRAIN_TYPE['FOREST'].level blocker[5, 7] = TERRAIN_TYPE['FOREST'].level self.board.addTerrain(blocker) self.assertTrue(GM.checkLine(self.board, self.state, self.los_tank), 'forest: tank has LOS on target') self.assertTrue(GM.checkLine(self.board, self.state, self.los_inf), 'forest: infantry has LOS on target') def testBuildingBlock(self): blocker = np.zeros(self.shape, 'uint8') blocker[4, 4] = TERRAIN_TYPE['CONCRETE_BUILDING'].level blocker[3, 6] = TERRAIN_TYPE['CONCRETE_BUILDING'].level blocker[4, 6] = TERRAIN_TYPE['CONCRETE_BUILDING'].level blocker[5, 6] = TERRAIN_TYPE['CONCRETE_BUILDING'].level self.board.addTerrain(blocker) self.assertFalse(GM.checkLine(self.board, self.state, self.los_tank), 'urban: tank has LOS on target') self.assertFalse(GM.checkLine(self.board, self.state, self.los_inf), 'urban: infantry has LOS on target') def testArmoredUnitBlock(self): dst = Hex(3, 5).cube() m1 = GM.actionMove(self.board, self.state, self.red_tank, destination=dst) # we move the tank in a blocking position GM.step(self.board, self.state, m1) los_on_target = self.state.getLOS(self.blue_tank) self.los_inf = los_on_target[self.red_inf.index] self.assertFalse(GM.checkLine(self.board, self.state, self.los_inf), 'armored: inf has LOS on target') def testIndirectFire(self): blocker = np.zeros(self.shape, 'uint8') blocker[2, 5] = TERRAIN_TYPE['CONCRETE_BUILDING'].level blocker[3, 5] = TERRAIN_TYPE['CONCRETE_BUILDING'].level self.board.addTerrain(blocker) # we replace the blue tank with an infantry so we can use the mortar for an indirect hit self.state.clearFigures(BLUE) blue_inf = buildFigure('Infantry', (4, 6), BLUE) self.state.addFigure(blue_inf) los_on_target = self.state.getLOS(blue_inf) self.los_inf = los_on_target[self.red_inf.index] self.assertFalse(GM.checkLine(self.board, self.state, self.los_inf), 'indirect: infantry has LOS on target') # self.blue_tank.kind = FigureType.INFANTRY self.assertTrue( GM.canShoot(self.board, self.state, self.red_inf, blue_inf, self.red_inf.weapons['MT']), 'indirect: infantry cannot shot at the target' )