mirror of
https://github.com/LHY0125/Gobang-Game.git
synced 2026-06-29 00:45:55 +08:00
feat: 实现认输和保存棋谱功能
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -176,3 +176,22 @@ pub fn get_game_state(state: State<AppState>) -> Result<serde_json::Value, Strin
|
|||||||
"game_over": game_over,
|
"game_over": game_over,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub fn resign(state: State<AppState>) -> Result<(), String> {
|
||||||
|
let player_color = *state.current_color.lock().map_err(|e| e.to_string())?;
|
||||||
|
// 当前玩家认输,对手获胜
|
||||||
|
let winner = player_color.opponent();
|
||||||
|
*state.game_over.lock().map_err(|e| e.to_string())? = true;
|
||||||
|
*state.current_color.lock().map_err(|e| e.to_string())? = winner;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub fn save_record(state: State<AppState>) -> Result<String, String> {
|
||||||
|
let board_opt = state.board.lock().map_err(|e| e.to_string())?;
|
||||||
|
let board = board_opt.as_ref().ok_or("游戏未开始")?;
|
||||||
|
|
||||||
|
let record = gobang_core::record::GameRecord::from_board(board, "玩家", "对手", None);
|
||||||
|
serde_json::to_string_pretty(&record).map_err(|e| e.to_string())
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ pub fn run() {
|
|||||||
|
|
||||||
commands::ai_move,
|
commands::ai_move,
|
||||||
commands::get_game_state,
|
commands::get_game_state,
|
||||||
|
commands::resign,
|
||||||
|
commands::save_record,
|
||||||
])
|
])
|
||||||
.run(tauri::generate_context!())
|
.run(tauri::generate_context!())
|
||||||
.expect("error while running tauri application");
|
.expect("error while running tauri application");
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { invoke } from '@tauri-apps/api/core';
|
||||||
import { useGameStore } from '../../store/gameStore';
|
import { useGameStore } from '../../store/gameStore';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -9,16 +10,43 @@ export default function GameControls({ onBackToMenu }: Props) {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const undo = useGameStore((s) => s.undo);
|
const undo = useGameStore((s) => s.undo);
|
||||||
const status = useGameStore((s) => s.status);
|
const status = useGameStore((s) => s.status);
|
||||||
|
const refreshBoard = useGameStore((s) => s.refreshBoard);
|
||||||
|
|
||||||
const handleUndo = () => {
|
const handleUndo = () => {
|
||||||
undo(1);
|
undo(1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleResign = async () => {
|
||||||
|
await invoke('resign');
|
||||||
|
await refreshBoard();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSave = async () => {
|
||||||
|
try {
|
||||||
|
const json: string = await invoke('save_record');
|
||||||
|
const blob = new Blob([json], { type: 'application/json' });
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = `gobang_${Date.now()}.json`;
|
||||||
|
a.click();
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('保存棋谱失败:', e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="game-controls">
|
<div className="game-controls">
|
||||||
<button onClick={handleUndo} disabled={status === 'game_over'}>
|
<button onClick={handleUndo} disabled={status === 'game_over'}>
|
||||||
{t('game.undo')}
|
{t('game.undo')}
|
||||||
</button>
|
</button>
|
||||||
|
<button onClick={handleResign} disabled={status === 'game_over'}>
|
||||||
|
{t('game.resign')}
|
||||||
|
</button>
|
||||||
|
<button onClick={handleSave}>
|
||||||
|
{t('game.save')}
|
||||||
|
</button>
|
||||||
<button onClick={onBackToMenu}>{t('game.new_game')}</button>
|
<button onClick={onBackToMenu}>{t('game.new_game')}</button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user