Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 31 additions & 5 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
# 插件系统(新)
from plugin_sdk import GameServerBridge
from plugin_manager.app_paths import get_env_for_subprocess
from shared_types.commands import NewGameCommand
from shared_types.commands import NewGameCommand, MouseClickCommand
from shared_types.enums import GameLevel
import subprocess

os.environ["QT_FONT_DPI"] = "96"
Expand Down Expand Up @@ -199,15 +200,40 @@ def cli_check_file(file_path: str) -> int:
ui._plugin_process = plugin_process # 保存引用,防止被 GC

GameServerBridge.instance().start()

# 注册控制命令处理器(自动在主线程执行)
def handle_new_game(cmd: NewGameCommand):
print(f"[NewGameCommand] rows={cmd.rows}, cols={cmd.cols}, mines={cmd.mines}")
ui.setBoard_and_start(cmd.rows, cmd.cols, cmd.mines)
"""处理新游戏命令"""
from lib_zmq_plugins.shared.base import CommandResponse

# 根据 level 确定参数
if cmd.level == GameLevel.BEGINNER.value:
rows, cols, mines = 8, 8, 10
elif cmd.level == GameLevel.INTERMEDIATE.value:
rows, cols, mines = 16, 16, 40
elif cmd.level == GameLevel.EXPERT.value:
rows, cols, mines = 16, 30, 99
else:
# 自定义模式,使用传入的参数
rows, cols, mines = cmd.rows, cmd.cols, cmd.mines

print(
f"[NewGameCommand] level={cmd.level}, rows={rows}, cols={cols}, mines={mines}")
ui.setBoard_and_start(rows, cols, mines)
return CommandResponse(request_id=cmd.request_id, success=True)


def handle_mouse_click(cmd: MouseClickCommand):
"""处理鼠标点击命令"""
from lib_zmq_plugins.shared.base import CommandResponse

print(
f"[MouseClickCommand] row={cmd.row}, col={cmd.col}, button={cmd.button}")
success = ui.execute_cell_click(cmd.row, cmd.col, cmd.button)
return CommandResponse(request_id=cmd.request_id, success=success)

GameServerBridge.instance().register_handler(NewGameCommand, handle_new_game)
GameServerBridge.instance().register_handler(
MouseClickCommand, handle_mouse_click)

# _translate = QtCore.QCoreApplication.translate
hwnd = int(ui.mainWindow.winId())
Expand Down
79 changes: 78 additions & 1 deletion src/mineSweeperGUI.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# from PyQt5.QtWidgets import QApplication, QFileDialog, QWidget
import gameDefinedParameter
from plugin_sdk.server_bridge import GameServerBridge
from shared_types.events import VideoSaveEvent
from shared_types.events import VideoSaveEvent, BoardUpdateEvent, GameStatusChangeEvent
import superGUI
import gameAbout
import gameSettings
Expand Down Expand Up @@ -37,6 +37,7 @@


class MineSweeperGUI(MineSweeperVideoPlayer):

def __init__(self, MainWindow: MainWindow, args):
self.mainWindow = MainWindow
self.checksum_guard = metaminesweeper_checksum.ChecksumGuard()
Expand Down Expand Up @@ -219,6 +220,8 @@ def game_state(self):
@game_state.setter
def game_state(self, game_state: str):
# print(self._game_state, " -> " ,game_state)
last_state = self._game_state

match self._game_state:
case "playing":
self.try_append_evfs(game_state)
Expand Down Expand Up @@ -252,8 +255,31 @@ def game_state(self, game_state: str):
self.label.paint_cursor = False
self.label.paintProbability = False
self.num_bar_ui.QWidget.close()

self._game_state = game_state

# 发送游戏状态变化事件
state_map = {
"ready": 1,
"playing": 2,
"win": 3,
"fail": 4,
"joking": 2, # joking 也视为游戏中
"jowin": 3,
"jofail": 4,
"show": 5,
"study": 6,
"display": 7,
"showdisplay": 8,
}
if last_state != game_state:
event = GameStatusChangeEvent(
last_status=state_map.get(last_state, 0),
current_status=state_map.get(game_state, 0),
)
GameServerBridge.instance().send_event(event)
self._send_board_update_event()

