def test_move_invaders_to_right_down(self): self.invaders.direction = 1 self.invaders.move(Rectangle(0, 0, 115, 200)) self.invaders.move(Rectangle(0, 0, 115, 200)) for y, line in enumerate(self.invaders.arr_invaders): for x, inv in enumerate(line): self.assertEqual( inv.x_left, 10 + x * (self.invader.width + self.invader.step) + self.invader.step) self.assertEqual( inv.y_top, 10 + y * (self.invader.height + self.invader.step) + self.invader.step * 2)
def test_contains(self): ellipse = Superellipse(Rectangle(20, 20, 30, 30), 5) self.assertTrue(ellipse.is_collapse(Point(30, 30))) self.assertTrue(ellipse.is_collapse(Point(20, 20))) self.assertTrue(ellipse.is_collapse(Point(18, 18))) self.assertTrue(ellipse.is_collapse(Point(50, 55))) self.assertFalse(ellipse.is_collapse(Point(50, 56)))
def test_contains2(self): ellipse = Superellipse(Rectangle(0, 0, 50, 50), 10) self.assertTrue(ellipse.is_collapse(Point(-6, 8))) self.assertTrue(ellipse.is_collapse(Point(60, 50))) self.assertTrue(ellipse.is_collapse(Point(50, 60))) self.assertTrue(ellipse.is_collapse(Point(56, 58))) self.assertFalse(ellipse.is_collapse(Point(56, 59)))
def test_one_fire_an_angle(self): for angle in range(15, 170, 15): self.ship_bullet = Bullet(15, 15, 1, angle, 1) self.ship_bullet.fire(Rectangle(0, 0, 30, 30)) self.assertLess((15 + math.cos(angle * math.pi / 180) - self.ship_bullet.x_left), 10e-5) self.assertLess((15 - math.sin(angle * math.pi / 180) - self.ship_bullet.y_top), 10e-5)
def test_ricochet_from_up(self): self.bullet = Bullet(0, 3, 1, 45, 1, True) for i in range(10): self.bullet.fire(Rectangle(0, 0, 20, 20)) self.assertEqual(self.bullet.angle, -45 * math.pi / 180) self.assertEqual(self.bullet.module_vector, 5) self.assertLess(10 * math.cos(45 * math.pi / 180) - self.bullet.x_left, 10e-5) self.assertLess(self.bullet.y_top - 3, 10e-5)
def test_ricochet_from_left(self): self.bullet = Bullet(15, 15, 1, 45, 1, True) for i in range(10): self.bullet.fire(Rectangle(0, 0, 19, 19)) self.assertEqual(self.bullet.angle, math.pi - 45 * math.pi / 180) self.assertEqual(self.bullet.module_vector, 5) self.assertLess(self.bullet.x_left - 15, 10e-5) self.assertLess( 15 - 10 * math.sin(45 * math.pi / 180) - self.bullet.y_top, 10e-5)
def test_fire_30(self): self.ship_bullet = Bullet(15, 15, 1, 30, 1) for i in range(10): self.ship_bullet.fire(Rectangle(0, 0, 25, 25)) self.assertLess( (15 + 10 * math.cos(30 * math.pi / 180) - self.ship_bullet.x_left), 10e-5) self.assertLess( (15 - 10 * math.sin(30 * math.pi / 180) - self.ship_bullet.y_top), 10e-5)
class Gachi: gravity = .7 def __init__(self, img): self.w = 56 self.h = 56 self.anim = Animation(img, self.w, self.h) self.anim.anim_type = AnimType.REPEAT self.x = 250 self.brain = NeuralNetwork((4, 4, 1)) self.y = Game.height / 2 self.vel_y = 0 self.collider = Rectangle(self.x, self.y, self.w, self.h) self.score = 0 self.fitness = 0 self.alive = True def think(self, wall): prediction = self.brain.predict([[self.y], [self.vel_y], [wall.x], [wall.top]]) if prediction[0][0] > 0.5: self.jump() def jump(self): self.vel_y = -9 def update(self, dt, wall): self.anim.update(dt) self.vel_y += Gachi.gravity self.y += self.vel_y self.collider.x = self.x self.collider.y = self.y self.score += 50 self.think(wall) if self.collider.intersect( wall.collider_top) or self.collider.intersect( wall.collider_bottom ) or self.y + self.h > Game.height or self.y < 0: self.alive = False def draw(self, surface): self.anim.show(surface, self.x, self.y)
def test_fire_90(self): for i in range(10): self.ship_bullet.fire(Rectangle(0, 0, 30, 30)) self.assertEqual(self.ship_bullet.y_top, 14 - i) self.assertEqual(self.ship_bullet.x_left, 15)
def test_ship_bullet_in_field(self): self.assertTrue(self.ship_bullet.in_field(Rectangle(0, 0, 50, 50))) self.assertFalse(self.ship_bullet.in_field(Rectangle(0, 0, 10, 10)))
def setUp(self): self.mystery_ship = MysteryShip(10, 10, 10, 10) self.field = Rectangle(0, 0, 100, 100)
class Window(QtWidgets.QMainWindow): def __init__(self): super().__init__() self.setWindowTitle('Space Invaders') self.ui = GUI() self.setFixedSize(Constants.WINDOW_WIDTH, Constants.WINDOW_HEIGHT) self.setWindowIcon(self.ui.icon) self.current_mode = WindowMode.CHOICE_LEVEL self.update_timer = QtCore.QTimer() self.update_timer.timeout.connect(self.update) self.update_timer.start(10) self.button_record = Rectangle(90, 430, 430, 53) self.button_select = Rectangle(90, 500, 430, 53) self.current_level = 0 try: levels = AllLevels(AllLevels.LEVELS_FILE) except EmptyLevelsFile as e: QtWidgets.QMessageBox.critical( self, "Failed to launch the game", f"{AllLevels.LEVELS_FILE} is empty. Write levels for the game", QtWidgets.QMessageBox.Ok) sys.exit(8) except Exception as e: QtWidgets.QMessageBox.critical( self, "Failed to launch the game", f"{AllLevels.LEVELS_FILE} not found: \n{e}", QtWidgets.QMessageBox.Ok) sys.exit(7) self.count_levels = levels.get_count_level() self.game = GameState(levels, QtCore.QTimer.stop, QtCore.QTimer.start) self.game.init_game(**self.get_game_timer()) self.update_timer = QtCore.QTimer() self.update_timer.timeout.connect(self.update_timeout) self.update_timer.start(10) self.previous_score = self.game.score self.previous_ship_live = self.game.ship.live self.previous_game_mode = self.game.current_mode self.music = Music() self.music.play_background() self.scoreboard = Scoreboard(self.count_levels) self.current_player = None self.names_players = self.scoreboard.get_players() self.show() self.show_name_choice() def update_timeout(self): self.update() if (self.game.score - self.previous_score == Constants.MYSTERY_SHIP_BILL): self.music.play_hit_mystery_ship_sound() elif self.game.score - self.previous_score == Constants.INVADER_BILL: self.music.play_hit_sound() if self.previous_ship_live > self.game.ship.live: self.music.play_dying() if (self.previous_game_mode == GameMode.GAME_PLAY and self.game.current_mode == GameMode.GAME_OVER): if self.game.invaders.count > 0: self.music.play_game_over() else: self.music.play_win() self.previous_score = self.game.score self.previous_ship_live = self.game.ship.live self.previous_game_mode = self.game.current_mode def paintEvent(self, event): painter = QtGui.QPainter(self) painter.drawPixmap(self.rect(), QtGui.QPixmap(self.ui.background_img)) if self.current_mode == WindowMode.SCOREBOARD: painter.setPen(QtGui.QColor(255, 255, 255)) painter.setFont(QtGui.QFont('Decorative', 20)) level = self.scoreboard.get_top_scoreboard(self.current_level) painter.drawText(100, 70, f"Level {self.current_level}") for site, player in enumerate(level): painter.drawText(100, 40 * site + 120, f"{site + 1}. {player[0]}: {player[1]}") self.ui.paint_button(painter, self.button_select, self.ui.level_selection) self.ui.paint_arrows_left_right(painter, self.rect()) elif self.current_mode == WindowMode.GAME_PLAY: if self.game.current_mode == GameMode.GAME_OVER: if self.game.invaders.count == 0: self.ui.paint_you_win(painter, self.rect()) else: self.ui.paint_game_over(painter, self.rect()) self.ui.paint_button(painter, self.button_select, self.ui.level_selection) self.ui.paint_button(painter, self.button_record, self.ui.record) elif self.game.current_mode == GameMode.GAME_PLAY: game = self.game painter.setPen(QtGui.QColor(255, 255, 255)) painter.setFont(QtGui.QFont('Decorative', 20)) painter.drawText(50, 25, "Score: {}".format(game.score)) painter.drawText(250, 25, "Time: {}".format(int(game.time / 1000))) painter.drawText(450, 25, "Live: {}".format(game.ship.live)) self.ui.paint_invaders(painter, game.invaders.arr_invaders) self.ui.paint_bullets(painter, game.ship_bullets.arr) self.ui.paint_bullets(painter, game.invader_bullets.arr, invader=True) self.ui.paint_ship(painter, game.ship) self.ui.paint_bunkers(painter, game.bunkers.arr) self.ui.paint_mystery_ship(painter, game.mystery_ship) elif self.game.current_mode == GameMode.GAME_PAUSE: self.ui.paint_pause(painter, self.rect()) elif self.current_mode == WindowMode.CHOICE_LEVEL: self.ui.paint_level(painter, self.current_level) self.ui.paint_arrows_up_down(painter, self.rect()) def get_game_timer(self): keys = { 'KEY_UP': QtCore.Qt.Key_Up, 'KEY_DOWN': QtCore.Qt.Key_Down, 'KEY_RIGHT': QtCore.Qt.Key_Right, 'KEY_LEFT': QtCore.Qt.Key_Left, 'KEY_SPACE': QtCore.Qt.Key_Space } invader_timer = QtCore.QTimer() invader_timer.timeout.connect(self.game.invader_timeout) press_timer = QtCore.QTimer() press_timer.timeout.connect(lambda: self.game.press_timeout(**keys)) run_timer = QtCore.QTimer() run_timer.timeout.connect(self.game.game_timeout) return { 'invader_timer': invader_timer, 'press_timer': press_timer, 'run_timer': run_timer } def mousePressEvent(self, event): click = Point(event.x(), event.y()) if self.current_mode == WindowMode.SCOREBOARD: if self.button_select.contains_point(click): self.game.init_game(**self.get_game_timer()) self.current_mode = WindowMode.CHOICE_LEVEL elif (self.current_mode == WindowMode.GAME_PLAY and self.game.current_mode == GameMode.GAME_OVER): level = self.current_level player = self.current_player if player: scoreboard = self.scoreboard.board if player not in scoreboard[level]: scoreboard[level][player] = 0 scoreboard[level][player] = max(self.game.score, scoreboard[level][player]) if self.button_select.contains_point(click): self.game.init_game(**self.get_game_timer()) self.current_mode = WindowMode.CHOICE_LEVEL if self.button_record.contains_point(click): self.current_mode = WindowMode.SCOREBOARD def keyPressEvent(self, event): key = event.key() if self.current_mode == WindowMode.GAME_PLAY: self.game.key_press_event(event) elif self.current_mode == WindowMode.CHOICE_LEVEL: if key == QtCore.Qt.Key_Down: self.current_level = ((self.current_level + 1) % self.count_levels) elif key == QtCore.Qt.Key_Up: self.current_level = ( (self.current_level - 1 + self.count_levels) % self.count_levels) elif key == QtCore.Qt.Key_Enter - 1 or key == QtCore.Qt.Key_Enter: try: self.game.start_level(self.current_level) self.previous_score = self.game.score self.previous_ship_live = self.game.ship.live except IncorrectFormatLevelsFile as e: QtWidgets.QMessageBox.critical( self, "Failed to launch the game", f'Incorrect format {AllLevels.LEVELS_FILE}: \n{e}', QtWidgets.QMessageBox.Ok) sys.exit(9) self.current_mode = WindowMode.GAME_PLAY elif self.current_mode == WindowMode.SCOREBOARD: if key == QtCore.Qt.Key_Right: self.current_level = ((self.current_level + 1) % self.count_levels) elif key == QtCore.Qt.Key_Left: self.current_level = ( (self.current_level - 1 + self.count_levels) % self.count_levels) def keyReleaseEvent(self, event): self.game.key_release_event(event, QtCore.Qt.Key_P) def closeEvent(self, event): self.scoreboard.dump_board() def show_name_choice(self): add_item = "Add new player..." items = list(self.names_players) if add_item not in items: items.insert(0, add_item) item, ok_pressed = QtWidgets.QInputDialog.getItem( self, "Choice player", "Player:", items, 0, False) if ok_pressed and item: if item == add_item: self.show_dialog() else: self.current_player = item def show_dialog(self): answer = 'Enter your name:' widget = QtWidgets.QInputDialog text, ok = widget.getText(self, "Enter player", answer) while True: if not ok: return if text in self.names_players: answer = "This name already used!" elif not text: answer = "You didn't enter name!" else: break text, ok = widget.getText(self, "Enter player", answer) self.current_player = text
def setUp(self): self.field = Rectangle(0, 0, 30, 30) self.bullets = Bullets() self.bullet = Bullet(0, 0, 5, 10, 10) self.bullets.add(self.bullet)