示例#1
0
def decode_ant_vision_2d_examples(encoded_examples: Tuple[ndarray, ndarray]) -> List[AntVision2DExample]:
    gst = GameStateTranslator()
    features, labels = encoded_examples
    feature_example_count = features.shape[0]
    feature_row_min = 0 - floor(features.shape[1] / 2)
    feature_row_max = 0 + floor(features.shape[1] / 2)
    feature_col_min = 0 - floor(features.shape[2] / 2)
    feature_col_max = 0 + floor(features.shape[2] / 2)
    row_nums = seq(range(feature_row_min, feature_row_max)).to_list()
    col_nums = seq(range(feature_col_min, feature_col_max)).to_list()
    if features.shape[3] != 7: raise ValueError(
        'Only implemented for 7 channel encoding since down_sampling eliminates information')

    items = []
    for ex_index in range(feature_example_count):
        example_features: Dict[Position, PositionState] = {}
        for row_index, row_num in enumerate(row_nums):
            for col_index, col_num in enumerate(col_nums):
                position = Position(row_num, col_num)
                enum_val = gst.convert_array_to_enum(features[ex_index, row_index, col_index].tolist(), PositionState)
                example_features[position] = enum_val

        direction = gst.convert_array_to_enum(labels[ex_index].tolist(), Direction)
        items.append(AntVision2DExample(example_features, direction))
    return items
    def test_create_nn_input(self):
        game_state = create_test_game_state()
        test_ant = game_state.game_turns[0].ants.get(Position(1, 19))
        ant_vision = game_state.game_map.get_positions_within_distance(
            test_ant.position, game_state.view_radius_squared)
        translator = GameStateTranslator()

        nn_input = translator.convert_to_1d_example(test_ant, game_state)
        self.assertIsNotNone(nn_input)
        self.assertEqual((len(ant_vision) - 1), len(nn_input.features))
 def test_convert_enums_to_array(self):
     translator = GameStateTranslator()
     array = translator.convert_enum_to_array(PositionState.LAND,
                                              PositionState)
     self.assertEqual([0, 0, 0, 0, 0, 0, 1], array)
     self.assertEqual(
         PositionState.LAND,
         translator.convert_array_to_enum(array, PositionState))
     self.assertIsNone(
         translator.convert_array_to_enum([0, 0, 0, 0, 0, 0, 0],
                                          PositionState))
示例#4
0
def encode_map_examples(examples: List[AntMapExample], channel_count: int) -> Tuple[ndarray, ndarray]:
    gst = GameStateTranslator()
    if len(examples) == 0: return numpy.empty([0, 43, 39, 7], dtype=int), numpy.empty([0, 5], dtype=int)
    ex = examples[0]
    features = numpy.zeros([len(examples), ex.row_count, ex.column_count, channel_count], dtype=int)
    for e_index, e in enumerate(examples):
        for r in range(ex.row_count):
            for c in range(ex.column_count):
                key = Position(r, c)
                features[e_index, r, c] = down_sample(gst, e.features[key], channel_count)
    labels = [gst.convert_enum_to_array(ex.label, Direction) for ex in examples]
    return numpy.array(features), numpy.array(labels)
示例#5
0
    def __init__(self, game_identifier: str, name: BotName, model_path: str):
        super().__init__(game_identifier, name)
        self.game_options: Dict[str, int] = {}
        self.game_map: GameMap = None
        self.visible_ants: Dict[Position, VisibleAnt] = {}
        self.visible_food: Set[Position] = set()
        self.visible_hills: Dict[Position, VisibleHill] = {}
        self.pending_orders: List[Order] = []
        self.channel_count = 7
        self.gst = GameStateTranslator()

        self.model: Model = keras.models.load_model(model_path)
        print(self.model.input.shape)
