Пример #1
0
 def test_breed(self):
     client = SimulationClient('sqlite:///:memory:')
     grid = SimulationGrid(persistence=client,
                           simulation_parameters=sim_config_empty)
     a_list = [(Animal.Fish, SquareGridCoordinate(x=1, y=1)),
               (Animal.Fish, SquareGridCoordinate(x=2, y=1)),
               (Animal.Fish, SquareGridCoordinate(x=3, y=1)),
               (Animal.Fish, SquareGridCoordinate(x=1, y=3)),
               (Animal.Fish, SquareGridCoordinate(x=3, y=2)),
               (Animal.Shark, SquareGridCoordinate(x=2, y=2))]
     # adding some food and a shark
     for t, c in a_list:
         client.init_animal(sim_id=grid._sid,
                            current_turn=0,
                            animal_type=t,
                            coordinate=c)
     # updating grid turn
     grid._sim_turn = 4
     shark_update = grid._eat()
     assert len(shark_update) == 1, 'Shark should have fed'
     breed_moved = grid._breed_and_move(fed_sharks=shark_update)
     assert len(
         breed_moved
     ) == 5, '4 fishes and one shark should have moved due to breeding'
     assert len(breed_moved) == (len(a_list) - 1)
     grid_df = grid.get_simulation_grid_data()
     assert len(grid_df[grid_df['animal_type'] ==
                        Animal.Shark]) == 2, 'Should be 2 Sharks'
     assert len(grid_df[grid_df['animal_type'] ==
                        Animal.Fish]) == 8, 'Should be 8 fishes'
Пример #2
0
 def test_topology_agnostic_eating(self):
     '''
     Check the topology-agnostic behavior, i.e. that the shark from one corner
     will eat the fish from the opposite corner
     '''
     # set fish breeding probability to 0
     sim_config_empty_local = copy.deepcopy(sim_config_empty)
     sim_config_empty_local['fish_breed_probability'] = 0
     client = SimulationClient('sqlite:///:memory:')
     grid = SimulationGrid(persistence=client,
                           simulation_parameters=sim_config_empty_local)
     a_list = [(Animal.Fish, SquareGridCoordinate(x=0, y=0)),
               (Animal.Shark, SquareGridCoordinate(x=9, y=9))]
     # adding some food and a shark
     for t, c in a_list:
         client.init_animal(sim_id=grid._sid,
                            current_turn=0,
                            animal_type=t,
                            coordinate=c)
     # updating grid turn
     grid._sim_turn = 6
     # AM: the latest two rows to allow optimized 'occupied coordinates' check
     grid.animals = grid.get_simulation_grid_data()
     grid.occupied_coord = set(
         zip(grid.animals.coord_x, grid.animals.coord_y))
     shark_update = grid._eat()
     # shark has eaten
     shark = grid._persistence.get_animals_by_type(
         sim_id=grid._sid, animal_type=Animal.Shark).iloc[0]
     # the shark is in update list
     assert len(
         shark_update) == 1, 'There should be one shark in update list'
     assert shark.last_fed == 6, 'Shark last fed value should have updated'
     assert shark_update[shark.oid] == SquareGridCoordinate(
         x=9, y=9), 'Shark previous coordinate in shark update'
     # Fish is dead
     animal_in_square = client.get_animal_in_position(
         sim_id=grid._sid,
         coordinate=SquareGridCoordinate(int(shark.coord_x),
                                         int(shark.coord_y)),
         live_only=False)
     assert len(
         animal_in_square) == 2, 'there shoud be two animals in that square'
     # check that there is no fish
     fish = grid._persistence.get_animals_by_type(sim_id=grid._sid,
                                                  animal_type=Animal.Fish)
     assert len(
         fish
     ) == 0, 'there should be no fish alive'  # there is no fish (since we put 0 breeding probability)
Пример #3
0
 def test_simulation_init(self):
     client = SimulationClient('sqlite:///:memory:')
     grid = SimulationGrid(persistence=client,
                           simulation_parameters=sim_config)
     # Should have spawned the fishes and sharks
     nb_fish = sim_config['init_nb_fish']
     nb_sharks = sim_config['init_nb_shark']
     grid_table = grid._persistence.get_animals_df(grid._sid)
     assert len(grid_table) == (nb_fish +
                                nb_sharks), 'Missing some animals!'