@property
def row(self):
return self._row
Expand Down Expand Up @@ -477,6 +503,54 @@ def mineNumWheel(self, i):
# self.timer_mine_num.setSingleShot(True)
# self.timer_mine_num.start(3000)

def _send_board_update_event(self):
"""发送棋盘更新事件给插件"""
try:
ms_board = self.label.ms_board
# 将 game_board 转换为列表格式
game_board_list = []
for row in ms_board.game_board:
game_board_list.append(list(row))

event = BoardUpdateEvent(
rows=self.row,
cols=self.column,
game_board=game_board_list,
mines_remaining=self.mineUnFlagedNum,
game_time=ms_board.time if hasattr(ms_board, 'time') else 0.0,
)
GameServerBridge.instance().send_event(event)
except Exception:
pass # 忽略发送失败

def execute_cell_click(self, row: int, col: int, button: int):
"""
执行格子点击(供外部命令调用)

Args:
row: 行索引(从 0 开始)
col: 列索引(从 0 开始)
button: 鼠标按钮(0=左键, 1=中键, 2=右键)
"""
if row < 0 or row >= self.row or col < 0 or col >= self.column:
return False
x = row * self.pixSize
y = col * self.pixSize
if button == 0:
self.mineAreaLeftPressed(x, y)
self.mineAreaLeftRelease(x, y)
elif button == 1:
self.mineAreaLeftPressed(x, y)
self.mineAreaLeftAndRightPressed(x, y)
self.mineAreaRightRelease(x, y)
self.mineAreaLeftRelease(x, y)
else:
self.mineAreaRightPressed(x, y)
self.mineAreaRightRelease(x, y)

self._send_board_update_event()
return True

def gameStart(self):
# 画界面,但是不埋雷。等价于点脸、f2、设置确定后的效果
self.mineUnFlagedNum = self.minenum # 没有标出的雷,显示在左上角
Expand Down Expand Up @@ -571,6 +645,9 @@ def gameFinished(self):
event = VideoSaveEvent(**data)
GameServerBridge.instance().send_event(event)

# 发送棋盘更新事件,让插件知道最终状态
self._send_board_update_event()

def gameWin(self): # 成功后改脸和状态变量,停时间
self.timer_10ms.stop()
self.score_board_manager.editing_row = -1
Expand Down
3 changes: 3 additions & 0 deletions src/mineSweeperGUIEvent.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ def mineAreaLeftRelease(self, i, j):
return
else:
self.label.update()
self._send_board_update_event()
self.set_face(14)
elif self.game_state == 'playing' or self.game_state == 'joking':
# 如果是游戏中,且是左键抬起(不是双击),且是在10上,且在局面内,则用ai劫持、处理下
Expand All @@ -88,6 +89,7 @@ def mineAreaLeftRelease(self, i, j):
self.label.update()
return
self.label.update()
self._send_board_update_event()
self.set_face(14)

elif self.game_state == 'show':
Expand Down Expand Up @@ -121,6 +123,7 @@ def mineAreaRightRelease(self, i, j):
self.chording_ai(i // self.pixSize, j // self.pixSize)
self.label.ms_board.step('rr', (i, j))
self.label.update()
self._send_board_update_event()
self.set_face(14)
elif self.game_state == 'show':
# 看概率时,所有操作都移出局面外
Expand Down
8 changes: 8 additions & 0 deletions src/plugins/llm_minesweeper_controller/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""
llm_minesweeper_controller - 使用requests进行反向控制扫雷并处理func calling的插件
"""
from __future__ import annotations

from .plugin import LlmMinesweeperControllerPlugin

__all__ = ["LlmMinesweeperControllerPlugin"]
Loading
Loading