You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复Wordle克隆Telegram Bot有效输入仍触发「无效输入」的问题?

问题根源

你的代码核心问题是错误地在onUpdateReceived里使用死循环。Telegram LongPollingBot是事件驱动模型:每收到一条用户消息,就会调用一次onUpdateReceived方法。你在用户输入"Wordle"后启动的while(true)循环,会一直复用当前的update对象(也就是用户输入"Wordle"的那条消息),永远获取不到用户后续输入的新单词,导致playerWord始终是"Wordle",自然通不过checkString校验,反复触发"invalid input"提示。

另外,turns、last这些游戏状态变量是onUpdateReceived的局部变量,每次收到新消息都会被重置,根本无法保存游戏进度。

修复方案

1. 定义游戏状态类

先创建一个类来保存每个聊天的游戏状态:

data class GameState(
    val targetWord: String,
    var turns: Int = 0,
    var matchedLetters: String = ""
)

2. 全局维护游戏状态映射

在Bot类里添加一个Map,用来记录每个聊天ID对应的游戏状态:

class MyAmazingBot : TelegramLongPollingBot() {
    // 保存每个聊天的游戏状态,key是chatId字符串
    private val activeGames = mutableMapOf<String, GameState>()

    // 省略getBotToken()等必要方法...
}

3. 重构onUpdateReceived逻辑

移除死循环,改成事件驱动的分支处理:

override fun onUpdateReceived(update: Update) {
    if (!update.hasMessage() || !update.message.hasText()) return

    val chatId = update.message.chatId.toString()
    val input = update.message.text.trim()
    val message = SendMessage(chatId, "")

    // 分支1:用户启动游戏
    if (input == "Wordle") {
        val candidateWordsFile = "candidate words file"
        val targetWord = getRandomWord(candidateWordsFile)
        
        // 初始化游戏状态
        activeGames[chatId] = GameState(targetWord)
        message.text = "Please enter a 5-letter word: "
        execute(message)
        return
    }

    // 分支2:用户输入/exit退出游戏
    if (input == "/exit") {
        activeGames.remove(chatId)
        message.text = "The game is over."
        execute(message)
        return
    }

    // 分支3:处理游戏中的用户猜测
    val gameState = activeGames[chatId] ?: return // 不在游戏中则直接返回

    // 校验输入格式
    if (!checkString(input)) {
        message.text = "Invalid input. Please enter a valid 5-letter word."
        execute(message)
        return
    }

    // 校验单词是否在词典中
    val dictionaryFile = "dictionary file"
    if (!File(dictionaryFile).readLines().contains(input)) {
        message.text = "The input word isn't included in my words list."
        execute(message)
        return
    }

    gameState.turns++

    // 猜对了的情况
    if (input == gameState.targetWord) {
        message.text = "Correct! The solution was found after ${gameState.turns} tries."
        execute(message)
        activeGames.remove(chatId) // 结束游戏
        return
    }

    // 未猜对,生成反馈
    val matchResult = findMatches(input, gameState.targetWord)
    val incorrectPositions = matchResult.substring(0, 5)
    gameState.matchedLetters += matchResult.substring(5)
    
    val uniqueMatchedLetters = gameState.matchedLetters.toSet().sorted().joinToString("")
    message.text = "Matching letters: $uniqueMatchedLetters\nIncorrect positions: $incorrectPositions"
    execute(message)
}

关键修改点说明

  • 移除了while(true)死循环,改用事件驱动的分支判断,每次用户输入都会触发对应的逻辑
  • 用activeGames Map保存每个聊天的游戏状态,避免每次调用onUpdateReceived时重置状态
  • 明确区分了「启动游戏」「退出游戏」「游戏中猜测」三种场景,逻辑更清晰
  • 每次处理完用户输入后直接返回,不会阻塞后续的消息处理

内容的提问来源于stack exchange,提问作者Condor mitnick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 23:43:21