jiang buqing
1. 删除放弃按钮
2e254f6
// Semantic Hunter Game Frontend
/**
* UI类 - 负责DOM操作和UI渲染
*/
class SemanticHunterUI {
constructor() {
// DOM元素
this.guessInput = document.getElementById('guess-input');
this.guessBtn = document.getElementById('guess-btn');
this.messageArea = document.getElementById('message-area');
this.guessesList = document.getElementById('guesses-list');
this.newGameBtn = document.getElementById('new-game-btn');
this.itemsPerPage = 7;
}
// 清空输入框并聚焦
clearAndFocusInput() {
this.guessInput.value = '';
this.guessInput.focus();
}
// 获取输入值
getInputValue() {
return this.guessInput.value.trim();
}
// 显示消息
showMessage(msg) {
this.messageArea.innerHTML = `<p class="message">${msg}</p>`;
}
// 显示错误消息
showError(msg) {
this.messageArea.innerHTML = `<p class="message error">${msg}</p>`;
}
// 显示成功消息
showSuccess(msg) {
this.messageArea.innerHTML = `<p class="message success">${msg}</p>`;
}
// 重置猜测列表
resetGuessList() {
this.guessesList.innerHTML = '';
this.messageArea.innerHTML = '';
}
// 获取相似度样式类
getSimilarityClass(similarity) {
if (similarity === 100) {
return 'similarity-perfect';
} else if (similarity >= 90) {
return 'similarity-super-high';
} else if (similarity >= 80) {
return 'similarity-very-high';
} else if (similarity >= 70) {
return 'similarity-high';
} else if (similarity >= 50) {
return 'similarity-medium';
} else {
return 'similarity-low';
}
}
// 渲染猜测列表,包括最新猜测和历史猜测
renderGuessList(guesses, latestGuess, currentPage) {
this.guessesList.innerHTML = '';
// 渲染最新猜测(如果有)
if (latestGuess) {
this.renderLatestGuess(latestGuess, guesses);
}
// 渲染历史猜测列表
this.renderHistoryGuesses(guesses, latestGuess, currentPage);
return guesses;
}
// 渲染最新猜测(置顶显示)
renderLatestGuess(latestGuess, guesses) {
// 寻找最新猜测的详细信息
const latestGuessData = guesses.find(g => g.word === latestGuess.word);
if (!latestGuessData) return;
// 创建最新猜测的容器
const latestGuessContainer = document.createElement('div');
latestGuessContainer.className = 'latest-guess-container';
// 添加最新猜测并使用不同样式
const latestGuessElement = document.createElement('div');
latestGuessElement.className = 'latest-guess';
// 如果100%匹配,添加perfect-match类
if (latestGuessData.similarity === 100) {
latestGuessElement.classList.add('perfect-match');
}
// 确定相似度颜色类
const similarityClass = this.getSimilarityClass(latestGuessData.similarity);
latestGuessElement.innerHTML = `
<span class="guess-word">${latestGuessData.word}</span>
<span class="guess-similarity ${similarityClass}">${latestGuessData.similarity}%</span>
`;
latestGuessContainer.appendChild(latestGuessElement);
// 添加分隔线
const separator = document.createElement('div');
separator.className = 'guess-separator';
latestGuessContainer.appendChild(separator);
this.guessesList.appendChild(latestGuessContainer);
}
// 渲染历史猜测列表
renderHistoryGuesses(guesses, latestGuess, currentPage) {
// 创建历史猜测的容器
const historyContainer = document.createElement('div');
historyContainer.className = 'history-guesses-container';
// 获取当前页的项目
const startIndex = (currentPage - 1) * this.itemsPerPage;
const endIndex = Math.min(startIndex + this.itemsPerPage, guesses.length);
const currentPageItems = guesses.slice(startIndex, endIndex);
// 添加当前页的猜测
currentPageItems.forEach(guess => {
// 如果有最新猜测且与当前历史猜测相同,则跳过(避免重复显示)
if (latestGuess && guess.word === latestGuess.word) {
return;
}
const guessItem = document.createElement('div');
guessItem.className = 'guess-item';
// 如果100%匹配,添加perfect-match类
if (guess.similarity === 100) {
guessItem.classList.add('perfect-match');
}
// 确定相似度颜色类
const similarityClass = this.getSimilarityClass(guess.similarity);
guessItem.innerHTML = `
<span class="guess-word">${guess.word}</span>
<span class="guess-similarity ${similarityClass}">${guess.similarity}%</span>
`;
historyContainer.appendChild(guessItem);
});
this.guessesList.appendChild(historyContainer);
}
// 添加分页控件
addPagination(allGuesses, currentPage, onPageChange) {
const totalPages = Math.ceil(allGuesses.length / this.itemsPerPage);
if (totalPages <= 1) return; // 如果只有一页,不显示分页控件
// 创建分页容器
const paginationContainer = document.createElement('div');
paginationContainer.className = 'pagination-container';
// 上一页按钮
const prevBtn = document.createElement('button');
prevBtn.className = 'pagination-btn prev-btn';
prevBtn.innerHTML = `<i class="fas fa-chevron-left"></i>`;
prevBtn.disabled = currentPage === 1;
prevBtn.addEventListener('click', () => {
if (currentPage > 1) {
onPageChange(currentPage - 1);
}
});
// 页面指示器
const pageIndicator = document.createElement('div');
pageIndicator.className = 'page-indicator';
pageIndicator.textContent = `${currentPage} / ${totalPages}`;
// 下一页按钮
const nextBtn = document.createElement('button');
nextBtn.className = 'pagination-btn next-btn';
nextBtn.innerHTML = `<i class="fas fa-chevron-right"></i>`;
nextBtn.disabled = currentPage === totalPages;
nextBtn.addEventListener('click', () => {
if (currentPage < totalPages) {
onPageChange(currentPage + 1);
}
});
// 将按钮添加到容器
paginationContainer.appendChild(prevBtn);
paginationContainer.appendChild(pageIndicator);
paginationContainer.appendChild(nextBtn);
// 添加到DOM
this.guessesList.appendChild(paginationContainer);
}
}
/**
* API类 - 负责与后端通信
*/
class SemanticHunterAPI {
// 获取当前游戏状态
async getGameStatus() {
try {
const response = await fetch('/game-status', {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
});
return await response.json();
} catch (error) {
console.error('获取游戏状态时出错:', error);
throw new Error('无法连接到服务器');
}
}
// 初始化新游戏
async initGame() {
try {
const response = await fetch('/new-game', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
});
return await response.json();
} catch (error) {
console.error('初始化游戏时出错:', error);
throw new Error('无法连接到服务器');
}
}
// 提交猜测
async submitGuess(guess) {
try {
const response = await fetch('/guess', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ guess })
});
return await response.json();
} catch (error) {
console.error('提交猜测时出错:', error);
throw new Error('无法连接到服务器');
}
}
}
/**
* 游戏控制器 - 处理游戏逻辑
*/
class SemanticHunterGame {
constructor() {
this.ui = new SemanticHunterUI();
this.api = new SemanticHunterAPI();
// 游戏状态
this.gameActive = true; // 默认假设游戏是活跃的
this.latestGuess = null; // 只在前端存储最新猜测
this.allGuesses = []; // 所有猜测历史
this.currentPage = 1; // 当前分页
// 初始设置新游戏按钮为禁用状态
this.ui.newGameBtn.disabled = true;
// 初始化事件监听器
this.initEventListeners();
// 加载游戏状态
this.loadGameStatus();
}
// 初始化事件监听器
initEventListeners() {
this.ui.guessBtn.addEventListener('click', () => this.submitGuess());
this.ui.guessInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') this.submitGuess();
});
this.ui.newGameBtn.addEventListener('click', () => this.initGame());
}
// 加载游戏状态 - 从后端获取当前状态
async loadGameStatus() {
try {
const data = await this.api.getGameStatus();
if (data.status === 'success') {
// 更新游戏状态
this.allGuesses = data.guesses;
this.gameActive = !data.has_correct_guess;
// 如果有猜测历史,渲染它们
if (this.allGuesses.length > 0) {
// 不指定最新猜测,所有猜测都在历史列表中显示
this.updateGuessList(this.allGuesses, null);
// 如果已经猜对了
if (!this.gameActive) {
const correctGuess = this.allGuesses.find(g => g.is_correct);
if (correctGuess) {
this.ui.showSuccess(`有人已经猜对了! 秘密词语是: ${correctGuess.word}`);
}
} else {
this.ui.showMessage('游戏进行中! 尝试猜测秘密词语!');
}
} else {
this.ui.showMessage('游戏开始! 尝试猜测秘密词语!');
}
// 更新新游戏按钮状态
this.updateNewGameButton();
// 清空输入框并聚焦
this.ui.clearAndFocusInput();
} else {
this.ui.showError('获取游戏状态失败');
}
} catch (error) {
this.ui.showError(error.message);
}
}
// 初始化游戏 - 创建新游戏
async initGame() {
try {
const data = await this.api.initGame();
if (data.status === 'success') {
this.gameActive = true;
this.ui.resetGuessList();
this.ui.clearAndFocusInput();
this.allGuesses = [];
this.latestGuess = null;
this.currentPage = 1;
this.ui.showMessage('新游戏开始! 尝试猜测秘密词语!');
// 更新新游戏按钮状态
this.updateNewGameButton();
} else {
this.ui.showError(data.message || '初始化游戏时出错');
}
} catch (error) {
this.ui.showError(error.message);
}
}
// 提交猜测
async submitGuess() {
const guessWord = this.ui.getInputValue();
if (!guessWord) return;
if (!this.gameActive) {
this.ui.showError('游戏已结束,请点击新游戏');
return;
}
try {
const data = await this.api.submitGuess(guessWord);
if (data.status === 'success') {
// 更新猜测历史
this.allGuesses = data.guesses;
// 在前端存储最新的猜测
this.latestGuess = {
word: guessWord,
similarity: data.similarity,
is_correct: data.is_correct
};
// 渲染猜测列表,将最新猜测置顶
this.updateGuessList(this.allGuesses, this.latestGuess);
// 根据猜测结果更新游戏状态和显示消息
if (data.is_correct) {
this.gameActive = false;
this.ui.showSuccess(`恭喜你猜对了! 秘密词语是: ${guessWord}`);
} else {
this.ui.showMessage(`相似度: ${data.similarity}%`);
}
// 更新新游戏按钮状态
this.updateNewGameButton();
// 清空输入框并聚焦
this.ui.clearAndFocusInput();
} else {
this.ui.showError(data.message || '提交猜测时出错');
}
} catch (error) {
this.ui.showError(error.message);
}
}
// 更新猜测列表 - 同时处理最新猜测和历史猜测
updateGuessList(guesses, latestGuess) {
// 渲染猜测列表
this.ui.renderGuessList(guesses, latestGuess, this.currentPage);
// 如果有多页,添加分页控件
if (guesses.length > this.ui.itemsPerPage) {
this.ui.addPagination(guesses, this.currentPage, (newPage) => {
this.currentPage = newPage;
this.updateGuessList(guesses, latestGuess);
});
}
}
// 更新新游戏按钮状态
updateNewGameButton() {
// 检查是否有正确的猜测
const hasCorrectGuess = this.allGuesses.some(guess => guess.is_correct);
// 只有在游戏已结束(有正确猜测)时,新游戏按钮才可用
this.ui.newGameBtn.disabled = !hasCorrectGuess;
}
}
// 当DOM内容加载完成时初始化游戏
document.addEventListener('DOMContentLoaded', () => {
new SemanticHunterGame();
});