class UiVScreenOverview:

    def __init__(self, view, vscreen):
        """
        :type view: PySide2.QtWidgets.QGraphicsView.QGraphicsView
        :param vscreen: hwmonitor.vscreen.vscreen.VScreen
        """
        self.view = view
        self.vscreen = vscreen

        self.view_margin = 10
        self.background_color = QColor(100, 100, 100)

        view.setInteractive(False)
        view.setStyleSheet('border: 0px;')
        view.setRenderHint(QPainter.Antialiasing)
        view.setCacheMode(QGraphicsView.CacheBackground)
        view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        self.scene = QGraphicsScene(view)
        self.scene.setBackgroundBrush(self.background_color)

        for monitor in self.vscreen.monitors:
            item = MonitorRepresentation(index_from_device_name(monitor.device_name), monitor)
            item.update_position()
            self.scene.addItem(item)

        view.setScene(self.scene)

    def update_position(self):
        for item in self.scene.items():
            item.update_position()

    def resize_scene(self):
        """Resize the scene to fit inside the available space of the viewport with an given margin.

        Update the scene rect, since it probably changes when changing the layout.
        """
        rect = self.scene.itemsBoundingRect()
        self.view.setSceneRect(rect)

        view_rect = self.view.viewport().rect().adjusted(self.view_margin, self.view_margin,
                                                         -self.view_margin, -self.view_margin)
        scene_rect = self.view.matrix().mapRect(rect)

        x_factor = view_rect.width() / scene_rect.width()
        y_factor = view_rect.height() / scene_rect.height()
        factor = min(x_factor, y_factor)

        self.view.scale(factor, factor)
        self.view.centerOn(rect.center())
Ejemplo n.º 2
0
    def __init__(self, start_state: GridGameState):
        super().__init__(start_state)
        self.start_state: GridGameState = start_state
        self.spaces = []  # self.spaces[i][j] holds row i, column j
        self.column_dividers = []
        self.row_dividers = []
        self.column_labels = []
        self.row_labels = []
        self.text_x = self.text_y = 0

        ui = self.ui = Ui_GridControls()
        ui.setupUi(self)
        scene = QGraphicsScene()
        ui.game_display.setScene(scene)
        scene.setBackgroundBrush(self.background_colour)
        self.player1_icon = self.create_icon(self.player1_colour)
        self.player2_icon = self.create_icon(self.player2_colour)
        ui.black_count_pixmap.setText('')
        ui.white_count_pixmap.setText('')
        ui.black_count.setText('')
        ui.white_count.setText('')

        for _ in range(start_state.board_height - 1):
            self.row_dividers.append(scene.addLine(0, 0, 1, 1))
        for _ in range(start_state.board_width - 1):
            self.column_dividers.append(scene.addLine(0, 0, 1, 1))
        for i in range(start_state.board_height):
            self.row_labels.append(scene.addSimpleText(f'{i + 1}'))
        for j in range(start_state.board_width):
            self.column_labels.append(scene.addSimpleText(chr(65 + j)))
        self.to_move = scene.addEllipse(0,
                                        0,
                                        1,
                                        1,
                                        brush=self.get_player_brush(
                                            self.start_state.X_PLAYER))
        self.to_move.setVisible(False)
        self.move_text = ui.move_text
        for i in range(self.start_state.board_height):
            row: typing.List[QGraphicsItem] = []
            self.spaces.append(row)
            for j in range(self.start_state.board_width):
                piece = GraphicsPieceItem(i, j, self)
                scene.addItem(piece)
                piece.setBrush(self.background_colour)
                piece.setPen(self.background_colour)
                row.append(piece)
        self.debug_message = ''