Пример #4
0
 def test_starving(self):
     client = SimulationClient('sqlite:///:memory:')
     grid = SimulationGrid(persistence=client,
                           simulation_parameters=sim_config)
     turn_to_starve = sim_config['shark_starving']
     # set turn to more...
     grid._sim_turn = turn_to_starve + 1
     grid._check_deads()
     assert len(
         grid._persistence.get_animals_by_type(grid._sid,
                                               Animal.Shark)) == 0
Пример #5
0
 def test_eating(self):
     client = SimulationClient('sqlite:///:memory:')
     grid = SimulationGrid(persistence=client,
                           simulation_parameters=sim_config_empty)
     a_list = [(Animal.Fish, SquareGridCoordinate(x=1, y=1)),
               (Animal.Fish, SquareGridCoordinate(x=2, y=1)),
               (Animal.Fish, SquareGridCoordinate(x=3, y=1)),
               (Animal.Fish, SquareGridCoordinate(x=1, y=3)),
               (Animal.Fish, SquareGridCoordinate(x=3, y=2)),
               (Animal.Shark, SquareGridCoordinate(x=2, y=2))]
     # adding some food and a shark
     for t, c in a_list:
         client.init_animal(sim_id=grid._sid,
                            current_turn=0,
                            animal_type=t,
                            coordinate=c)
     # updating grid turn
     grid._sim_turn = 4
     # AM: the next two rows are to allow optimized 'occupied coordinates' check
     grid.animals = grid.get_simulation_grid_data()
     grid.occupied_coord = set(
         zip(grid.animals.coord_x, grid.animals.coord_y))
     shark_update = grid._eat()
     # shark has eaten
     shark = grid._persistence.get_animals_by_type(
         sim_id=grid._sid, animal_type=Animal.Shark).iloc[0]
     # the shark is in update list
     assert len(
         shark_update) == 1, 'There should be one shark in update list'
     assert shark.last_fed == 4, 'Shark last fed value should have updated'
     assert shark_update[shark.oid] == SquareGridCoordinate(
         x=2, y=2), 'Shark previous coordinate in shark update'
     # Fish is dead
     animal_in_square = client.get_animal_in_position(
         sim_id=grid._sid,
         coordinate=SquareGridCoordinate(int(shark.coord_x),
                                         int(shark.coord_y)),
         live_only=False)
     assert len(
         animal_in_square) == 2, 'there shoud be two animals in that square'
Пример #6
0
 def test_check_if_occupied(self):
     '''
     Test the modified function
     '''
     client = SimulationClient('sqlite:///:memory:')
     grid = SimulationGrid(persistence=client,
                           simulation_parameters=sim_config_empty)
     a_list = [(Animal.Fish, SquareGridCoordinate(x=1, y=1)),
               (Animal.Shark, SquareGridCoordinate(x=2, y=2))]
     # adding some food and a shark
     for t, c in a_list:
         client.init_animal(sim_id=grid._sid,
                            current_turn=0,
                            animal_type=t,
                            coordinate=c)
     grid.animals = grid.get_simulation_grid_data()
     grid.occupied_coord = set(
         zip(grid.animals.coord_x, grid.animals.coord_y))
     assert grid.check_if_occupied(SquareGridCoordinate(
         x=1, y=1)) == True, 'should be occupied'
     assert grid.check_if_occupied(SquareGridCoordinate(
         x=2, y=2)) == True, 'should be occupied'
     assert grid.check_if_occupied(SquareGridCoordinate(
         x=1, y=2)) == False, 'should be spare'
     # repeat the same for 1x1 case with initialization of 1 Fish
     del client, grid, a_list
     sim_config_empty_local = copy.deepcopy(sim_config_empty)
     sim_config_empty_local['init_nb_fish'] = 1
     sim_config_empty_local['grid_size'] = 1
     client = SimulationClient('sqlite:///:memory:')
     grid = SimulationGrid(persistence=client,
                           simulation_parameters=sim_config_empty_local)
     assert grid.check_if_occupied(SquareGridCoordinate(
         x=0, y=0)) == True, 'should be occupied'
