Skip to content

Commit

Permalink
implement replay scoring
Browse files Browse the repository at this point in the history
- add credit events
- catch an error in placeholders
- add test with settings and replay score
  • Loading branch information
jabdoa2 committed Apr 28, 2017
1 parent de92bd1 commit c3f8a26
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 20 deletions.
4 changes: 4 additions & 0 deletions mpf/core/config_spec.py
Expand Up @@ -281,6 +281,10 @@
switch: single|machine(switches)|None
value: single|float|0.25
type: single|str|money
events:
event: single|str|None
credits: single|float|0.25
type: single|str|replay
pricing_tiers:
price: single|float|.50
credits: single|int|1
Expand Down
7 changes: 5 additions & 2 deletions mpf/core/placeholder_manager.py
Expand Up @@ -254,8 +254,11 @@ def _eval_unary_op(self, node, variables):
def _eval_compare(self, node, variables):
if len(node.ops) > 1:
raise AssertionError("Only single comparisons are supported.")
return comparisons[type(node.ops[0])](self._eval(node.left, variables),
self._eval(node.comparators[0], variables))
try:
return comparisons[type(node.ops[0])](self._eval(node.left, variables),
self._eval(node.comparators[0], variables))
except TypeError as e:
raise ValueError("Comparison failed: {}".format(e))

def _eval_bool_op(self, node, variables):
result = self._eval(node.values[0], variables)
Expand Down
53 changes: 35 additions & 18 deletions mpf/modes/credits/code/credits.py
Expand Up @@ -59,7 +59,7 @@ def mode_start(self, **kwargs):
def mode_stop(self, **kwargs):
"""Stop mode."""
self._set_free_play_string()
self._disable_credit_switch_handlers()
self._disable_credit_handlers()

def _calculate_credit_units(self):
# "credit units" are how we handle fractional credits (since most
Expand Down Expand Up @@ -106,7 +106,7 @@ def _calculate_credit_units(self):

self.credit_units_per_game = int(price_per_game / self.credit_unit)

self.debug_log("Credit units per game: %s", self.credit_units_per_game)
self.info_log("Credit units per game: %s", self.credit_units_per_game)

def _calculate_pricing_tiers(self):
# pricing tiers are calculated with a set of tuples which indicate the
Expand Down Expand Up @@ -184,7 +184,7 @@ def enable_credit_play(self, post_event=True, **kwargs):

self._update_credit_strings()

self._enable_credit_switch_handlers()
self._enable_credit_handlers()

# prevent duplicate handlers
self._remove_event_handlers()
Expand Down Expand Up @@ -226,7 +226,7 @@ def enable_free_play(self, post_event=True, **kwargs):

self._remove_event_handlers()

self._disable_credit_switch_handlers()
self._disable_credit_handlers()

self._update_credit_strings()

Expand Down Expand Up @@ -257,11 +257,11 @@ def _player_add_request(self, **kwargs):
del kwargs
if (self._get_credit_units() >=
self.credit_units_per_game):
self.debug_log("Received request to add player. Request Approved")
self.info_log("Received request to add player. Request Approved. Sufficient credits available.")
return True

else:
self.debug_log("Received request to add player. Request Denied")
self.info_log("Received request to add player. Request Denied. Not enough credits available.")
self.machine.events.post("not_enough_credits")
'''event: not_enough_credits
desc: A player has pushed the start button, but the game is not set
Expand All @@ -274,11 +274,11 @@ def _request_to_start_game(self, **kwargs):
del kwargs
if (self._get_credit_units() >=
self.credit_units_per_game):
self.debug_log("Received request to start game. Request Approved")
self.info_log("Received request to start game. Request Approved. Sufficient credits available.")
return True

else:
self.debug_log("Received request to start game. Request Denied")
self.info_log("Received request to start game. Request Denied. Not enough credits available.")
self.machine.events.post("not_enough_credits")
# event docstring covered in _player_add_request() method
return False
Expand All @@ -289,14 +289,14 @@ def _player_added(self, **kwargs):
self.credit_units_per_game)

if new_credit_units < 0:
self.log.warning("Somehow credit units went below 0?!? Resetting "
self.warning_log("Somehow credit units went below 0?!? Resetting "
"to 0.")
new_credit_units = 0

self.machine.set_machine_var('credit_units', new_credit_units)
self._update_credit_strings()

def _enable_credit_switch_handlers(self):
def _enable_credit_handlers(self):
for switch_settings in self.credits_config['switches']:
self.machine.switch_controller.add_switch_handler(
switch_name=switch_settings['switch'].name,
Expand All @@ -309,24 +309,41 @@ def _enable_credit_switch_handlers(self):
switch_name=switch.name,
callback=self._service_credit_callback)

def _disable_credit_switch_handlers(self):
for event_settings in self.credits_config['events']:
self.machine.events.add_handler(
event=event_settings['event'],
handler=self._credit_event_callback,
credits=event_settings['credits'],
audit_class=event_settings['type'])

def _disable_credit_handlers(self):
for switch_settings in self.credits_config['switches']:
self.machine.switch_controller.remove_switch_handler(
switch_name=switch_settings['switch'].name,
callback=self._credit_switch_callback)

self.machine.events.remove_handler(self._credit_event_callback)

for switch in self.credits_config['service_credits_switch']:
self.machine.switch_controller.remove_switch_handler(
switch_name=switch.name,
callback=self._service_credit_callback)

def _credit_switch_callback(self, value, audit_class):
self.info_log("Credit switch hit. Credit Added. Value: %s. Type: %s", value, audit_class)
self._add_credit_units(credit_units=value / self.credit_unit)
self._audit(value, audit_class)
self._reset_timeouts()

def _credit_event_callback(self, credits, audit_class, **kwargs):
del kwargs
self.info_log("Credit event hit. Credit Added. Credits: %s. Type: %s", credits, audit_class)
self._add_credit_units(credit_units=credits * self.credit_units_per_game, price_tiering=False)
self._audit(credits, audit_class)
self._reset_timeouts()

def _service_credit_callback(self):
self.debug_log("Service Credit Added")
self.info_log("Service Credit Added. Value: 1.")
self.add_credit(price_tiering=False)
self._audit(1, 'service_credit')

Expand All @@ -351,7 +368,7 @@ def _add_credit_units(self, credit_units, price_tiering=True):
self.credit_units_per_game)

if max_credit_units and total_credit_units > max_credit_units:
self.debug_log("Max credits reached")
self.info_log("Max credits reached.")
self._update_credit_strings()
self.machine.events.post('max_credits_reached')
'''event: max_credits_reached
Expand All @@ -360,7 +377,7 @@ def _add_credit_units(self, credit_units, price_tiering=True):
self.machine.set_machine_var('credit_units', max_credit_units)

