def setUp(self): self.tb = Toybox('breakout') fire = Input() fire.button1 = True noop = Input() self.tb.apply_action(fire)
def test_with_state(self): state = None with Toybox("breakout") as tb: state = tb.state_to_json() state['lives'] = 10 with Toybox("breakout", withstate=state) as tb: state = tb.state_to_json() self.assertEqual(state['lives'], 10)
def test_with_seed(self): # get default seed v1, v2, v1_, v2_ = [None] * 4 with Toybox("breakout") as tb: (v1, v2) = tb.state_to_json()["rand"]["state"] with Toybox("breakout", seed=1234) as tb: (v1_, v2_) = tb.state_to_json()["rand"]["state"] self.assertNotEqual(v1, v1_) self.assertNotEqual(v2, v2_)
def get_schema_caching(toybox: Toybox): global _CACHED_SCHEMA if toybox.game_name in _CACHED_SCHEMA: return _CACHED_SCHEMA[toybox.game_name] loaded = toybox.schema_for_state() _CACHED_SCHEMA[toybox.game_name] = loaded return loaded
def test_amidar_straight_up(self): with Toybox("amidar") as tb: up = Input() up.up = True score = 0 while not tb.game_over(): score = max(tb.get_score(), score) tb.apply_action(up) self.assertEqual(2, score)
def test_amidar_straight_down(self): with Toybox("amidar") as tb: down_fire = Input() # down and fire! down_fire.down = True down_fire.button1 = True score = 0 while not tb.game_over(): score = max(tb.get_score(), score) tb.apply_action(down_fire) self.assertEqual(2, score)
def test_amidar(self): config = None state = None with Toybox("amidar") as tb: config = tb.config_to_json() state = tb.state_to_json() self.assertEqual(1, tb.get_level()) self.assertEqual(356, tb.query_state_json("num_tiles_unpainted")) self.assertEqual(True, tb.query_state_json("jumps_remaining")) self.assertEqual(0, tb.get_score()) self.assertIsNotNone(tb.get_state())
def test_ffi_toybox_set_seed_no_new_game(self): with Toybox('breakout') as tb: json = tb.state_to_json() rng1_before, rng2_before = json['rand']['state'] tb.set_seed(1234) json = tb.state_to_json() rng1_after, rng2_after = json['rand']['state'] # You need to call tb.new_game() to reset the RNG # Therefore, these should be equal. self.assertEqual(rng1_before, rng1_after) self.assertEqual(rng2_before, rng2_after)
def test_breakout(self): config = None state = None with Toybox("breakout") as tb: config = tb.config_to_json() state = tb.state_to_json() self.assertEqual(108, tb.query_state_json("bricks_remaining")) self.assertEqual(0, tb.query_state_json("count_channels")) self.assertEqual(1, tb.get_level()) self.assertEqual(0, tb.get_score()) self.assertIsNotNone(tb.get_state())
def test_ffi_toybox_set_seed_new_game(self): with Toybox('breakout') as tb: json = tb.state_to_json() rng1_before, rng2_before = json['rand']['state'] tb.set_seed(1234) # Get new game tb.new_game() json = tb.state_to_json() rng1_after, rng2_after = json['rand']['state'] # Now they should be equal self.assertNotEqual(rng1_before, rng1_after) self.assertNotEqual(rng2_before, rng2_after)
def test_space_invaders(self): config = None state = None with Toybox("space_invaders") as tb: config = tb.config_to_json() state = tb.state_to_json() self.assertEqual(3, tb.query_state_json("shield_count")) self.assertEqual(state["ship"]["x"], tb.query_state_json("ship_x")) self.assertEqual(1, tb.get_level()) self.assertEqual(0, tb.get_score()) self.assertIsNotNone(tb.get_state()) self.assertIsNotNone(tb.get_state())
def test_set_eq(self): with Toybox('breakout') as tb: with BreakoutIntervention(tb) as intervention: intervention.eq_mode = SetEq initial_state = intervention.game with Toybox('breakout') as tb: with BreakoutIntervention(tb) as intervention: intervention.eq_mode = SetEq initial_state_copy = intervention.game with Toybox('breakout') as tb: with BreakoutIntervention(tb) as intervention: intervention.eq_mode = SetEq intervened1 = intervention.game intervention.game.paddle_speed += 1 intervention.game.lives += 1 with Toybox('breakout') as tb: with BreakoutIntervention(tb) as intervention: intervention.eq_mode = SetEq intervened2 = intervention.game intervention.game.paddle_speed += 1 intervention.game.lives +=1 with Toybox('breakout') as tb: with BreakoutIntervention(tb) as intervention: intervention.eq_mode = SetEq intervened3 = intervention.game intervention.game.paddle_speed += 2 intervention.game.lives += 1 # print(initial_state == initial_state_copy) self.assertEqual(initial_state, initial_state_copy) self.assertNotEqual(initial_state, intervened1) # print(initial_state == intervened1) self.assertEqual(intervened1, intervened2) # print(intervened1==intervened2) self.assertNotEqual(intervened1, intervened3)
def test_amidar(self): with Toybox("amidar") as tb: state = tb.state_to_json() self.assertEqual(1, tb.query_state_json('.state.level')) self.assertEqual(0, tb.query_state_json(".state.score")) self.assertEqual(4, tb.query_state_json(".state.jumps")) self.assertEqual( state['enemies'][3]['position']['x'], tb.query_state_json(".state.enemies[3].position.x")) self.assertEqual( state['enemies'][2]['position']['y'], tb.query_state_json(".state.enemies[2].position.y")) print(tb.query_state_json(".state.enemies[2].position.y"))
def test_get_property_simple(self): with Toybox('breakout') as tb: with BreakoutIntervention(tb) as intervention: game = intervention.game bricks = get_property(game, 'bricks') self.assertIsInstance(bricks, BrickCollection) brick = get_property(game, 'bricks[1]') self.assertIsInstance(brick, Brick) second_brick_col = get_property(intervention.game, 'bricks[1].col') self.assertEqual(second_brick_col, 0)
def test_set_at_index(self): with Toybox('breakout') as tb: with BreakoutIntervention(tb) as intervention: game = intervention.game new_brick = Brick.decode(intervention, game.bricks[2].encode(), Brick) old_brick = game.bricks[1] self.assertNotEqual(new_brick, old_brick) foo = get_property(game, 'bricks[1]', setval=new_brick) self.assertIsInstance(foo, Brick) self.assertNotEqual(old_brick, foo) # not setting foo to be new? self.assertEqual(foo, new_brick)
def test_rand_start_10_seeds(self): with Toybox('breakout') as tb: balls = [] input = Input() input.button1 = True for i in range(10): tb.set_seed(i) tb.new_game() tb.apply_action(input) json = tb.state_to_json() self.assertNotEqual(len(json['balls']), 0) balls.append(json['balls'][0]) ball_xpos = [ball['position']['x'] for ball in balls] x = ball_xpos[0] # At least one of these should be different! self.assertFalse(all([bx == x for bx in ball_xpos]))
def test_get_parent(self): with Toybox('breakout') as tb: with BreakoutIntervention(tb) as intervention: game = intervention.game # you would only use this if you wanted to get the parent # AND set the child first_brick_color = get_property(game, 'bricks[0].color.r', setval=42, get_container=True) self.assertIsInstance(first_brick_color, Color) self.assertEqual(first_brick_color.r, 42) bkout = get_property(game, 'paddle_speed', setval=100., get_container=True) self.assertIsInstance(bkout, Breakout) self.assertEqual(bkout.paddle_speed, 100.)
def sample(*args, **kwargs): with Toybox({game}) as tb: with {intervention}(tb) as intervention: game = intervention.game for key, v in vars(game).items(): if key in game.immutable_fields and not isinstance(v, Collection): continue mod = importlib.import_module(kwargs['modelmod'] + '.' + key) val = mod.sample(*args, **kwargs) if key in game.coersions: val = game.coersions[key](val) if __debug__: before = get_property(game, key) if key in game.immutable_fields: v.clear() for item in val: v.append(item) else: after = get_property(game, key, setval=val) return game
def test_set_eq_prop_state(self): s1, s2 = None, None with Toybox('breakout') as tb: with BreakoutIntervention(tb, eq_mode=SetEq) as intervention: s1 = Breakout.decode(intervention, intervention.game.encode(), Breakout) intervention.game.bricks[50].color.g = 99 s2 = Breakout.decode(intervention, intervention.game.encode(), Breakout) self.assertEqual(s1.bricks[49].color.g, s2.bricks[49].color.g) self.assertNotEqual(s1.bricks[50].color.g, s2.bricks[50].color.g) self.assertEqual(s1.bricks[49].color, s2.bricks[49].color) self.assertNotEqual(s1.bricks[50].color, s2.bricks[50].color) self.assertEqual(s1.bricks[49], s2.bricks[49]) self.assertNotEqual(s1.bricks[50], s2.bricks[50]) self.assertNotEqual(s1.bricks, s2.bricks) self.assertNotEqual(s1, s2)
def test_standard_eq(self): s1, s2, s3 = None, None, None with Toybox('breakout') as tb: fire = Input() fire.button1 = True noop = Input() tb.apply_action(fire) with BreakoutIntervention(tb) as intervention: s1 = intervention.game with BreakoutIntervention(tb) as intervention: s2 = intervention.game with BreakoutIntervention(tb) as intervention: intervention.game.paddle_speed = 10 s3 = intervention.game self.assertEqual(s1, s2) self.assertNotEqual(s1, s3) self.assertNotEqual(s2, s3)
def test_set_property(self): with Toybox('breakout') as tb: with BreakoutIntervention(tb) as intervention: game = intervention.game first_brick_r = get_property(game, 'bricks[0].color.r', setval=72) first_brick_g = get_property(game, 'bricks[0].color.g', setval=72) first_brick_b = get_property(game, 'bricks[0].color.b', setval=72) self.assertEqual(first_brick_r, 72) self.assertEqual(first_brick_g, 72) self.assertEqual(first_brick_b, 72) self.assertEqual(game.bricks[0].color.r, 72) self.assertEqual(game.bricks[0].color.g, 72) self.assertEqual(game.bricks[0].color.b, 72) self.assertNotEqual(game.bricks[1].color.r, 72) self.assertNotEqual(game.bricks[1].color.g, 72) self.assertNotEqual(game.bricks[1].color.b, 72)
def test_gridworld(self): config = None state = None with Toybox("gridworld") as tb: config = tb.config_to_json() state = tb.state_to_json()
def test_amidar(self): with Toybox("amidar") as tb: self._1000_random_actions_are_deterministic(tb)
def test_breakout(self): with Toybox("breakout") as tb: self._1000_random_actions_are_deterministic(tb)
def test_space_invaders(self): with Toybox("space_invaders") as tb: self._1000_random_actions_are_deterministic(tb)
if os.path.isfile(fname): with open(fname) as f: data = json.load(f) for k in data.keys(): if k in self.config.keys(): self.config[k] = data[k] self.dirty_config = True def load_models(self): return importlib.import_module(self.modelmod, package=__package__) def make_models(self): self.clz.make_models(self.modelmod, self.data) if __name__ == "__main__": with Toybox('amidar') as tb: state = tb.to_state_json() config = tb.config_to_json() with Intervention(tb, 'amidar') as intervention: intervention.config['enemies'] = [] new_state = intervention.state new_config = intervention.config assert len(config['enemies']) == 5 assert len(new_config['enemies']) == 0 assert len(tb.config_to_json()['enemies']) == 0
class BreakoutInterventionTests(TestCase): def setUp(self): self.tb = Toybox('breakout') fire = Input() fire.button1 = True noop = Input() self.tb.apply_action(fire) def test_allowable_interventions(self): with BreakoutIntervention(self.tb) as intervention: with self.assertRaises(InterventionNoneError): intervention.game.paddle.intervention = None with self.assertRaises(MutationError): intervention.game.paddle.intervention = intervention with self.assertRaises(MutationError): intervention.game.paddle._in_init = True # assert False, 'We should not be able to manulaly set the _in_init flag' self.assertIn('intervention', intervention.game.paddle.immutable_fields) self.assertNotIn('_in_init', intervention.game.paddle.immutable_fields) def test_dirty_state(self): with BreakoutIntervention(self.tb) as intervention: intervention.game.lives = 1 self.assertTrue(intervention.dirty_state) self.assertFalse(intervention.dirty_config) def test_not_dirty_state(self): with BreakoutIntervention(self.tb) as intervention: lives = intervention.game.lives self.assertFalse(intervention.dirty_state) self.assertFalse(intervention.dirty_config) def test_removal_from_collection(self): with BreakoutIntervention(self.tb) as intervention: nbricks = intervention.num_bricks_remaining() intervention.game.bricks[0].alive = False nbricks_post = intervention.num_bricks_remaining() self.assertEqual(nbricks_post, nbricks - 1) # reset and assert that the brick is present with BreakoutIntervention(self.tb) as intervention: nbricks = intervention.num_bricks_remaining() intervention.game.bricks[0].alive = True nbricks_post = intervention.num_bricks_remaining() self.assertEqual(nbricks_post, nbricks + 1) def test_channel_manipulation(self): # add a channel and assert that num_rows bricks have been removed with BreakoutIntervention(self.tb) as intervention: nbricks = intervention.num_bricks_remaining() intervention.add_channel(0) nbricks_post = intervention.num_bricks_remaining() self.assertEqual(nbricks_post, nbricks - intervention.num_rows()) col, channel = intervention.find_channel() self.assertIsNotNone(channel) self.assertEqual(1, intervention.channel_count()) # remove a channel and assert that num_rows bricks have been added with BreakoutIntervention(self.tb) as intervention: nbricks = intervention.num_bricks_remaining() intervention.fill_column(0) nbricks_post = intervention.num_bricks_remaining() self.assertEqual(nbricks_post, nbricks + intervention.num_rows()) def test_brick_color_change(self): with BreakoutIntervention(self.tb) as intervention: b50g_from = intervention.game.bricks[50].color.g intervention.game.bricks[50].color.g = 77 b50g_to = intervention.game.bricks[50].color.g with BreakoutIntervention(self.tb) as intervention: # make sure it was written to the game b50g_to_check = intervention.game.bricks[50].color.g self.assertNotEqual(b50g_from, b50g_to) self.assertEqual(b50g_to, b50g_to_check) def test_get_ball_position(self): # get ball position, even when multiple balls present with BreakoutIntervention(self.tb) as intervention: game = intervention.game self.assertGreater(len(game.balls), 0) ball = game.balls[0] game.balls.append(ball) ball_positions = intervention.get_ball_position() self.assertEqual(len(ball_positions), 2) ball_velocities = intervention.get_ball_velocity() self.assertEqual(len(ball_velocities), 2) game.balls.clear() game.balls.append(ball) # the line above should have triggered an error ball_positions = intervention.get_ball_position() def test_move_diagonally(self): # move ball diagonally by sqrt(2) pixels with BreakoutIntervention(self.tb) as intervention: ball_pos = intervention.get_ball_position() ball_pos.x = ball_pos.x + 1 ball_pos.y = ball_pos.y + 1 with BreakoutIntervention(self.tb) as intervention: ball_pos_post = intervention.get_ball_position() self.assertEqual(ball_pos_post.x, ball_pos.x) ball_pos_post.x = ball_pos.x - 1 ball_pos_post.y = ball_pos.y - 1 with BreakoutIntervention(self.tb) as intervention: ball_pos_post_post = intervention.get_ball_position() self.assertEqual(ball_pos_post.x, ball_pos_post_post.x) def test_change_ball_velocity(self): # change ball velocity with BreakoutIntervention(self.tb) as intervention: ball_vel = intervention.get_ball_velocity() ball_vel.x = ball_vel.x + 1 ball_vel.y = ball_vel.y + 1 ball_vel_post = intervention.get_ball_velocity() self.assertEqual(ball_vel_post.x, ball_vel.x) ball_vel.x = ball_vel.x - 1 ball_vel.y = ball_vel.y - 1 ball_vel_post = intervention.get_ball_velocity() self.assertEqual(ball_vel_post.x, ball_vel.x) def test_move(self): # get paddle position and move with BreakoutIntervention(self.tb) as intervention: pos = intervention.get_paddle_position() self.assertAlmostEqual(pos.x, 120.0) self.assertAlmostEqual(pos.y, 143.0) pos.x = pos.x + 10 pos_post = intervention.get_paddle_position() self.assertAlmostEqual(pos.x, pos_post.x)
def smoke_test(tb): print(tb.get_width(), tb.get_height()) # Score and lives make sense! assert(tb.get_score() == 0) assert(tb.get_lives() > 0) for _ in range(100): # NOOP should work for every game. tb.apply_action(Input()) # Color rendering should work. image = tb.get_rgb_frame() for game in ['amidar', 'breakout', 'space_invaders']: print("TEST ", game) with Toybox(game) as tb: # config -> json should work: config = tb.config_to_json() # state -> json should work: state = tb.state_to_json() actions = tb.get_legal_action_set() print("legal_actions", actions) # setting a seed should work. tb.set_seed(1234) # and all sorts of things make sense: smoke_test(tb) # Writing config should work:
def clear_board(self): """Clears the board of all bricks""" for brick in self.game.bricks: brick.alive = False if __name__ == "__main__": import argparse from ctoybox import Toybox, Input parser = argparse.ArgumentParser(description='test Amidar interventions') parser.add_argument('--partial_config', type=str, default="null") parser.add_argument('--save_json', type=bool, default=False) args = parser.parse_args() with Toybox('breakout') as tb: fire = Input() fire.button1 = True noop = Input() tb.apply_action(fire) state = tb.to_state_json() config = tb.config_to_json() if args.save_json: # save a sample starting state and config with open( 'toybox/toybox/interventions/defaults/breakout_state_default.json', 'w') as outfile: json.dump(state, outfile)
def test_set_property_zero(self): with Toybox('breakout') as tb: with BreakoutIntervention(tb) as intervention: game = intervention.game v = get_property(game, 'bricks[107].points', setval=0) self.assertEqual(v, 0)