示例#6
0
def map_to_input(
        task: Tuple[str, EncodingType, str]) -> Tuple[np.ndarray, np.ndarray]:
    bot_name, type, game_path = task
    channel_count = 7
    gst = GameStateTranslator()
    if type == EncodingType.ANT_VISION_2D:
        feature_cache_path = game_path.replace(
            '.json', f'_ANT_VISION_2D_FEATURES_{bot_name}_{channel_count}.npy')
        label_cache_path = game_path.replace(
            '.json', f'_ANT_VISION_2D_LABELS_{bot_name}_{channel_count}.npy')
        if os.path.exists(feature_cache_path):
            return np.load(feature_cache_path), np.load(label_cache_path)
        gs = load_game_state(game_path)
        try:
            ant_vision = gst.convert_to_2d_ant_vision(bot_name, [gs])
            features, labels = enc.encode_2d_examples(ant_vision,
                                                      channel_count)
            print(f'Saving {feature_cache_path}')
            np.save(feature_cache_path, features)
            np.save(label_cache_path, labels)
            return features, labels
        except:
            print(f'Failed to load ${game_path}')
            return np.empty([0, 12, 12, 7]), np.empty([0, 5])

    elif type == EncodingType.MAP_2D:
        feature_cache_path = game_path.replace(
            '.json',
            f'_ANT_VISION_2DMAP_FEATURES_{bot_name}_{channel_count}.npy')
        label_cache_path = game_path.replace(
            '.json',
            f'_ANT_VISION_2DMAP_LABELS_{bot_name}_{channel_count}.npy')
        if os.path.exists(feature_cache_path):
            return np.load(feature_cache_path), np.load(label_cache_path)
        gs = load_game_state(game_path)
        try:
            ant_vision = gst.convert_to_antmap(bot_name, [gs])
            features, labels = enc.encode_map_examples(ant_vision,
                                                       channel_count)
            print(f'Saving {feature_cache_path}')
            np.save(feature_cache_path, features)
            np.save(label_cache_path, labels)
            return features, labels
        except:
            print(f'Failed to load ${game_path}')
            return np.empty([0, 43, 39, 7]), np.empty([0, 5])
    else:
        raise NotImplementedError()
示例#7
0
def decode_map_examples(encoded_examples: Tuple[ndarray, ndarray]) -> List[AntMapExample]:
    features, labels = encoded_examples
    items = []
    gst = GameStateTranslator()
    row_count = features.shape[1]
    col_count = features.shape[2]
    for ex_index in range(features.shape[0]):
        example_features: Dict[Position, PositionState] = {}
        for row_num in range(features.shape[1]):
            for col_num in range(features.shape[2]):
                position = Position(row_num, col_num)
                enum_val = gst.convert_array_to_enum(features[ex_index, row_num, col_num].tolist(), PositionState)
                example_features[position] = enum_val

        direction = gst.convert_array_to_enum(labels[ex_index].tolist(), Direction)
        items.append(AntMapExample(example_features, direction, row_count, col_count))
    return items
示例#8
0
    def test_encode_2d_map(self):
        bot_to_emulate = 'pkmiec_1'

        gsg = GameStateGenerator()
        gst = GameStateTranslator()
        test_game_state = gsg.generate_from_file(self.data_path)
        expected_map = gst.convert_to_antmap(bot_to_emulate, [test_game_state])

        actual_encoded_map = map_to_input(
            (bot_to_emulate, EncodingType.MAP_2D, self.data_path))
        actual_decoded_map = decode_map_examples(actual_encoded_map)

        for index, expected in enumerate(expected_map):
            self.assertEqual(expected.label, actual_decoded_map[index].label)
            for expected_pos in expected.features.keys():
                self.assertEqual(
                    expected.features[expected_pos],
                    actual_decoded_map[index].features[expected_pos])
示例#9
0
def profile_encoding():
    bot_to_emulate = 'memetix_1'
    game_paths = [
        f for f in glob.glob(
            f'{os.getcwd()}\\training\\tests\\test_data\\**\\*.json')
    ]
    test_games = game_paths[2:3]
    gst = GameStateTranslator()
    gsg = GameStateGenerator()

    pr = cProfile.Profile()
    pr.enable()
    game_states = seq(test_games).map(
        lambda path: load_game_state(path, gsg)).to_list()
    mv_features, mv_labels = enc.encode_map_examples(
        gst.convert_to_global_antmap(bot_to_emulate, game_states), 7)
    pr.disable()
    # pr.print_stats(sort='cumtime')
    pr.dump_stats('ants_example_python.profile')