Пример #7
0
    def test_empty(self):
        '''
        Tests that an empty grid throws an exception of no sharks
        '''
        client = SimulationClient('sqlite:///:memory:')
        grid = SimulationGrid(persistence=client,
                              simulation_parameters=sim_config_empty)

        with pytest.raises(EndOfSimulatioError):
            grid._check_deads()

        with pytest.raises(EndOfSimulatioError):
            grid.play_turn()
Пример #8
0
    def test_starving(self):
        client = SimulationClient('sqlite:///:memory:')
        grid = SimulationGrid(persistence=client,
                              simulation_parameters=sim_config)
        turn_to_starve = sim_config['shark_starving']
        # set turn to more...
        grid._sim_turn = turn_to_starve + 1
        grid._check_deads()
        assert len(
            grid._persistence.get_animals_by_type(grid._sid,
                                                  Animal.Shark)) == 0

        # amend this test by adding further checks
        # after the first turn we should have killed the sharks
        with pytest.raises(EndOfSimulatioError):
            grid.check_simulation_ends()

        with pytest.raises(EndOfSimulatioError):
            grid._check_deads()

        with pytest.raises(EndOfSimulatioError):
            grid.play_turn()
Пример #9
0
    def test_fish_only(self):
        '''
        Test if non-empty, but fish only: the simulation should end
        Make two cases:
            (1) add manually the fish to empty grid
            (2) use the config with updated value for corresponding key
        '''
        # No. 1
        client = SimulationClient('sqlite:///:memory:')
        grid = SimulationGrid(persistence=client,
                              simulation_parameters=sim_config_empty)
        a_list = [
            (Animal.Fish, SquareGridCoordinate(x=1, y=1)),
        ]

        for t, c in a_list:
            client.init_animal(sim_id=grid._sid,
                               current_turn=0,
                               animal_type=t,
                               coordinate=c)

        with pytest.raises(EndOfSimulatioError):
            grid._check_deads()

        with pytest.raises(EndOfSimulatioError):
            grid.play_turn()

        # repeat the same for No. 2
        del client, grid, a_list

        sim_config_empty_local = copy.deepcopy(sim_config_empty)
        sim_config_empty_local['init_nb_fish'] = 1

        client = SimulationClient('sqlite:///:memory:')
        grid = SimulationGrid(persistence=client,
                              simulation_parameters=sim_config_empty_local)
        with pytest.raises(EndOfSimulatioError):
            grid._check_deads()

        with pytest.raises(EndOfSimulatioError):
            grid.play_turn()
Пример #10
0
 def test_position_functions(self):
     client = SimulationClient('sqlite:///:memory:')
     # init DB
     sid = client.init_simulation(**sim_config)
     # add a bunch of animals
     for t, c in animal_list:
         client.init_animal(sim_id=sid,
                            current_turn=0,
                            animal_type=t,
                            coordinate=c)
     # check animal in square
     coord = SquareGridCoordinate(x=1, y=3)
     animals_in_square = client.get_animal_in_position(sim_id=sid,
                                                       coordinate=coord)
     assert len(animals_in_square) == 1
     # kill that animal
     client.kill_animal(sim_id=sid, animal_ids=[animals_in_square[0].oid])
     animals_in_square = client.get_animal_in_position(sim_id=sid,
                                                       coordinate=coord)
     assert len(animals_in_square) == 0
     # adding a live one in coord
     client.init_animal(sim_id=sid,
                        current_turn=0,
                        animal_type=Animal.Fish,
                        coordinate=coord)
     animals_in_square = client.get_animal_in_position(sim_id=sid,
                                                       coordinate=coord,
                                                       live_only=False)
     assert len(animals_in_square) == 2