Ejemplo n.º 3
0
class TimeLineLabelView(QGraphicsView):
    def __init__(self, parent=None):
        super(TimeLineLabelView, self).__init__(parent)
        self.x = 0
        self.y = 0
        self.m_originX = 0
        self.m_originY = 0
        self.label_height = 10
        self.frame_width = 10
        self.time_line_length = 10
        self.label_width = 80
        self.zoom_factor = 0.0001
        self._min_scale_factor = 0.01
        self.scale_factor = 1.0
        self.time_lines = dict()
        self.setInteractive(True)
        self.setDragMode(drag_mode)
        self.setSceneRect(0, 0, self.time_line_length, self.label_height)
        self.labels = []
        self.setTransformationAnchor(
            transform_anchor
        )  # needs to be set to 0 to allow view transform changes https://bugreports.qt.io/browse/QTBUG-
        self.frame_indicator = None
        self.edit_start_frame_indicator = None
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

    def create_frame_indicator(self):
        size = QSizeF()
        height = 100
        size.setHeight(height)
        size.setWidth(self.label_height)
        self.frame_indicator = FrameIndicator(size, self.frame_width,
                                              self.label_width, 0)
        self._label_scene.addItem(self.frame_indicator)

        self.edit_start_frame_indicator = FrameIndicator(
            size, self.frame_width, self.label_width, 0, blue)
        self._label_scene.addItem(self.edit_start_frame_indicator)

    def initScene(self):
        brush = QBrush()
        color = QColor()
        color.setGreen(255)
        color.setAlpha(255)
        brush.setColor(color)
        self._label_scene = QGraphicsScene()
        self._label_scene.setBackgroundBrush(grey)
        #self._label_scene.setForegroundBrush(color)
        self.setScene(self._label_scene)

    def clearScene(self):
        self.labels = []
        self.time_lines = dict()
        self._label_scene.clear()

    def setTimeLineParameters(self, time_line_length, label_height):
        self.label_height = label_height
        self.time_line_length = self.frame_width * time_line_length

    def addLabel(self, l, indices, color):
        y = len(self.labels) * self.label_height
        pos = QPointF(0, y)
        label = l
        timeline = TimeLine(label, indices, pos, self.time_line_length,
                            self.label_height, self.label_width,
                            self.frame_width, color)
        self._label_scene.addItem(timeline)
        self.time_lines[label] = timeline
        self.labels.append(l)

        self.setSceneRect(0, 0, self.time_line_length,
                          self.label_height * len(self.labels))

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.m_originX = event.x()
            self.m_originY = event.y()

    def mouseMoveEvent(self, event):
        if event.buttons() and Qt.LeftButton:
            deltaX = event.x() - self.m_originX
            deltaY = event.y() - self.m_originY
            #self.translate(deltaX, deltaY)
            self.x += deltaX
            self.y += deltaY
            self.updateTransform()
            self.m_originX = event.x()
            self.m_originY = event.y()

    def wheelEvent(self, event):
        self.scale_factor += event.angleDelta().y() * self.zoom_factor
        self.scale_factor = max(self._min_scale_factor, self.scale_factor)
        self.updateTransform()

    def setFrame(self, idx):
        self.x = self.scale_factor * -idx * self.frame_width + self.label_width

        #transform = Qt.QTransform()
        #transform.translate(-deltaX, 0)
        #self.setTransform(transform)
        self.updateTransform()
        if self.frame_indicator is not None:
            self.frame_indicator.setFrame(idx)

    def set_edit_start_frame(self, idx):
        if self.edit_start_frame_indicator is not None:
            self.edit_start_frame_indicator.setFrame(idx)

    def updateTransform(self):
        if self.x > 0:
            self.x = 0

        self.resetTransform()
        m = QTransform()
        m.translate(self.x, self.y)
        m.scale(self.scale_factor, 1.0)
        self.setTransform(m)
