def testRemovedField(self): a = sc_pb.ResponseObservation(observation=sc_pb.Observation( game_loop=1)) b = sc_pb.ResponseObservation(observation=sc_pb.Observation()) diff = proto_diff.compute_diff(a, b) self.assertIsNotNone(diff) self.assertLen(diff.removed, 1, diff) self.assertEqual(str(diff.removed[0]), "observation.game_loop") self.assertEqual(diff.removed, diff.all_diffs()) self.assertEqual(diff.report(), "Removed observation.game_loop.")
def testTruncation(self): a = sc_pb.ResponseObservation(observation=sc_pb.Observation( game_loop=1, alerts=[sc_pb.AlertError, sc_pb.LarvaHatched])) b = sc_pb.ResponseObservation(observation=sc_pb.Observation( game_loop=2, alerts=[sc_pb.AlertError, sc_pb.MergeComplete])) diff = proto_diff.compute_diff(a, b) self.assertIsNotNone(diff) self.assertEqual( diff.report([_alert_formatter], truncate_to=9), "Changed observation.alerts[1]: LarvaH....\n" "Changed observation.game_loop: 1 -> 2.") self.assertEqual( diff.report([_alert_formatter], truncate_to=-1), "Changed observation.alerts[1]: ....\n" "Changed observation.game_loop: ... -> ....")
def testAddedFields(self): a = sc_pb.ResponseObservation(observation=sc_pb.Observation( alerts=[sc_pb.AlertError])) b = sc_pb.ResponseObservation(observation=sc_pb.Observation( alerts=[sc_pb.AlertError, sc_pb.MergeComplete]), player_result=[sc_pb.PlayerResult()]) diff = proto_diff.compute_diff(a, b) self.assertIsNotNone(diff) self.assertLen(diff.added, 2, diff) self.assertEqual(str(diff.added[0]), "observation.alerts[1]") self.assertEqual(str(diff.added[1]), "player_result") self.assertEqual(diff.added, diff.all_diffs()) self.assertEqual( diff.report(), "Added observation.alerts[1].\n" "Added player_result.")
def testRemovedFields(self): a = sc_pb.ResponseObservation(observation=sc_pb.Observation( game_loop=1, score=score_pb2.Score(), alerts=[sc_pb.AlertError, sc_pb.MergeComplete])) b = sc_pb.ResponseObservation(observation=sc_pb.Observation( alerts=[sc_pb.AlertError])) diff = proto_diff.compute_diff(a, b) self.assertIsNotNone(diff) self.assertLen(diff.removed, 3, diff) self.assertEqual(str(diff.removed[0]), "observation.alerts[1]") self.assertEqual(str(diff.removed[1]), "observation.game_loop") self.assertEqual(str(diff.removed[2]), "observation.score") self.assertEqual(diff.removed, diff.all_diffs()) self.assertEqual( diff.report(), "Removed observation.alerts[1].\n" "Removed observation.game_loop.\n" "Removed observation.score.")
def testChangedFields(self): a = sc_pb.ResponseObservation(observation=sc_pb.Observation( game_loop=1, alerts=[sc_pb.AlertError, sc_pb.LarvaHatched])) b = sc_pb.ResponseObservation(observation=sc_pb.Observation( game_loop=2, alerts=[sc_pb.AlertError, sc_pb.MergeComplete])) diff = proto_diff.compute_diff(a, b) self.assertIsNotNone(diff) self.assertLen(diff.changed, 2, diff) self.assertEqual(str(diff.changed[0]), "observation.alerts[1]") self.assertEqual(str(diff.changed[1]), "observation.game_loop") self.assertEqual(diff.changed, diff.all_diffs()) self.assertEqual( diff.report(), "Changed observation.alerts[1]: 7 -> 8.\n" "Changed observation.game_loop: 1 -> 2.") self.assertEqual( diff.report([_alert_formatter]), "Changed observation.alerts[1]: LarvaHatched -> MergeComplete.\n" "Changed observation.game_loop: 1 -> 2.")
def main(argv): """Compare the observations from multiple binaries.""" if len(argv) <= 1: sys.exit( "Please specify binaries to run / to connect to. For binaries to run, " "specify the executable name. For remote connections, specify " "<hostname>:<port>. The version must match the replay.") targets = argv[1:] interface = sc_pb.InterfaceOptions() interface.raw = True interface.raw_affects_selection = True interface.raw_crop_to_playable_area = True interface.score = True interface.show_cloaked = True interface.show_placeholders = True interface.feature_layer.width = 24 interface.feature_layer.resolution.x = 48 interface.feature_layer.resolution.y = 48 interface.feature_layer.minimap_resolution.x = 48 interface.feature_layer.minimap_resolution.y = 48 interface.feature_layer.crop_to_playable_area = True interface.feature_layer.allow_cheating_layers = True run_config = run_configs.get() replay_data = run_config.replay_data(FLAGS.replay) start_replay = sc_pb.RequestStartReplay(replay_data=replay_data, options=interface, observed_player_id=1, realtime=False) version = replay.get_replay_version(replay_data) timers = [] controllers = [] procs = [] for target in targets: timer = stopwatch.StopWatch() timers.append(timer) with timer("launch"): if _is_remote(target): host, port = target.split(":") controllers.append( remote_controller.RemoteController(host, int(port))) else: proc = run_configs.get(version=version._replace( binary=target)).start(want_rgb=False) procs.append(proc) controllers.append(proc.controller) diff_counts = [0] * len(controllers) diff_paths = all_collections_generated_classes.Counter() try: print("-" * 80) print(controllers[0].replay_info(replay_data)) print("-" * 80) for controller, t in zip(controllers, timers): with t("start_replay"): controller.start_replay(start_replay) # Check the static data. static_data = [] for controller, t in zip(controllers, timers): with t("data"): static_data.append(controller.data_raw()) if FLAGS.diff: diffs = { i: proto_diff.compute_diff(static_data[0], d) for i, d in enumerate(static_data[1:], 1) } if any(diffs.values()): print(" Diff in static data ".center(80, "-")) for i, diff in diffs.items(): if diff: print(targets[i]) diff_counts[i] += 1 print(diff.report(truncate_to=FLAGS.truncate)) for path in diff.all_diffs(): diff_paths[ path.with_anonymous_array_indices()] += 1 else: print("No diffs in static data.") # Run some steps, checking speed and diffing the observations. for _ in range(FLAGS.count): for controller, t in zip(controllers, timers): with t("step"): controller.step(FLAGS.step_mul) obs = [] for controller, t in zip(controllers, timers): with t("observe"): obs.append(controller.observe()) if FLAGS.diff: for o in obs: _clear_non_deterministic_fields(o) diffs = { i: proto_diff.compute_diff(obs[0], o) for i, o in enumerate(obs[1:], 1) } if any(diffs.values()): print((" Diff on step: %s " % obs[0].observation.game_loop).center(80, "-")) for i, diff in diffs.items(): if diff: print(targets[i]) diff_counts[i] += 1 print( diff.report( [image_differencer.image_differencer], truncate_to=FLAGS.truncate)) for path in diff.all_diffs(): diff_paths[ path.with_anonymous_array_indices()] += 1 if obs[0].player_result: break except KeyboardInterrupt: pass finally: for c in controllers: c.quit() c.close() for p in procs: p.close() if FLAGS.diff: print(" Diff Counts by target ".center(80, "-")) for target, count in zip(targets, diff_counts): print(" %5d %s" % (count, target)) print() print(" Diff Counts by observation path ".center(80, "-")) for path, count in diff_paths.most_common(100): print(" %5d %s" % (count, path)) print() print(" Timings ".center(80, "-")) for v, t in zip(targets, timers): print(v) print(t)
def testNoDiffs(self): a = sc_pb.ResponseObservation() b = sc_pb.ResponseObservation() diff = proto_diff.compute_diff(a, b) self.assertIsNone(diff)