Пример #11
0
                         help='Maximum number of turns for the simulation')
 cmd_parser.add_argument('--config_path',
                         default=None,
                         type=str,
                         help="""
                         Configuration file path. If specified, configuration file will be loaded from this path
                         """)
 args = cmd_parser.parse_args()
 if args.config_path is not None:
     raise NotImplementedError(
         'Code for directing to an alternative configuration'
         ' repository has not been implemented yet')
 # Load simulation configuration
 sim_config = read_simulation_config(args.config_name)
 # Instantiate client
 client = SimulationClient(get_database_string())
 # display initial grid
 grid = SimulationGrid(persistence=client, simulation_parameters=sim_config)
 print(
     display_simple_grid(client.get_animals_df(grid._sid),
                         grid_size=sim_config['grid_size']))
 for turn in range(args.max_turn):
     start_time = current_milli_time()
     grid.play_turn()
     print(''.join(['*'] * sim_config['grid_size'] * 2))
     print('Turn: {turn: ^{size}}'.format(turn=grid._sim_turn,
                                          size=sim_config['grid_size']))
     print()
     print(
         display_simple_grid(grid.get_simulation_grid_data(),
                             sim_config['grid_size']))
Пример #12
0
    def test_database_init(self):
        client = SimulationClient('sqlite:///:memory:')
        # init DB
        sid = client.init_simulation(**sim_config)
        assert len(
            client.get_all_simulations()) == 1, 'Should be only one simulation'
        assert isinstance(client.get_simulation(sid), Simulation)

        # check exception raised in init when adding animal on non-existent sim
        with pytest.raises(ValueError):
            client.init_animal(sim_id=10,
                               current_turn=0,
                               animal_type=Animal.Fish,
                               coordinate=SquareGridCoordinate(x=0, y=1))
        # init some animals
        client.init_animal(sim_id=sid,
                           current_turn=0,
                           animal_type=Animal.Fish,
                           coordinate=SquareGridCoordinate(x=0, y=1))
        assert client.coordinate_is_occupied(sim_id=sid,
                                             coordinate=SquareGridCoordinate(
                                                 x=0, y=1))

        # check exception for adding animal to an already occupied square
        with pytest.raises(NonEmptyCoordinate):
            client.init_animal(sim_id=sid,
                               current_turn=0,
                               animal_type=Animal.Fish,
                               coordinate=SquareGridCoordinate(x=0, y=1))
        # but should be fine in a new simulation
        sid_2 = client.init_simulation(**sim_config)
        client.init_animal(sim_id=sid_2,
                           current_turn=0,
                           animal_type=Animal.Fish,
                           coordinate=SquareGridCoordinate(x=0, y=1))

        # spawn outside the grid
        with pytest.raises(TopologyError):
            client.init_animal(sim_id=sid_2,
                               current_turn=0,
                               animal_type=Animal.Fish,
                               coordinate=SquareGridCoordinate(x=10, y=1))
Пример #13
0
import logging

from fish_bowl.dataio.persistence import SimulationClient, get_database_string
from fish_bowl.common.config_reader import read_simulation_config, save_simulation_config

_logger = logging.getLogger(__name__)

if __name__ == '__main__':
    logging.basicConfig(
        level=logging.INFO,
        format="%(asctime)s [%(levelname)s] %(filename)s:%(lineno)d:%(message)s"
    )
    client = SimulationClient(get_database_string())
    for config in ['simulation_config_1', 'simulation_config_2']:
        sim_config = read_simulation_config(config)
        client.init_simulation(**sim_config)
Пример #14
0
from fish_bowl.dataio.persistence import SimulationClient, get_database_string
from fish_bowl.process.topology import SquareGridCoordinate
from fish_bowl.process.simple_display import display_simple_grid

client = SimulationClient(get_database_string())
print(display_simple_grid(client.get_animals_df(sim_id=1), 10))
coord_1 = SquareGridCoordinate(6, 8)
coord_2 = SquareGridCoordinate(7, 9)
print(
    client.get_animal_in_position(sim_id=1,
                                  coordinate=coord_1,
                                  live_only=False))
print(
    client.get_animal_in_position(sim_id=1,
                                  coordinate=coord_2,
                                  live_only=False))