Ejemplo n.º 4
0
class DynamicView(QGraphicsView):
    viewChanged = Signal(QRect, float, int, int)

    def __init__(self, image, parent=None):
        super(DynamicView, self).__init__(parent)
        self.scene = QGraphicsScene()
        self.scene.setBackgroundBrush(Qt.darkGray)
        self.setScene(self.scene)
        self.set_image(image)
        self.setRenderHint(QPainter.SmoothPixmapTransform)
        self.setDragMode(QGraphicsView.ScrollHandDrag)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.ZOOM_STEP = 0.2
        self.mouse_pressed = False
        self.next_fit = False
        self.fit_scale = 0
        self.zoom_fit()

    def set_image(self, image):
        if type(image) is QPixmap:
            pixmap = image
        elif type(image) is QImage:
            pixmap = QPixmap.fromImage(image)
        elif type(image) is np.ndarray:
            pixmap = QPixmap.fromImage(mat2img(image))
        else:
            raise TypeError(
                self.tr('DynamicView.set_image: Unsupported type: {}'.format(
                    type(image))))
        if not self.scene.items():
            self.scene.addPixmap(pixmap)
        else:
            self.scene.items()[0].setPixmap(pixmap)
        self.scene.setSceneRect(QRectF(pixmap.rect()))

    def zoom_full(self):
        self.set_scaling(1)
        self.next_fit = True
        self.notify_change()

    def zoom_fit(self):
        self.fitInView(self.scene.sceneRect(), Qt.KeepAspectRatio)
        self.fit_scale = self.matrix().m11()
        if self.fit_scale > 1:
            self.fit_scale = 1
            self.zoom_full()
        else:
            self.next_fit = False
            self.notify_change()

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.mouse_pressed = True
        QGraphicsView.mousePressEvent(self, event)

    def mouseMoveEvent(self, event):
        QGraphicsView.mouseMoveEvent(self, event)
        if self.mouse_pressed:
            self.notify_change()

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.mouse_pressed = False
        QGraphicsView.mouseReleaseEvent(self, event)

    def mouseDoubleClickEvent(self, event):
        if event.button() == Qt.LeftButton:
            if self.next_fit:
                self.zoom_fit()
            else:
                self.zoom_full()
        QGraphicsView.mouseDoubleClickEvent(self, event)

    def wheelEvent(self, event):
        if event.delta() > 0:
            self.change_zoom(+1)
        else:
            self.change_zoom(-1)

    def resizeEvent(self, event):
        # FIXME: Se la finestra viene massimizzata, il valore di fit_scale non si aggiorna
        if self.matrix().m11() <= self.fit_scale:
            self.zoom_fit()
        else:
            self.notify_change()
        QGraphicsView.resizeEvent(self, event)

    def change_zoom(self, direction):
        level = math.log2(self.matrix().m11())
        if direction > 0:
            level += self.ZOOM_STEP
        else:
            level -= self.ZOOM_STEP
        scaling = 2**level
        if scaling < self.fit_scale:
            scaling = self.fit_scale
            self.next_fit = False
        elif scaling > 1:
            # scaling = 1
            if scaling > 4:
                scaling = 4
            self.next_fit = True
        self.set_scaling(scaling)
        self.notify_change()

    def set_scaling(self, scaling):
        matrix = QMatrix()
        matrix.scale(scaling, scaling)
        self.setMatrix(matrix)

    def change_view(self, _, new_scaling, new_horiz, new_vert):
        old_factor = self.matrix().m11()
        old_horiz = self.horizontalScrollBar().value()
        old_vert = self.verticalScrollBar().value()
        if new_scaling != old_factor or new_horiz != old_horiz or new_vert != old_vert:
            self.set_scaling(new_scaling)
            self.horizontalScrollBar().setValue(new_horiz)
            self.verticalScrollBar().setValue(new_vert)
            self.notify_change()

    def notify_change(self):
        scene_rect = self.get_rect()
        horiz_scroll = self.horizontalScrollBar().value()
        vert_scroll = self.verticalScrollBar().value()
        zoom_factor = self.matrix().m11()
        self.viewChanged.emit(scene_rect, zoom_factor, horiz_scroll,
                              vert_scroll)

    def get_rect(self):
        top_left = self.mapToScene(0, 0).toPoint()
        if top_left.x() < 0:
            top_left.setX(0)
        if top_left.y() < 0:
            top_left.setY(0)
        view_size = self.viewport().size()
        bottom_right = self.mapToScene(view_size.width(),
                                       view_size.height()).toPoint()
        image_size = self.sceneRect().toRect()
        if bottom_right.x() >= image_size.width():
            bottom_right.setX(image_size.width() - 1)
        if bottom_right.y() >= image_size.height():
            bottom_right.setY(image_size.height() - 1)
        return QRect(top_left, bottom_right)