if max_credit_units <= 0 or max_credit_units > previous_credit_units:
self.debug_log("Credit units added")
self.info_log("Credit units added")
self.machine.set_machine_var('credit_units', total_credit_units)
self._update_credit_strings()
self.machine.events.post('credits_added')
Expand All @@ -380,7 +397,7 @@ def add_credit(self, price_tiering=True):

def _reset_pricing_tier_credits(self):
if not self.reset_pricing_tier_count_this_game:
self.debug_log("Resetting pricing tier credit count")
self.info_log("Resetting pricing tier credit count.")
self.credit_units_for_pricing_tiers = 0
self.reset_pricing_tier_count_this_game = True

Expand Down Expand Up @@ -439,7 +456,7 @@ def _audit(self, value, audit_class):

def _game_started(self, **kwargs):
del kwargs
self.debug_log("Removing credit clearing delays")
self.debug_log("Removing credit clearing delays.")
self.delay.remove('clear_fractional_credits')
self.delay.remove('clear_all_credits')

Expand All @@ -465,7 +482,7 @@ def _game_ended(self, **kwargs):
self.reset_pricing_tier_count_this_game = False

def _clear_fractional_credits(self):
self.debug_log("Clearing fractional credits")
self.info_log("Clearing fractional credits.")

credit_units = self._get_credit_units()
credit_units -= credit_units % self.credit_units_per_game
Expand All @@ -476,6 +493,6 @@ def _clear_fractional_credits(self):
def clear_all_credits(self, **kwargs):
"""Clear all credits."""
del kwargs
self.debug_log("Clearing all credits")
self.info_log("Clearing all credits.")
self.machine.set_machine_var('credit_units', 0)
self._update_credit_strings()
3 changes: 3 additions & 0 deletions mpf/tests/MpfTestCase.py
Expand Up @@ -278,6 +278,9 @@ def _wait_for_start(self, init, timeout):
if time.time() > start + timeout:
raise AssertionError("Start took more than {}s".format(timeout))

# trigger exception if there was one
init.result()

def _mock_event_handler(self, event_name, **kwargs):
self._last_event_kwargs[event_name] = kwargs
self._events[event_name] += 1
Expand Down
15 changes: 15 additions & 0 deletions mpf/tests/machine_files/credits/config/config.yaml
Expand Up @@ -23,6 +23,17 @@ coils:
c_eject:
number:

settings:
replay_score:
label: Replay Score
values:
500000: "500000 (default)"
1000000: "1000000"
1500000: "1500000"
default: 500000
key_type: int
sort: 100

credits:
max_credits: 12
free_play: no
Expand All @@ -37,6 +48,10 @@ credits:
- switch: s_right_coin
type: money
value: 1
events:
- event: game_ending{current_player.score > settings.replay_score}
type: award
credits: 1
pricing_tiers:
- price: .50
credits: 1
Expand Down
27 changes: 27 additions & 0 deletions mpf/tests/test_CreditsMode.py
Expand Up @@ -136,6 +136,33 @@ def testCredits(self):
self.machine_run()
self.assertEqual("CREDITS 3", self.machine.get_machine_var('credits_string'))

def testReplay(self):
# add coins
self.hit_and_release_switch("s_left_coin")
self.hit_and_release_switch("s_left_coin")
self.advance_time_and_run()
self.assertEqual("CREDITS 1", self.machine.get_machine_var('credits_string'))
# start game
self.start_game(True)

self.assertEqual("CREDITS 0", self.machine.get_machine_var('credits_string'))
# no replay
self.stop_game()

# try again
self.hit_and_release_switch("s_left_coin")
self.hit_and_release_switch("s_left_coin")
self.advance_time_and_run()
self.assertEqual("CREDITS 1", self.machine.get_machine_var('credits_string'))
self.start_game(True)

# score 600k
self.machine.game.player.score = 600000

# replay credit on game end
self.stop_game()
self.assertEqual("CREDITS 1", self.machine.get_machine_var('credits_string'))

def testMorePlayers(self):
self.assertTrue(self.machine.mode_controller.is_active('credits'))
self.assertEqual("CREDITS 0", self.machine.get_machine_var('credits_string'))
Expand Down

0 comments on commit c3f8a26

Please sign in to comment.