Пример #15
0
 def test_moving_animals(self):
     client = SimulationClient('sqlite:///:memory:')
     # init DB
     sid = client.init_simulation(**sim_config)
     # add a bunch of animals
     for v in animal_list:
         client.init_animal(sim_id=sid,
                            current_turn=0,
                            animal_type=v[0],
                            coordinate=v[1])
     # test move
     assert not client.coordinate_is_occupied(
         sim_id=sid, coordinate=SquareGridCoordinate(5, 3))
     client.move_animal(sim_id=sid,
                        animal_id=4,
                        new_position=SquareGridCoordinate(5, 3))
     assert client.coordinate_is_occupied(sim_id=sid,
                                          coordinate=SquareGridCoordinate(
                                              5, 3))
     # trying to move dead animal
     client.kill_animal(sim_id=sid, animal_ids=[3])
     with pytest.raises(ImpossibleAction):
         client.move_animal(sim_id=sid,
                            animal_id=3,
                            new_position=SquareGridCoordinate(3, 3))
     # trying to move to an already occupied square
     with pytest.raises(NonEmptyCoordinate):
         client.move_animal(sim_id=sid,
                            animal_id=5,
                            new_position=SquareGridCoordinate(5, 3))
     # but moving to a square occupied by a dead animal is possible
     assert not client.coordinate_is_occupied(
         sim_id=sid, coordinate=SquareGridCoordinate(3, 2))
     client.move_animal(sim_id=sid,
                        animal_id=1,
                        new_position=SquareGridCoordinate(3, 2))
     assert client.coordinate_is_occupied(sim_id=sid,
                                          coordinate=SquareGridCoordinate(
                                              3, 2))
Пример #16
0
    def test_animal_function(self):
        client = SimulationClient('sqlite:///:memory:')
        # init DB
        sid = client.init_simulation(**sim_config)
        # add a bunch of animals
        a_list = [(Animal.Fish, SquareGridCoordinate(x=1, y=1)),
                  (Animal.Fish, SquareGridCoordinate(x=2, y=1)),
                  (Animal.Fish, SquareGridCoordinate(x=3, y=1)),
                  (Animal.Fish, SquareGridCoordinate(x=1, y=3)),
                  (Animal.Fish, SquareGridCoordinate(x=3, y=2))]
        for t, c in a_list:
            client.init_animal(sim_id=sid,
                               current_turn=0,
                               animal_type=t,
                               coordinate=c)
        coord_list = client.has_fish_in_square(
            sim_id=sid, coordinates=[SquareGridCoordinate(1, 1)])
        assert len(coord_list) == 1, 'There should be a single fish'
        coord_list = client.has_fish_in_square(
            sim_id=sid, coordinates=[SquareGridCoordinate(1, 2)])
        assert len(coord_list) == 0, 'There should be no fish here'
        neigh = square_grid_neighbours(grid_size=10,
                                       coordinate=SquareGridCoordinate(2, 2))
        coord_list = client.has_fish_in_square(sim_id=sid, coordinates=neigh)
        assert len(coord_list) == 5, 'There should be 5 fishes here'

        # eating animals
        eaten = client.eat_animal_in_square(sim_id=sid,
                                            coordinate=SquareGridCoordinate(
                                                1, 1))
        assert eaten, 'Fish in 1, 1 should have been eaten'
        # can't eat dead Fish
        eaten = client.eat_animal_in_square(sim_id=sid,
                                            coordinate=SquareGridCoordinate(
                                                1, 1))
        assert not eaten, 'Should not be able to eat a dead Fish'
        client.init_animal(sim_id=sid,
                           current_turn=0,
                           animal_type=Animal.Shark,
                           coordinate=SquareGridCoordinate(5, 5))
        eaten = client.eat_animal_in_square(sim_id=sid,
                                            coordinate=SquareGridCoordinate(
                                                5, 5))
        assert not eaten, 'Should not be able to eat a Shark'