示例#10
0
def down_sample(gst: GameStateTranslator, ps: PositionState, channel_count: int):
    if channel_count == 7:
        return gst.convert_enum_to_array(ps, PositionState)
    elif channel_count == 3:
        if ps == PositionState.FRIENDLY_ANT or ps == PositionState.FRIENDLY_HILL:
            return [1, 0, 0]
        elif ps == PositionState.HOSTILE_ANT or ps == PositionState.HOSTILE_HILL:
            return [0, 1, 0]
        elif ps == PositionState.FOOD:
            return [0, 0, 1]
        else:
            return [0, 0, 0]
    else:
        raise ValueError('Not implemented')
示例#11
0
 def __init__(self,
              game_paths: List[str],
              batch_size: int,
              bot_to_emulate: str,
              channel_count=7,
              dataset_type: DatasetType = DatasetType.TRAINING):
     self.batch_size = batch_size
     self.channel_count = channel_count
     self.bot_to_emulate = bot_to_emulate
     self.game_paths = sk.utils.shuffle(game_paths)
     self.gst = GameStateTranslator()
     self.gsg = GameStateGenerator()
     self.game_indexes: List[GameIndex] = []
     self.loaded_indexes: List[LoadedIndex] = []
     self.max_load_count = 10
     self.dataset_type = dataset_type
     if len(game_paths) == 0:
         raise ValueError(
             'Must provide at least one game path for the index')
示例#12
0
class NNBot(Bot):
    def __init__(self, game_identifier: str, name: BotName, model_path: str):
        super().__init__(game_identifier, name)
        self.game_options: Dict[str, int] = {}
        self.game_map: GameMap = None
        self.visible_ants: Dict[Position, VisibleAnt] = {}
        self.visible_food: Set[Position] = set()
        self.visible_hills: Dict[Position, VisibleHill] = {}
        self.pending_orders: List[Order] = []
        self.channel_count = 7
        self.gst = GameStateTranslator()

        self.model: Model = keras.models.load_model(model_path)
        print(self.model.input.shape)

    def start(self, start_data: str):
        self.game_options = seq(start_data.split('\n')) \
            .filter(lambda line: line != '') \
            .map(lambda opt: (opt.split(' ')[0], int(opt.split(' ')[1]))) \
            .to_dict()
        self.game_map = create_map(self.game_options['rows'],
                                   self.game_options['cols'])

    def convert_pos_to_state(self, pos: Position) -> PositionState:
        if self.visible_ants.get(pos) is not None:
            return PositionState.FRIENDLY_ANT if self.visible_ants[
                pos].is_friendly() else PositionState.HOSTILE_ANT
        if self.visible_hills.get(pos) is not None:
            return PositionState.FRIENDLY_HILL if self.visible_hills.get(
                pos).is_friendly() else PositionState.HOSTILE_HILL
        if pos in self.visible_food:
            return PositionState.FOOD
        return PositionState.WATER if self.game_map.get_terrain(
            pos) == TerrainType.WATER else PositionState.LAND

    def create_predictions(
            self,
            ants: List[VisibleAnt]) -> List[Tuple[VisibleAnt, Direction]]:
        def map_to_position_state(
                ant: VisibleAnt) -> Dict[Position, PositionState]:
            ant_vision = self.game_map.get_positions_within_distance(
                ant.position,
                self.game_options['viewradius2'],
                use_absolute=False,
                crop_to_square=True)
            position_states = {
                av: self.convert_pos_to_state(
                    self.game_map.wrap_position(
                        ant.position.row + av.row,
                        ant.position.column + av.column))
                for av in ant_vision
            }
            return position_states

        def convert_prediction_to_direction(
                ant: VisibleAnt,
                prediction: List) -> Tuple[VisibleAnt, Direction]:
            pred = [0] * 5
            pred[numpy.array(prediction).argmax()] = 1
            d: Direction = self.gst.convert_array_to_enum(pred, Direction)
            return ant, d

        position_states = seq(ants).map(map_to_position_state).to_list()
        features = encode_2d_features(position_states, self.gst,
                                      self.channel_count)
        predictions = self.model.predict(features)
        mapped_predictions = [
            convert_prediction_to_direction(ants[index], prediction)
            for index, prediction in enumerate(predictions)
        ]
        return mapped_predictions

    def create_orders(self) -> List[Order]:
        friendly_ants = seq(self.visible_ants.values()) \
            .filter(lambda a: a.is_friendly()) \
            .to_list()

        pending_orders = seq(friendly_ants) \
            .map(lambda va: Order(va.position, Direction.NONE,
                                  self.game_map.adjacent_movement_position(va.position, Direction.NONE))) \
            .to_list()
        predictions: List[Tuple[
            VisibleAnt, Direction]] = self.create_predictions(friendly_ants)

        pass_through_count = 0
        while seq(pending_orders).filter(
                lambda po: po.dir == Direction.NONE).len(
                ) > 0 and pass_through_count < 3:
            for index, order in enumerate(pending_orders):
                # pylint: disable=cell-var-from-loop
                matching_prediction = seq(predictions).find(
                    lambda t: t[0].position == order.position)
                new_order_position = self.game_map.adjacent_movement_position(
                    order.position, matching_prediction[1])
                # pylint: disable=cell-var-from-loop
                conflicting_order = seq(pending_orders).find(
                    lambda po: po.next_position == new_order_position)
                if conflicting_order is None:
                    pending_orders[index] = Order(order.position,
                                                  matching_prediction[1],
                                                  new_order_position)
            pass_through_count += 1
        return pending_orders

    def play_turn(self, play_turn_data: str):
        def parse_segments(line: str) -> Tuple[str, Position, Optional[int]]:
            segments = line.split(' ')
            return segments[0], Position(int(segments[1]), int(
                segments[2])), int(segments[3]) if len(segments) == 4 else None

        input_data = seq(play_turn_data.split('\n')) \
            .filter(lambda line: line != '') \
            .map(parse_segments) \
            .to_list()

        seq(input_data).filter(lambda t: t[0] == 'w').for_each(
            lambda t: self.game_map.update_terrain(t[1], TerrainType.WATER))
        self.visible_hills = seq(input_data).filter(lambda t: t[0] == 'h').map(
            lambda t: (t[1], VisibleHill(t[1], t[2]))).to_dict()
        self.visible_ants = seq(input_data).filter(lambda t: t[0] == 'a').map(
            lambda t: (t[1], VisibleAnt(t[1], t[2]))).to_dict()
        self.visible_food = seq(input_data).filter(lambda t: t[0] == 'f').map(
            lambda t: t[1]).to_set()
        self.pending_orders = self.create_orders()

    def read_lines(self):
        orders = seq(self.pending_orders).map(str).to_list()
        return orders
 def test_create_2d_ant_vision(self):
     game_state = create_test_game_state()
     translator = GameStateTranslator()
     translated = translator.convert_to_2d_ant_vision(
         'pkmiec_1', [game_state])
     self.assertIsNotNone(translated)