Ejemplo n.º 5
0
class window(QWidget):
    def __init__(self):
        # main window settings
        super().__init__()
        self.setWindowTitle("Snake")
        self.setGeometry(150, 50, 820, 320)
        self.setFixedSize(820, 320)
        self.scene = QGraphicsScene()
        self.game_loop = False
        self.scoreboard = None
        self.hot_seat = 0
        self.config = 0
        self.against_ai = 0
        self.game = snake_map(width, height)
        self.multi_info = []
        self.hex = []
        self.grahpicsitem = []
        self.end_connection = False
        self.guicomponents()

    # key listener for a gameplay that is not provided by tcp
    def keyPressEvent(self, event: PySide2.QtGui.QKeyEvent):
        if self.game_loop:
            if self.against_ai is 0:
                if event.text() in p1_controls:
                    p1_keys.append(event.text())
                if event.text() in p2_controls:
                    p2_keys.append(event.text())
            else:
                if event.text() in p1_controls:
                    p1_keys.append(event.text())

    # main window graphic layout
    def guicomponents(self):
        button_exit = QPushButton("Exit", self)
        button_start = QPushButton("1 player", self)
        button_hot_seat = QPushButton("2 players", self)
        button_multi = QPushButton("Multiplayer", self)
        button_replay = QPushButton("Replay", self)
        button_ai = QPushButton("Against bot", self)
        self.connection_info = QLabel(self)
        self.controls_info = QLabel(self)
        self.scoreboard = QLabel(self)
        self.config_info = QLabel(self)
        self.config_info.setText("")
        self.scoreboard.setText("")
        self.config_info.setFont(PySide2.QtGui.QFont("Courier", 9))
        self.scoreboard.setFont(PySide2.QtGui.QFont("Courier", 10))
        self.scoreboard.setGeometry(QRect(10, 225, 500, 30))
        self.config_info.setGeometry(QRect(10, 225, 790, 30))
        button_start.setGeometry(QRect(10, 250, 100, 30))
        button_exit.setGeometry(QRect(510, 250, 100, 30))
        button_hot_seat.setGeometry(QRect(110, 250, 100, 30))
        button_multi.setGeometry(QRect(210, 250, 100, 30))
        button_replay.setGeometry(QRect(410, 250, 100, 30))
        button_ai.setGeometry(QRect(310, 250, 100, 30))
        self.connection_info.setGeometry(10, 280, 200, 30)
        self.controls_info.setGeometry(220, 280, 200, 30)
        button_hot_seat.clicked.connect(self.prepare_hot_seat)
        button_exit.clicked.connect(exit_app)
        button_start.clicked.connect(self.prepare_single)
        button_multi.clicked.connect(self.prepare_multi)
        button_replay.clicked.connect(self.prepare_replay)
        button_ai.clicked.connect(self.prepare_ai)
        self.view = QGraphicsView(self.scene, self)
        self.view.setGeometry(10, 10, 10 * (width + 2), 10 * (height + 2))
        self.scene.setBackgroundBrush(QBrush(QColor(0, 120, 0, 255)))
        self.grass = QPixmap(":/map/grass.png").scaled(20, 20)
        self.snake = QPixmap(":/map/orange.png").scaled(20, 20)
        self.black = QPixmap(":/map/black.png").scaled(20, 20)
        self.apple = QPixmap(":/map/apple.png").scaled(20, 20)
        self.white = QPixmap(":/map/white.png").scaled(20, 20)
        self.clear_map()

    # load configuration from h5 file and map history from xml file
    def prepare_replay(self):
        try:
            self.scoreboard.setText("")
            with open("config.json", "r") as f:
                self.config = json.load(f)
            output = []
            for k in self.config:
                output.append([k, self.config[k]])
            output = [item for sublist in output for item in sublist]
            self.config_info.setText("".join(output))
            tree = ET.parse("replay.xml")
            root = tree.getroot()
            game_history = []
            rounds = []
            for turn in root:
                for cells in turn:
                    for row in cells:
                        if cells.attrib["indexes"] == "19" and row.attrib[
                                "indexes"] == "77":
                            game_history.append(row.text)
                            copy_history = deepcopy(game_history)
                            rounds.append(copy_history)
                            game_history.clear()
                        else:
                            game_history.append(row.text)
            for round in rounds:
                round = np.reshape(round, (20, 78))
                self.game.map = round
                Snake.get_hex(self.hex, self.game)
                self.initialize_map()
                self.update_map()
                myApp.processEvents()
                time.sleep(0.5)
        except:
            self.config_info.setText("Failed to load a replay!")

    # key listener for multiplayer
    def send_key(self, number, socket):
        self.game_loop = True
        while True:
            time.sleep(0.3)
            if number == "0" and len(p1_keys) > 0:
                try:
                    socket.send(bytes(p1_keys[-1], "utf-8"))
                except:
                    break
            elif number == "1" and len(p2_keys) > 0:
                try:
                    socket.send(bytes(p2_keys[-1], "utf-8"))
                except:
                    break
            if self.end_connection:
                break

    # receive map configuration from the server
    def prepare_multi(self):
        self.end_connection = False
        root = ET.Element("game")
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect(("127.0.0.1", 1235))
        self.connection_info.setText("Connected to server!")

        msg = s.recv(1024).decode("utf-8")
        init_msg = msg.split()
        score_1, score_2 = 0, 0

        if init_msg[0] == "Start":
            if init_msg[1] == "0":
                self.controls_info.setText("Controls Q, A, Z, E, D, C")
            elif init_msg[1] == "1":
                self.controls_info.setText("Controls T, G, B, U, J, M")
            Thread(target=self.send_key, args=(init_msg[-1], s)).start()
            end = False
            frames = 0

            while end is False:
                myApp.processEvents()
                msg = s.recv(4096)
                msg = pickle.loads(msg)

                if msg[0] == 'end':
                    end = True
                    self.config = {
                        "mode-": "Multiplayer",
                        " Client 1 -": str(msg[1]),
                        " Client 2 -": str(msg[-1]),
                        " P1 points-": str(score_1),
                        " P2 points-": str(score_2)
                    }
                    with open("config.json", "w") as f:
                        json.dump(self.config, f)
                    continue

                self.game.map = msg[0]
                doc = ET.SubElement(root, "turn", name=str(frames))
                for i in range(height):
                    row = ET.SubElement(doc, "cell", indexes=str(i))
                    for j in range(width):
                        ET.SubElement(
                            row, "row",
                            indexes=str(j)).text = self.game.map[i][j]

                if len(msg) == 3:
                    score_1, score_2 = msg[1], msg[2]

                if msg[0] != "end":
                    if init_msg[1] == "0":
                        self.scoreboard.setText("Your score - " + str(msg[1]) +
                                                " | " + "Enemy - " +
                                                str(msg[2]))
                    if init_msg[1] == "1":
                        self.scoreboard.setText("Your score - " + str(msg[2]) +
                                                " | " + "Enemy - " +
                                                str(msg[1]))

                if frames == 0:
                    Snake.get_hex(self.hex, self.game)
                    self.initialize_map()

                self.update_map()
                myApp.processEvents()
                frames = frames + 1
                time.sleep(0.25)

            if init_msg[1] == "0":
                if score_1 > score_2:
                    self.scoreboard.setText("You won!")
                elif score_2 > score_1:
                    self.scoreboard.setText("Enemy won!")
                else:
                    self.scoreboard.setText("Draw!")

            if init_msg[1] == "1":
                if score_1 < score_2:
                    self.scoreboard.setText("You won!")
                elif score_2 < score_1:
                    self.scoreboard.setText("Enemy won!")
                else:
                    self.scoreboard.setText("Draw!")

        self.connection_info.setText("Disconnected!")
        tree = ET.ElementTree(root)
        tree.write("replay.xml")
        self.end_connection = True

    def prepare_hot_seat(self):
        self.hot_seat = 1
        self.against_ai = 0
        self.clear_map()
        self.start_game()

    def prepare_single(self):
        self.hot_seat = 0
        self.against_ai = 0
        self.clear_map()
        self.start_game()

    def prepare_ai(self):
        self.against_ai = 1
        self.hot_seat = 0
        self.clear_map()
        self.start_game()

    def clear_map(self):
        self.game.init_map()
        Snake.get_hex(self.hex, self.game)
        self.initialize_map()

    def initialize_map(self):
        self.grahpicsitem = []
        self.scene.clear()
        for i in self.hex:
            if self.game.map[i[0]][i[1]] == " ":
                cell = QGraphicsPixmapItem(self.grass)
                cell.setPos(QPointF(i[1] * 10, i[0] * 10))
                self.grahpicsitem.append(cell)
                self.scene.addItem(cell)
            elif self.game.map[i[0]][i[1]] == "#":
                cell = QGraphicsPixmapItem(self.black)
                cell.setPos(QPointF(i[1] * 10, i[0] * 10))
                self.grahpicsitem.append(cell)
                self.scene.addItem(cell)
            elif self.game.map[i[0]][i[1]] == "+":
                cell = QGraphicsPixmapItem(self.white)
                cell.setPos(QPointF(i[1] * 10, i[0] * 10))
                self.grahpicsitem.append(cell)
                self.scene.addItem(cell)
            if self.game.map[i[0]][i[1]] == "@":
                cell = QGraphicsPixmapItem(self.apple)
                cell.setPos(QPointF(i[1] * 10, i[0] * 10))
                self.grahpicsitem.append(cell)
                self.scene.addItem(cell)

    def update_map(self):
        for i in range(len(self.hex)):
            if self.game.map[self.hex[i][0]][self.hex[i][1]] == " ":
                self.grahpicsitem[i].setPixmap(self.grass)
            elif self.game.map[self.hex[i][0]][self.hex[i][1]] == "#":
                self.grahpicsitem[i].setPixmap(self.black)
            elif self.game.map[self.hex[i][0]][self.hex[i][1]] == "@":
                self.grahpicsitem[i].setPixmap(self.apple)
            elif self.game.map[self.hex[i][0]][self.hex[i][1]] == "+":
                self.grahpicsitem[i].setPixmap(self.white)

    def start_game(self):
        self.config_info.setText("")
        self.game_loop, spawn_fruit = False, False

        if self.game_loop is not True:
            p1_keys.clear(), p2_keys.clear()

        root = ET.Element("game")
        spawn_animal1, spawn_animal2, self.game_loop = False, False, True
        p1_can_play, p2_can_play = True, True
        animal1, animal2 = [], []
        points1, points2 = 0, 0

        # find free space on the map and spawn snake (or snakes)
        if (self.hot_seat and self.against_ai is 0) or (self.hot_seat is 0
                                                        and self.against_ai):
            self.scoreboard.setText("1.P1 points - " + str(points1) +
                                    " | 2.P2 points - " + str(points2))
            while (spawn_animal1 is False) and (spawn_animal2 is False):
                if not spawn_animal1:
                    x = np.random.randint(0, len(self.hex))
                    spawn_animal1, _ = Snake.check_space(
                        self.game.map, self.hex[x], 1, [0, 0, "#", "+"], 0)
                if not spawn_animal2:
                    y = np.random.randint(0, len(self.hex))
                    spawn_animal2, _ = Snake.check_space(
                        self.game.map, self.hex[y], 1, [0, 0, "#", "+"], 0)
            animal1.insert(0, snake(self.hex[x], self.game.map, "#"))
            animal2.insert(0, snake(self.hex[y], self.game.map, "+"))
        elif self.hot_seat is 0 and self.against_ai is 0:
            self.scoreboard.setText("Points - " + str(points1))
            while not spawn_animal1:
                x = np.random.randint(0, len(self.hex))
                spawn_animal1, _ = Snake.check_space(self.game.map,
                                                     self.hex[x], 1,
                                                     [0, 0, "#"], 0)
            animal1.insert(0, snake(self.hex[x], self.game.map, "#"))

        #main game loop
        index = 0
        while self.game_loop:

            # save actual map to xml file
            doc = ET.SubElement(root, "turn", name=str(index))
            for i in range(height):
                row = ET.SubElement(doc, "cell", indexes=str(i))
                for j in range(width):
                    ET.SubElement(row, "row",
                                  indexes=str(j)).text = self.game.map[i][j]

            # spawn fruit on the map
            if not spawn_fruit:
                while not spawn_fruit:
                    x = np.random.randint(0, len(self.hex))
                    spawn_fruit, _ = Snake.check_space(self.game.map,
                                                       self.hex[x], 1,
                                                       [0, 0, "@"], 0)

            fruit_on_map = fruit(self.hex[x], self.game.map, "@")

            spawn_fruit, points1, points2, p1_can_play, p2_can_play, self.game_loop = \
                Snake.move_anim(p1_can_play, p2_can_play, spawn_fruit, animal1, animal2, points1, points2, fruit_on_map,
                                p1_keys, p2_keys, self.hot_seat, self.against_ai, self.game, self.hex, self.scoreboard,
                                self.game_loop)

            self.update_map()
            index = index + 1
            myApp.processEvents()
            time.sleep(0.5)

        # prepare configuration and map history
        if self.hot_seat is 0 and self.against_ai is 0:
            self.config = {"mode-": "Singleplayer", " points-": str(points1)}
        elif self.hot_seat and self.against_ai is 0:
            self.config = {
                "mode-": "Hotseat",
                " P1 points-": str(points1),
                " P2 points-": str(points2)
            }
        elif self.hot_seat is 0 and self.against_ai:
            self.config = {
                "mode-": "Against Bot",
                " P1 points-": str(points1),
                " P2 points-": str(points2)
            }
        with open("config.json", "w") as f:
            json.dump(self.config, f)

        tree = ET.ElementTree(root)
        tree.write("replay.xml")

        if (self.hot_seat and self.against_ai is 0) or (self.hot_seat is 0
                                                        and self.against_ai):
            if points1 == points2:
                self.scoreboard.setText("It's draw! 1.P1 score - " +
                                        str(points1) + " | 2.P2 score - " +
                                        str(points2))
            elif points1 > points2:
                self.scoreboard.setText("P1 won! 1.P1 score - " +
                                        str(points1) + " | 2.P2 score - " +
                                        str(points2))
            else:
                self.scoreboard.setText("P2 won! 1.P1 score - " +
                                        str(points1) + " | 2.P2 score - " +
                                        str(points2))
        else:
            self.scoreboard.setText("You lost! Your score - " + str(points1))
