def detect_build_order(bo, compare_bo, depth=-1): """Determines how closely two build orders match each other. Args: bo (BuildOrderElement[]): A build order to compare against. compare_bo (BuildOrderElement[]): A build order that will be compared to bo. (depth) (int): Optional. The depth with which to traverse the build order. If not defined (-1), the entire build order will be used. Returns: int: The confidence (0.0 - 1.0) that the compare_bo build order is a derivative of the bo build order. BuildOrderDeviation: The BOD object used to determine the confidence. """ bod = BuildOrderDeviation(bo) bod.calculate_deviations(compare_bo, depth) #order_dev = bod.get_scaled_order_dev() ## there could be more accuracy if the discrepencies were split into 4 categories: ## worker, army, building, upgrade and a NN trained on those inputs instead. #discrepencies = bod.get_scaled_discrepency() #confidence = BuildOrderDetect._nn3_feed_forward(order_dev, discrepencies) #nn = BuildOrderDetect._get_nn() #confidence = nn.feed_forward([order_dev, discrepencies])[0] confidence = BuildOrderDetect._get_confidence(bod) return confidence, bod
def test_time_deviation_calculated_correctly_when_early_on_time(self): golden_bo = [] compare_bo = [] golden_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) golden_bo.append(BuildOrderElement(2, 'Assimilator', 15, 50, 200)) compare_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) compare_bo.append(BuildOrderElement(2, 'Assimilator', 15, 40, 200)) bo_dev = BuildOrderDeviation(golden_bo) bo_dev.calculate_deviations(compare_bo) self.assertEqual(bo_dev.time_dev, 10)
def test_order_dev_p_is_correct_when_build_unit_is_missing(self): golden_bo = [] compare_bo = [] golden_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) golden_bo.append(BuildOrderElement(2, 'Pylon', 14, 20, 90)) golden_bo.append(BuildOrderElement(3, 'Assimilator', 15, 50, 200)) compare_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) compare_bo.append(BuildOrderElement(2, 'Assimilator', 16, 50, 200)) bo_dev = BuildOrderDeviation(golden_bo) bo_dev.calculate_deviations(compare_bo) self.assertEqual(bo_dev.order_dev_p, 1)
def test_discrepencies_when_missing_build_order_units(self): golden_bo = [] compare_bo = [] golden_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) golden_bo.append(BuildOrderElement(2, 'Pylon', 14, 20, 90)) golden_bo.append(BuildOrderElement(3, 'Assimilator', 15, 50, 200)) compare_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) compare_bo.append(BuildOrderElement(2, 'Assimilator', 15, 50, 200)) bo_dev = BuildOrderDeviation(golden_bo) bo_dev.calculate_deviations(compare_bo, depth=3) self.assertEqual(bo_dev.discrepency, 1)
def test_depth_when_depth_is_greater_than_bench_bo(self): golden_bo = [] compare_bo = [] golden_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) golden_bo.append(BuildOrderElement(2, 'Pylon', 14, 20, 90)) compare_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) compare_bo.append(BuildOrderElement(2, 'Pylon', 14, 20, 90)) compare_bo.append(BuildOrderElement(3, 'Assimilator', 16, 51, 201)) bo_dev = BuildOrderDeviation(golden_bo) bo_dev.calculate_deviations(compare_bo, depth=3) self.assertEqual(bo_dev.dev, 0) self.assertEqual(bo_dev.discrepency, 0)
def test_dev_arr_is_correct_size_when_build_order_is_correct(self): golden_bo = [] compare_bo = [] golden_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) golden_bo.append(BuildOrderElement(2, 'Pylon', 14, 20, 90)) golden_bo.append(BuildOrderElement(3, 'Assimilator', 15, 50, 200)) compare_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) compare_bo.append(BuildOrderElement(2, 'Pylon', 14, 20, 90)) compare_bo.append(BuildOrderElement(3, 'Assimilator', 15, 50, 200)) bo_dev = BuildOrderDeviation(golden_bo) bo_dev.calculate_deviations(compare_bo) self.assertEqual(3, len(bo_dev.bode_arr))
def test_scaled_tag_order_dev_is_correct_when_elements_are_missing(self): golden_bo = [] compare_bo = [] golden_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) golden_bo.append(BuildOrderElement(2, 'Pylon', 14, 20, 90)) golden_bo.append(BuildOrderElement(3, 'Assimilator', 15, 50, 200)) compare_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) compare_bo.append(BuildOrderElement(2, 'Probe', 12, 0, 0)) compare_bo.append(BuildOrderElement(3, 'Assimilator', 15, 50, 200)) bo_dev = BuildOrderDeviation(golden_bo) bo_dev.calculate_deviations(compare_bo) self.assertEqual(1 / 6, bo_dev.get_scaled_tag_order_dev(uc.SUPPLY_TAG))
def test_avg_order_dev_is_zero_when_builds_have_not_deviated(self): golden_bo = [] compare_bo = [] golden_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) golden_bo.append(BuildOrderElement(2, 'Pylon', 14, 20, 90)) golden_bo.append(BuildOrderElement(3, 'Assimilator', 15, 50, 200)) compare_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) compare_bo.append(BuildOrderElement(2, 'Pylon', 14, 20, 90)) compare_bo.append(BuildOrderElement(3, 'Assimilator', 15, 50, 200)) bo_dev = BuildOrderDeviation(golden_bo) bo_dev.calculate_deviations(compare_bo) self.assertEqual(0, bo_dev.get_average_order_dev())
def test_deviation_is_zero_when_builds_are_exactly_the_same(self): golden_bo = [] compare_bo = [] golden_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) golden_bo.append(BuildOrderElement(2, 'Pylon', 14, 20, 90)) golden_bo.append(BuildOrderElement(3, 'Assimilator', 15, 50, 200)) compare_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) compare_bo.append(BuildOrderElement(2, 'Pylon', 14, 20, 90)) compare_bo.append(BuildOrderElement(3, 'Assimilator', 15, 50, 200)) bo_dev = BuildOrderDeviation(golden_bo) bo_dev.calculate_deviations(compare_bo) self.assertEqual(bo_dev.dev, 0)
def test_time_dev_p_is_zero_when_build_unit_is_not_missing(self): golden_bo = [] compare_bo = [] golden_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) golden_bo.append(BuildOrderElement(2, 'Pylon', 14, 20, 90)) golden_bo.append(BuildOrderElement(3, 'Assimilator', 15, 50, 200)) compare_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) compare_bo.append(BuildOrderElement(2, 'Pylon', 14, 25, 95)) compare_bo.append(BuildOrderElement(3, 'Assimilator', 15, 55, 205)) bo_dev = BuildOrderDeviation(golden_bo) bo_dev.calculate_deviations(compare_bo) self.assertEqual(bo_dev.time_dev_p, 0)
def test_tag_order_dev_p_is_not_incremented_when_units_do_not_differ(self): golden_bo = [] compare_bo = [] golden_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) golden_bo.append(BuildOrderElement(2, 'Pylon', 14, 20, 90)) golden_bo.append(BuildOrderElement(3, 'Assimilator', 15, 50, 200)) compare_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) compare_bo.append(BuildOrderElement(2, 'Pylon', 14, 20, 90)) compare_bo.append(BuildOrderElement(3, 'Assimilator', 15, 50, 200)) bo_dev = BuildOrderDeviation(golden_bo) bo_dev.calculate_deviations(compare_bo) self.assertFalse(uc.BUILDING_TAG in bo_dev.tag_order_dev_p) self.assertFalse(uc.SUPPLY_TAG in bo_dev.tag_order_dev_p)
def test_time_deviation_calculated_correctly_when_build_is_missing_element( self): golden_bo = [] compare_bo = [] golden_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) golden_bo.append(BuildOrderElement(2, 'Pylon', 14, 20, 90)) golden_bo.append(BuildOrderElement(3, 'Assimilator', 15, 50, 200)) compare_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) compare_bo.append(BuildOrderElement(2, 'Assimilator', 15, 50, 200)) bo_dev = BuildOrderDeviation(golden_bo) bo_dev.calculate_deviations(compare_bo) #self.assertEqual(bo_dev.time_dev, 30) self.assertEqual(bo_dev.time_dev, 0)
def test_order_dev_p_is_correct_when_build_unit_is_not_missing_but_greater_than_ORDER_DEV_GRACE( self): golden_bo = [] compare_bo = [] golden_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) golden_bo.append(BuildOrderElement(2, 'Pylon', 14, 20, 90)) golden_bo.append(BuildOrderElement(3, 'Assimilator', 15, 50, 200)) compare_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) compare_bo.append(BuildOrderElement(2, 'Assimilator', 16, 55, 205)) compare_bo.append(BuildOrderElement(23, 'Pylon', 17, 65, 215)) bo_dev = BuildOrderDeviation(golden_bo) bo_dev.calculate_deviations(compare_bo) self.assertEqual(bo_dev.tag_order_dev_p[uc.SUPPLY_TAG], 1)
def test_tag_order_dev_p_calculated_correctly_when_build_has_different_element( self): golden_bo = [] compare_bo = [] golden_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) golden_bo.append(BuildOrderElement(2, 'Pylon', 14, 20, 90)) golden_bo.append(BuildOrderElement(3, 'Assimilator', 15, 50, 200)) compare_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) compare_bo.append(BuildOrderElement(2, 'Probe', 14, 20, 90)) compare_bo.append(BuildOrderElement(3, 'Assimilator', 15, 50, 200)) bo_dev = BuildOrderDeviation(golden_bo) bo_dev.calculate_deviations(compare_bo) self.assertEqual(bo_dev.tag_order_dev_p[uc.SUPPLY_TAG], 1)
def test_order_deviation_calculated_correctly_when_build_order_deviation_occurred( self): golden_bo = [] compare_bo = [] golden_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) golden_bo.append(BuildOrderElement(2, 'Pylon', 14, 20, 90)) golden_bo.append(BuildOrderElement(3, 'Assimilator', 15, 50, 200)) compare_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) compare_bo.append(BuildOrderElement(2, 'Assimilator', 15, 50, 200)) compare_bo.append(BuildOrderElement(3, 'Pylon', 16, 60, 220)) bo_dev = BuildOrderDeviation(golden_bo) bo_dev.calculate_deviations(compare_bo) self.assertEqual(bo_dev.order_dev, 2)
def test_order_deviation_isnt_affected_when_build_order_deviates_by_more_than_20_beyond_last_build_unit( self): golden_bo = [] compare_bo = [] golden_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) golden_bo.append(BuildOrderElement(2, 'Pylon', 14, 20, 90)) golden_bo.append(BuildOrderElement(3, 'Assimilator', 15, 50, 200)) compare_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) compare_bo.append(BuildOrderElement(3, 'Assimilator', 15, 50, 200)) compare_bo.append(BuildOrderElement(24, 'Pylon', 14, 20, 90)) bo_dev = BuildOrderDeviation(golden_bo) bo_dev.calculate_deviations(compare_bo) self.assertEqual(bo_dev.order_dev, 0)
def test_avg_order_dev_is_correct_when_elements_are_ordered_different_and_missing( self): golden_bo = [] compare_bo = [] golden_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) golden_bo.append(BuildOrderElement(2, 'Pylon', 14, 20, 90)) golden_bo.append(BuildOrderElement(3, 'Assimilator', 15, 50, 200)) compare_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) compare_bo.append(BuildOrderElement(2, 'Assimilator', 15, 50, 200)) compare_bo.append(BuildOrderElement(3, 'Probe', 12, 0, 0)) bo_dev = BuildOrderDeviation(golden_bo) bo_dev.calculate_deviations(compare_bo) # deviation are: 0, 1, 1 self.assertEqual(1, bo_dev.get_average_order_dev())
def test_scaled_tag_order_dev_is_zero_when_tag_has_not_occurred_in_build( self): golden_bo = [] compare_bo = [] golden_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) golden_bo.append(BuildOrderElement(2, 'Pylon', 14, 20, 90)) golden_bo.append(BuildOrderElement(3, 'Assimilator', 15, 50, 200)) compare_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) compare_bo.append(BuildOrderElement(2, 'Probe', 12, 0, 0)) compare_bo.append(BuildOrderElement(3, 'Pylon', 14, 20, 90)) compare_bo.append(BuildOrderElement(4, 'Assimilator', 15, 50, 200)) bo_dev = BuildOrderDeviation(golden_bo) bo_dev.calculate_deviations(compare_bo) self.assertEqual(0, bo_dev.get_scaled_tag_order_dev(uc.ARMY_TAG))
def test_tag_order_dev_p_is_incremented_when_build_order_element_is_missing( self): golden_bo = [] compare_bo = [] golden_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) golden_bo.append(BuildOrderElement(2, 'Pylon', 14, 20, 90)) golden_bo.append(BuildOrderElement(3, 'Assimilator', 15, 50, 200)) compare_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) compare_bo.append(BuildOrderElement(2, 'Assimilator', 15, 50, 200)) compare_bo.append(BuildOrderElement(3, 'Probe', 12, 0, 0)) bo_dev = BuildOrderDeviation(golden_bo) bo_dev.calculate_deviations(compare_bo) self.assertEqual(bo_dev.tag_order_dev_p[uc.BUILDING_TAG], 1) self.assertEqual(bo_dev.tag_order_dev_p[uc.SUPPLY_TAG], 1)
def test_build_order_comparison_is_limited_when_setting_build_num_limitor( self): golden_bo = [] compare_bo = [] golden_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) golden_bo.append(BuildOrderElement(2, 'Pylon', 14, 20, 90)) golden_bo.append(BuildOrderElement(3, 'Assimilator', 15, 50, 200)) compare_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) compare_bo.append(BuildOrderElement(2, 'Pylon', 14, 20, 90)) compare_bo.append(BuildOrderElement(3, 'Assimilator', 16, 51, 201)) bo_dev = BuildOrderDeviation(golden_bo) bo_dev.calculate_deviations(compare_bo, depth=2) self.assertEqual(bo_dev.dev, 0) self.assertEqual(bo_dev.discrepency, 0)
def test_discrepencies_are_none_when_additional_build_order_units_are_present_beyond_bench_bo( self): golden_bo = [] compare_bo = [] golden_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) golden_bo.append(BuildOrderElement(2, 'Pylon', 14, 20, 90)) golden_bo.append(BuildOrderElement(3, 'Assimilator', 15, 50, 200)) compare_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) compare_bo.append(BuildOrderElement(2, 'Pylon', 14, 20, 90)) compare_bo.append(BuildOrderElement(3, 'Assimilator', 15, 50, 200)) compare_bo.append(BuildOrderElement(4, 'Pylon', 16, 51, 201)) bo_dev = BuildOrderDeviation(golden_bo) bo_dev.calculate_deviations(compare_bo) self.assertEqual(bo_dev.discrepency, 0)
def test_tag_order_dev_is_incremented_when_multiple_elements_with_the_same_tag_have_differing_order( self): golden_bo = [] compare_bo = [] golden_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) golden_bo.append(BuildOrderElement(2, 'Pylon', 14, 20, 90)) golden_bo.append(BuildOrderElement(3, 'Assimilator', 15, 50, 200)) compare_bo.append(BuildOrderElement(1, 'Probe', 12, 0, 0)) compare_bo.append(BuildOrderElement(2, 'Probe', 12, 0, 0)) compare_bo.append(BuildOrderElement(3, 'Pylon', 14, 20, 90)) compare_bo.append(BuildOrderElement(4, 'Assimilator', 15, 50, 200)) bo_dev = BuildOrderDeviation(golden_bo) bo_dev.calculate_deviations(compare_bo) self.assertEqual(bo_dev.tag_order_dev[uc.BUILDING_TAG], 2)