Пример #17
0
                         default=None,
                         type=str,
                         help="""
                         Configuration file path. If specified, configuration file will be loaded from this path
                         """)
 args = cmd_parser.parse_args()
 if args.config_path is not None:
     raise NotImplementedError(
         'Code for directing to an alternative configuration'
         ' repository has not been implemented yet')
 # Load simulation configuration
 sim_config = read_simulation_config(args.config_name)
 # Instantiate client
 # client = SimulationClient(get_database_string())
 client = SimulationClient(
     'sqlite:///:memory:'
 )  # use RAM, grids so far do not seem to be large; for extremely large need to change architecture as well
 # display initial grid
 grid = SimulationGrid(persistence=client, simulation_parameters=sim_config)
 print(
     display_simple_grid(client.get_animals_df(grid._sid),
                         grid_size=sim_config['grid_size']))
 for turn in range(args.max_turn):
     timer = time.time()
     # get occupied coord-s for quicker occupation-checks
     grid.animals = grid.get_simulation_grid_data()
     grid.occupied_coord = set(
         zip(grid.animals.coord_x, grid.animals.coord_y))
     grid.play_turn()
     print(''.join(['*'] * sim_config['grid_size'] * 2))
     print('Turn: {turn: ^{size}}'.format(turn=grid._sim_turn,
Пример #18
0
 def test_animal_functions(self):
     client = SimulationClient('sqlite:///:memory:')
     # init DB
     sid = client.init_simulation(**sim_config)
     # add a bunch of animals
     for t, c in animal_list:
         client.init_animal(sim_id=sid,
                            current_turn=0,
                            animal_type=t,
                            coordinate=c)
     # retrieve animals
     animals_df = client.get_animals_df(sim_id=1)
     assert isinstance(animals_df, pd.DataFrame), 'results is a DataFrame'
     assert len(animals_df) == 8, 'should be only 9 animals'
     # update animals
     # create update dict
     update_dict = {
         oid: {
             'breed_count': 1,
             'last_breed': 5,
             'last_fed': 4
         }
         for oid in animals_df.oid.values
     }
     client.update_animals(sim_id=sid, update_dict=update_dict)
     animals_df = client.get_animals_df(sim_id=1)
     assert animals_df.breed_count.unique(
     )[0] == 1, 'Breed count should be one now'
     client.update_animals(sim_id=sid, update_dict={1: {'alive': False}})
     # this update should not work
     animal = client.get_animal(sim_id=sid, animal_id=1)
     assert animal.alive, 'Animal should still be alive'
     # but this should work
     client.kill_animal(sim_id=sid, animal_ids=[1, 2, 3])
     animal = client.get_animal(sim_id=sid, animal_id=1)
     assert not animal.alive, 'This time alive was updates'
     # a dead animal does not occupy a square
     assert not client.coordinate_is_occupied(
         sim_id=sid, coordinate=SquareGridCoordinate(1, 3))
     # test get animal by types
     shark_df = client.get_animals_by_type(sim_id=sid,
                                           animal_type=Animal.Shark)
     assert shark_df.animal_type.unique()[0] == Animal.Shark
Пример #19
0
sim_config_empty = {
    'grid_size': 10,
    'init_nb_fish': 0,
    'fish_breed_maturity': 3,
    'fish_breed_probability': 80,
    'fish_speed': 2,
    'init_nb_shark': 0,
    'shark_breed_maturity': 5,
    'shark_breed_probability': 100,
    'shark_speed': 4,
    'shark_starving': 4}

if __name__ == '__main__':
    logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(filename)s:%(lineno)d:%(message)s")
    # save_simulation_config(sim_config, 'simulation_config_1', overwrite=True)
    # sim_config = read_simulation_config('simulation_config_2')
    client = SimulationClient(get_database_string())
    # sid = client.init_simulation(**sim_config)
    grid = SimulationGrid(persistence=client, simulation_parameters=sim_config)
    # for t, c in a_list:
    #     client.init_animal(sim_id=grid._sid, current_turn=0, animal_type=t, coordinate=c)

    print(display_simple_grid(client.get_animals_df(grid._sid), grid_size=sim_config['grid_size']))
    for turn in range(100):
        _logger.info('Turn: {}'.format(grid._sim_turn))
        grid.play_turn()
        print(display_simple_grid(grid.get_simulation_grid_data(), grid.get_simulation_parameters().grid_size))
        # _ = input('press key')