class GameScreen(QWidget): def __init__(self): # Call parent class's __init__() super().__init__() self.board = GameBoard() self.board.setFixedSize(600, 600) self.game_status = QLabel() self.game_status.setObjectName("gameStatus") self.game_status.setMaximumHeight(30) self.game_status.setAlignment(QtCore.Qt.AlignCenter) self.reset_button = QPushButton("Reset") self.reset_button.clicked.connect(self.reset_game) self.reset_button.setCursor(QtCore.Qt.CursorShape.PointingHandCursor) self.reset_button.setMinimumWidth(120) self.exit_button = QPushButton("Exit Game") self.exit_button.clicked.connect(sys.exit) self.exit_button.setCursor(QtCore.Qt.CursorShape.PointingHandCursor) self.exit_button.setMinimumWidth(120) self.control_panel = QVBoxLayout() self.control_panel.addWidget(self.game_status) self.control_panel.addWidget(self.reset_button) self.control_panel.addWidget(self.exit_button) self.main_layout = QBoxLayout(QBoxLayout.Direction.LeftToRight) self.main_layout.addWidget(self.board) self.main_layout.addLayout(self.control_panel) # Set layout self.setLayout(self.main_layout) def resizeEvent(self, event): offset = -self.board.main_layout.spacing() * self.board.main_layout.rowCount() width = self.size().width() + offset height = self.size().height() + offset excess = width - height if excess >= 0: min_cp_width = self.control_panel.minimumSize().width() margin = max([0, min_cp_width - excess + self.main_layout.spacing()]) height -= margin self.main_layout.setDirection(QBoxLayout.Direction.LeftToRight) self.board.setFixedSize(height, height) self.board.setContentsMargins(0, 0, 0, 0) else: min_cp_height = self.control_panel.minimumSize().height() margin = max([0, min_cp_height + excess + self.main_layout.spacing()]) width -= margin self.main_layout.setDirection(QBoxLayout.Direction.TopToBottom) self.board.setFixedSize(width + margin - self.main_layout.spacing(), width) self.board.setContentsMargins( (margin - self.main_layout.spacing()) / 2, 0, (margin - self.main_layout.spacing()) / 2, 0, ) super().resizeEvent(event) def reset_game(self): for cell in self.board.findChildren(QPushButton): cell.setText(" ") cell.setStyleSheet("") self.game_status.setText("") def get_state(self): state = [] cell_type = {"X": 1.0, "O": -1.0, " ": 0.0} for cell in self.board.findChildren(QPushButton): state.append(cell_type[cell.text()]) # Add a batch dimension return torch.tensor(state).unsqueeze(0).to(self.device) def num_actions_available(self): num_actions_available = 0 for cell in self.board.findChildren(QPushButton): if cell.text() == " ": num_actions_available += 1 return num_actions_available def take_action(self, action): player = "X" if self.board.x_turn else "O" print(self.board.findChildren(QPushButton)[action.item()]) self.board.findChildren(QPushButton)[action.item()].setText(player) self.board.x_turn = not self.board.x_turn if (game_status := self.board.check_game_status()) == 0: self.game_status.setText("It's a tie!") self.done = True return torch.tensor([1], device=self.device) elif game_status == 1: self.game_status.setText("X has won!") self.done = True return torch.tensor([-1 + (self.board.x_turn) * 3], device=self.device)