Ejemplo n.º 6
0
class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        view = QGraphicsView()
        self.scene = QGraphicsScene()
        self.scene.setSceneRect(QRectF(0, 0, *WINDOW_SIZE))

        felt = QBrush(QPixmap(os.path.join('images', 'felt.png')))
        self.scene.setBackgroundBrush(felt)

        name = QGraphicsPixmapItem()
        name.setPixmap(QPixmap(os.path.join('images', 'ronery.png')))
        name.setPos(QPointF(170, 375))
        self.scene.addItem(name)

        view.setScene(self.scene)

        # Timer for the win animation only.
        self.timer = QTimer()
        self.timer.setInterval(5)
        self.timer.timeout.connect(self.win_animation)

        self.animation_event_cover = AnimationCover()
        self.scene.addItem(self.animation_event_cover)

        menu = self.menuBar().addMenu("&Game")

        deal_action = QAction(
            QIcon(os.path.join('images', 'playing-card.png')), "Deal...", self)
        deal_action.triggered.connect(self.restart_game)
        menu.addAction(deal_action)

        menu.addSeparator()

        deal1_action = QAction("1 card", self)
        deal1_action.setCheckable(True)
        deal1_action.triggered.connect(lambda: self.set_deal_n(1))
        menu.addAction(deal1_action)

        deal3_action = QAction("3 card", self)
        deal3_action.setCheckable(True)
        deal3_action.setChecked(True)
        deal3_action.triggered.connect(lambda: self.set_deal_n(3))

        menu.addAction(deal3_action)

        dealgroup = QActionGroup(self)
        dealgroup.addAction(deal1_action)
        dealgroup.addAction(deal3_action)
        dealgroup.setExclusive(True)

        menu.addSeparator()

        rounds3_action = QAction("3 rounds", self)
        rounds3_action.setCheckable(True)
        rounds3_action.setChecked(True)
        rounds3_action.triggered.connect(lambda: self.set_rounds_n(3))
        menu.addAction(rounds3_action)

        rounds5_action = QAction("5 rounds", self)
        rounds5_action.setCheckable(True)
        rounds5_action.triggered.connect(lambda: self.set_rounds_n(5))
        menu.addAction(rounds5_action)

        roundsu_action = QAction("Unlimited rounds", self)
        roundsu_action.setCheckable(True)
        roundsu_action.triggered.connect(lambda: self.set_rounds_n(None))
        menu.addAction(roundsu_action)

        roundgroup = QActionGroup(self)
        roundgroup.addAction(rounds3_action)
        roundgroup.addAction(rounds5_action)
        roundgroup.addAction(roundsu_action)
        roundgroup.setExclusive(True)

        menu.addSeparator()

        quit_action = QAction("Quit", self)
        quit_action.triggered.connect(self.quit)
        menu.addAction(quit_action)

        self.deck = []
        self.deal_n = 3  # Number of cards to deal each time
        self.rounds_n = 3  # Number of rounds (restacks) before end.

        for suit in SUITS:
            for value in range(1, 14):
                card = Card(value, suit)
                self.deck.append(card)
                self.scene.addItem(card)
                card.signals.doubleclicked.connect(
                    lambda card=card: self.auto_drop_card(card))

        self.setCentralWidget(view)
        self.setFixedSize(*WINDOW_SIZE)

        self.deckstack = DeckStack()
        self.deckstack.setPos(OFFSET_X, OFFSET_Y)
        self.scene.addItem(self.deckstack)

        # Set up the working locations.
        self.works = []
        for n in range(7):
            stack = WorkStack()
            stack.setPos(OFFSET_X + CARD_SPACING_X * n, WORK_STACK_Y)
            self.scene.addItem(stack)
            self.works.append(stack)

        self.drops = []
        # Set up the drop locations.
        for n in range(4):
            stack = DropStack()
            stack.setPos(OFFSET_X + CARD_SPACING_X * (3 + n), OFFSET_Y)
            stack.signals.complete.connect(self.check_win_condition)

            self.scene.addItem(stack)
            self.drops.append(stack)

        # Add the deal location.
        self.dealstack = DealStack()
        self.dealstack.setPos(OFFSET_X + CARD_SPACING_X, OFFSET_Y)
        self.scene.addItem(self.dealstack)

        # Add the deal click-trigger.
        dealtrigger = DealTrigger()
        dealtrigger.signals.clicked.connect(self.deal)
        self.scene.addItem(dealtrigger)

        self.shuffle_and_stack()

        self.setWindowTitle("Ronery")
        self.show()

    def restart_game(self):
        reply = QMessageBox.question(
            self, "Deal again", "Are you sure you want to start a new game?",
            QMessageBox.Yes | QMessageBox.No)

        if reply == QMessageBox.Yes:
            self.shuffle_and_stack()

    def quit(self):
        self.close()

    def set_deal_n(self, n):
        self.deal_n = n

    def set_rounds_n(self, n):
        self.rounds_n = n
        self.deckstack.update_stack_status(self.rounds_n)

    def shuffle_and_stack(self):
        # Stop any ongoing animation.
        self.timer.stop()
        self.animation_event_cover.hide()

        # Remove cards from all stacks.
        for stack in [self.deckstack, self.dealstack
                      ] + self.drops + self.works:
            stack.reset()

        random.shuffle(self.deck)

        # Deal out from the top of the deck, turning over the
        # final card on each line.
        cards = self.deck[:]
        for n, workstack in enumerate(self.works, 1):
            for a in range(n):
                card = cards.pop()
                workstack.add_card(card)
                card.turn_back_up()
                if a == n - 1:
                    card.turn_face_up()

        # Ensure removed from all other stacks here.
        self.deckstack.stack_cards(cards)

    def deal(self):
        if self.deckstack.cards:
            self.dealstack.spread_from = len(self.dealstack.cards)
            for n in range(self.deal_n):
                card = self.deckstack.take_top_card()
                if card:
                    self.dealstack.add_card(card)
                    card.turn_face_up()

        elif self.deckstack.can_restack(self.rounds_n):
            self.deckstack.restack(self.dealstack)
            self.deckstack.update_stack_status(self.rounds_n)

    def auto_drop_card(self, card):
        for stack in self.drops:
            if stack.is_valid_drop(card):
                card.stack.remove_card(card)
                stack.add_card(card)
                break

    def check_win_condition(self):
        complete = all(s.is_complete for s in self.drops)
        if complete:
            # Add click-proof cover to play area.
            self.animation_event_cover.show()
            # Get the stacks of cards from the drop,stacks.
            self.timer.start()

    def win_animation(self):
        # Start off a new card
        for drop in self.drops:
            if drop.cards:
                card = drop.cards.pop()
                if card.vector is None:
                    card.vector = QPoint(-random.randint(3, 10),
                                         -random.randint(0, 10))
                    break

        for card in self.deck:
            if card.vector is not None:
                card.setPos(card.pos() + card.vector)
                card.vector += QPoint(0, 1)  # Gravity
                if card.pos().y() > WINDOW_SIZE[1] - CARD_DIMENSIONS.height():
                    # Bounce the card, losing some energy.
                    card.vector = QPoint(
                        card.vector.x(),
                        -max(1, int(card.vector.y() * BOUNCE_ENERGY)))
                    # Bump back up to base of screen.
                    card.setPos(card.pos().x(),
                                WINDOW_SIZE[1] - CARD_DIMENSIONS.height())

                if card.pos().x() < -CARD_DIMENSIONS.width():
                    card.vector = None
                    # Put the card back where it started.
                    card.stack.add_card(card)