示例#14
0
def encode_2d_examples(examples: List[AntVision2DExample], channel_count: int) -> Tuple[ndarray, ndarray]:
    gst = GameStateTranslator()
    features = encode_2d_features(seq(examples).map(lambda e: e.features).to_list(), gst, channel_count)
    labels = numpy.array([gst.convert_enum_to_array(ex.label, Direction) for ex in examples])
    return features, labels
示例#15
0
import cProfile
import glob

from ants_ai.training.neural_network.encoders.game_state_translator import GameStateTranslator
from ants_ai.training.tests.test_utils import create_test_game_state
from ants_ai.training.game_state.generator import GameStateGenerator
from functional import seq
import jsonpickle
import os
from ants_ai.training.game_state.game_state import GameState
from ants_ai.training.neural_network.encoders import encoders as enc

game_state = create_test_game_state()
translator = GameStateTranslator()


def load_game_state(path: str, gsg: GameStateGenerator) -> GameState:
    with open(path, "r") as f:
        json_data = f.read()
        pr = jsonpickle.decode(json_data)
        return gsg.generate(pr)


def convert_game_state():
    bot_to_emulate = 'memetix_1'
    game_paths = [
        f for f in glob.glob(
            f'{os.getcwd()}\\training\\tests\\test_data\\**\\*.json')
    ]
    test_games = game_paths[2:3]
    gst = GameStateTranslator()