diff --git a/pythonwarrior/abilities/listen.py b/pythonwarrior/abilities/listen.py index a9b723f..ad58d66 100644 --- a/pythonwarrior/abilities/listen.py +++ b/pythonwarrior/abilities/listen.py @@ -10,8 +10,8 @@ def _collect_non_warrior_spaces(unit): if unit and unit != self._unit: return unit.position.space() - units = map(_collect_non_warrior_spaces, - self._unit.position.floor.units) - units = filter(lambda x: x, units) + units = list(map(_collect_non_warrior_spaces, + self._unit.position.floor.units)) + units = [x for x in units if x] return units diff --git a/pythonwarrior/abilities/look.py b/pythonwarrior/abilities/look.py index 688166a..0fd2a00 100644 --- a/pythonwarrior/abilities/look.py +++ b/pythonwarrior/abilities/look.py @@ -8,4 +8,4 @@ def description(self): def perform(self, direction='forward'): self.verify_direction(direction) - return map(lambda amount: self.space(direction, amount), [1, 2, 3]) + return [self.space(direction, amount) for amount in [1, 2, 3]] diff --git a/pythonwarrior/abilities/shoot.py b/pythonwarrior/abilities/shoot.py index fa8c1fb..776ca0e 100644 --- a/pythonwarrior/abilities/shoot.py +++ b/pythonwarrior/abilities/shoot.py @@ -8,8 +8,8 @@ def description(self): def perform(self, direction='forward'): self.verify_direction(direction) - units = self.multi_unit(direction, range(1, 4)) - units = filter(lambda unit: unit, units) + units = self.multi_unit(direction, list(range(1, 4))) + units = [unit for unit in units if unit] if len(units): receiver = units[0] self._unit.say("shoots %(direction)s and hits %(receiver)s" % @@ -19,4 +19,4 @@ def perform(self, direction='forward'): self._unit.say("shoots and hits nothing") def multi_unit(self, direction, range_list): - return map(lambda n: self.unit(direction, n), range_list) + return [self.unit(direction, n) for n in range_list] diff --git a/pythonwarrior/floor.py b/pythonwarrior/floor.py index 15c5bce..dcc9cc8 100644 --- a/pythonwarrior/floor.py +++ b/pythonwarrior/floor.py @@ -21,11 +21,10 @@ def stairs_space(self): @property def units(self): - return filter(lambda unit: unit.position is not None, self._units) + return [unit for unit in self._units if unit.position is not None] def other_units(self): - return filter(lambda unit: unit.__class__.__name__ != 'Warrior', - self.units) + return [unit for unit in self.units if unit.__class__.__name__ != 'Warrior'] def get(self, x, y): for unit in self.units: @@ -55,8 +54,7 @@ def character(self): def unique_units(self): uniq_units = [] for unit in self.units: - uniq_classes = map(lambda unit: unit.__class__.__name__, - uniq_units) + uniq_classes = [unit.__class__.__name__ for unit in uniq_units] uniq_classes = list(set(uniq_classes)) if not unit.__class__.__name__ in uniq_classes: uniq_units.append(unit) diff --git a/pythonwarrior/game.py b/pythonwarrior/game.py index d947e95..caf0a07 100644 --- a/pythonwarrior/game.py +++ b/pythonwarrior/game.py @@ -138,7 +138,7 @@ def go_back_to_normal_mode(self): 'pythonwarrior/%s directory' % self.profile().directory_name()) def profiles(self): - return map(lambda profile: Profile.load(profile), self.profile_paths()) + return [Profile.load(profile) for profile in self.profile_paths()] def profile_paths(self): return glob.glob(Config.path_prefix + '/pythonwarrior/**/.profile') @@ -155,12 +155,13 @@ def new_profile(self): return profile def towers(self): - return map(lambda path: Tower(path), self.tower_paths()) + return [Tower(path) for path in self.tower_paths()] def tower_paths(self): tower_paths = glob.glob(os.path.normpath(os.path.abspath(__file__) + '/../towers/*')) - tower_paths = filter(lambda path: os.path.isdir(path), tower_paths) + tower_paths = [path for path in tower_paths + if os.path.isdir(path) and '__' not in path] return tower_paths def current_level(self): @@ -185,8 +186,7 @@ def choose_profile(self): self.profiles() + [['new', 'New Profile']]) if profile == 'new': profile = self.new_profile() - if filter(lambda prof: prof.player_path == profile.player_path, - self.profiles()): + if [prof for prof in self.profiles() if prof.player_path == profile.player_path]: if UI.ask('Are you sure you want to replace your existing' 'profile for this tower?'): UI.puts('Replacing existing profile.') diff --git a/pythonwarrior/level.py b/pythonwarrior/level.py index 3f291de..a59052b 100644 --- a/pythonwarrior/level.py +++ b/pythonwarrior/level.py @@ -97,7 +97,7 @@ def tally_points(self): UI.puts('Total Score: %s' % self.score_calculation(self.profile.score, score)) self.profile.score += score - self.profile.abilities = self.warrior.abilities.keys() + self.profile.abilities = list(self.warrior.abilities.keys()) def grade_for(self, score): if self.ace_score: diff --git a/pythonwarrior/level_loader.py b/pythonwarrior/level_loader.py index 9dcb75d..3f193b5 100644 --- a/pythonwarrior/level_loader.py +++ b/pythonwarrior/level_loader.py @@ -56,5 +56,5 @@ def warrior(self, *args, **kwargs): @staticmethod def _unit_to_constant(name): - camel = "".join(map(lambda x: x.capitalize(), str(name).split('_'))) + camel = "".join([x.capitalize() for x in str(name).split('_')]) return eval(camel) diff --git a/pythonwarrior/profile.py b/pythonwarrior/profile.py index 7eb8fdf..9758c52 100644 --- a/pythonwarrior/profile.py +++ b/pythonwarrior/profile.py @@ -30,7 +30,7 @@ def save(self): self.update_epic_score() if self.epic: self.level_number = 0 - f = open(self.player_path + '/.profile', 'w') + f = open(self.player_path + '/.profile', 'wb') f.write(self.encode()) @staticmethod diff --git a/pythonwarrior/templates/README b/pythonwarrior/templates/README index 0197297..7692d00 100644 --- a/pythonwarrior/templates/README +++ b/pythonwarrior/templates/README @@ -13,7 +13,7 @@ Tip: {{level.tip}} Warrior Abilities: -{% for name, ability in level.warrior.abilities.iteritems() %} +{% for name, ability in level.warrior.abilities.items() %} warrior.{{name}} {{ability.description()}} @@ -22,7 +22,7 @@ Warrior Abilities: Golem Abilities: -{% for name, ability in level.warrior.base_golem.abilities.iteritems() %} +{% for name, ability in level.warrior.base_golem.abilities.items() %} golem.{{name}} {{ability.description()}} diff --git a/pythonwarrior/tests/test_level.py b/pythonwarrior/tests/test_level.py index 900a926..9c4fed0 100644 --- a/pythonwarrior/tests/test_level.py +++ b/pythonwarrior/tests/test_level.py @@ -43,7 +43,7 @@ def test_should_load_file_contents_into_level(self): return_value='path/to/level.py'): mock_file = mock.Mock( read=mock.Mock(return_value="level.description('foo')")) - with mock.patch('__builtin__.open', + with mock.patch('builtins.open', return_value=mock_file): self.level.load_level() self.assertEqual(self.level.description, 'foo') diff --git a/pythonwarrior/tests/test_profile.py b/pythonwarrior/tests/test_profile.py index aab2bb2..26a2ef0 100644 --- a/pythonwarrior/tests/test_profile.py +++ b/pythonwarrior/tests/test_profile.py @@ -34,7 +34,7 @@ def test_should_decode_with_pickle_and_base64(self): self.assertEqual(Profile.decode(self.profile.encode()).warrior_name, self.profile.warrior_name) - @mock.patch('__builtin__.open') + @mock.patch('builtins.open') def test_load_should_read_file_decode_and_set_player_path(self, mock_open): profile = mock.Mock() mock_open.read.return_value = "encoded_profile" @@ -45,7 +45,7 @@ def test_load_should_read_file_decode_and_set_player_path(self, mock_open): def test_should_add_abilities_and_remove_duplicates(self): self.profile.add_abilities('foo', 'bar', 'blah', 'bar') - self.assertItemsEqual(self.profile.abilities, ['foo', 'bar', 'blah']) + self.assertSetEqual(set(self.profile.abilities), {'foo', 'bar', 'blah'}) def test_should_fetch_new_level_with_current_number(self): self.profile.level_number = 1 @@ -94,7 +94,7 @@ def setUp(self): self.profile.tower_path = "path/to/tower" def test_save_should_write_file_with_encoded_profile(self): - with mock.patch('__builtin__.open') as mock_open: + with mock.patch('builtins.open') as mock_open: with mock.patch.object(self.profile, 'encode', return_value='encoded_profile'): f = mock.Mock() @@ -102,7 +102,7 @@ def test_save_should_write_file_with_encoded_profile(self): self.profile.save() f.write.assert_called_once_with('encoded_profile') mock_open.assert_called_once_with(self.profile._player_path + - '/.profile', 'w') + '/.profile', 'wb') def test_should_have_a_nice_string_representation(self): self.profile.warrior_name = "Joe" diff --git a/pythonwarrior/tests/test_ui.py b/pythonwarrior/tests/test_ui.py index 8c5251c..ed51f92 100644 --- a/pythonwarrior/tests/test_ui.py +++ b/pythonwarrior/tests/test_ui.py @@ -3,7 +3,7 @@ from pythonwarrior.config import Config from pythonwarrior.ui import UI -from io import BytesIO +from io import StringIO class TestUI(unittest.TestCase): @@ -11,8 +11,8 @@ def setUp(self): self.ui = UI() self.config = Config self.config.delay = None - self.out_stream = BytesIO() - self.in_stream = BytesIO() + self.out_stream = StringIO() + self.in_stream = StringIO() self.config.out_stream = self.out_stream self.config.in_stream = self.in_stream @@ -38,7 +38,7 @@ def test_should_request_text_input(self): self.in_stream.write("bar") self.in_stream.seek(0) self.assertEqual(self.ui.request("foo"), "bar") - self.assertEqual(self.out_stream.getvalue(), "foo") + self.assertEqual(self.out_stream.getvalue(), "foo\n") @mock.patch('pythonwarrior.ui.UI.request') def test_should_ask_for_yes_no_and_return_true_when_yes(self, mock_req): diff --git a/pythonwarrior/tests/units/test_sludge.py b/pythonwarrior/tests/units/test_sludge.py index eb43c9d..b4a6c38 100644 --- a/pythonwarrior/tests/units/test_sludge.py +++ b/pythonwarrior/tests/units/test_sludge.py @@ -8,10 +8,10 @@ def setUp(self): self.sludge = Sludge() def test_should_have_attack_action(self): - self.assertIn('attack_', self.sludge.abilities.keys()) + self.assertIn('attack_', list(self.sludge.abilities.keys())) def test_should_have_feel_sense(self): - self.assertIn('feel', self.sludge.abilities.keys()) + self.assertIn('feel', list(self.sludge.abilities.keys())) def test_should_have_attack_of_3(self): self.assertEqual(self.sludge.attack_power, 3) diff --git a/pythonwarrior/tests/units/test_warrior.py b/pythonwarrior/tests/units/test_warrior.py index 0453fc6..28e3adc 100644 --- a/pythonwarrior/tests/units/test_warrior.py +++ b/pythonwarrior/tests/units/test_warrior.py @@ -51,4 +51,4 @@ def test_should_appear_as_AT_symbol_on_map(self): def test_should_be_able_to_add_golem_abilities_which_are_used_on_base_golem(self): self.warrior.add_golem_abilities("walk") - self.assertEqual(self.warrior.base_golem().abilities.keys(), ["walk"]) + self.assertEqual(list(self.warrior.base_golem().abilities.keys()), ["walk"]) diff --git a/pythonwarrior/towers/beginner/level_002.py b/pythonwarrior/towers/beginner/level_002.py index 376f14c..3cf0456 100644 --- a/pythonwarrior/towers/beginner/level_002.py +++ b/pythonwarrior/towers/beginner/level_002.py @@ -3,7 +3,7 @@ # -------- level.description("It is too dark to see anything, but you smell sludge nearby.") -level.tip("Use warrior.feel().is_empty() to see if there is anything in front of you, and warrior.attack() to fight it. Remember, you can only do one action (ending in _) per turn.") +level.tip("Use warrior.feel().is_empty() to see if there is anything in front of you, and warrior.attack_() to fight it. Remember, you can only do one action (ending in _) per turn.") level.time_bonus(20) level.ace_score(26) level.size(8, 1) diff --git a/pythonwarrior/towers/beginner/level_003.py b/pythonwarrior/towers/beginner/level_003.py index cdd0db1..5dd2307 100644 --- a/pythonwarrior/towers/beginner/level_003.py +++ b/pythonwarrior/towers/beginner/level_003.py @@ -3,7 +3,7 @@ # --------- level.description("The air feels thicker than before. There must be a horde of sludge.") -level.tip("Be careful not to die! Use warrior.health to keep an eye on your health, and warrior.rest! to earn 10% of max health back.") +level.tip("Be careful not to die! Use warrior.health() to keep an eye on your health, and warrior.rest_() to earn 10% of max health back.") level.clue("When there is no enemy ahead of you call warrior.rest_() until health is full before walking forward.") level.time_bonus(35) level.ace_score(71) diff --git a/pythonwarrior/turn.py b/pythonwarrior/turn.py index 2557793..70d8587 100644 --- a/pythonwarrior/turn.py +++ b/pythonwarrior/turn.py @@ -6,7 +6,7 @@ def __init__(self, abilities): self.action = None self.senses = {} - for name, sense in abilities.iteritems(): + for name, sense in abilities.items(): if name.endswith("_"): self.add_action(name) else: diff --git a/pythonwarrior/ui.py b/pythonwarrior/ui.py index d65764c..cb95db0 100644 --- a/pythonwarrior/ui.py +++ b/pythonwarrior/ui.py @@ -29,7 +29,7 @@ def gets(): @staticmethod def request(msg): - UI.write(msg) + UI.puts(msg) return UI.gets().rstrip() @staticmethod diff --git a/pythonwarrior/units/base.py b/pythonwarrior/units/base.py index e0b8540..c94274e 100644 --- a/pythonwarrior/units/base.py +++ b/pythonwarrior/units/base.py @@ -107,7 +107,7 @@ def unbind(self): def perform_turn(self): if self.position: - for ability in self.abilities.values(): + for ability in list(self.abilities.values()): ability.pass_turn() if self.current_turn.action and not self.is_bound(): name = self.current_turn.action[0] diff --git a/pythonwarrior/units/warrior.py b/pythonwarrior/units/warrior.py index ddb958f..f511c1e 100644 --- a/pythonwarrior/units/warrior.py +++ b/pythonwarrior/units/warrior.py @@ -33,7 +33,7 @@ def player(self): def earn_points(self, points): self.score = self.score + points - print "earns %d points" % points + print("earns %d points" % points) @property def attack_power(self):