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

如何在Visual Basic闪卡应用中实现类似Anki的答错闪卡高频展示机制

实现Anki风格的闪卡智能调度功能

Got it, let's tackle this smart scheduling feature similar to Anki. Here's a step-by-step approach to implement weighted flashcard selection based on user feedback:

1. 数据库准备

首先给你的Access数据表添加一个Weight字段(建议用双精度数字类型),默认值设为1.0。这个值代表闪卡的展示优先级:值越高,被选中的概率越大;值越低,概率越小。

2. 代码修改与实现

2.1 添加全局变量记录当前闪卡ID

在窗体类顶部添加变量,用来追踪当前显示的闪卡,方便后续更新权重:

Private currentCardId As Integer ' 假设你的表有主键ID字段,用来唯一标识闪卡

2.2 实现加权随机选择算法

替换原来的简单随机,改用加权随机,让高权重的闪卡更易被选中:

' 加权随机选择闪卡索引的核心方法
Private Function GetWeightedRandomCardIndex() As Integer
    If dt.Rows.Count = 0 Then Return -1

    ' 计算所有闪卡的权重总和
    Dim totalWeight As Double = 0
    For Each row As DataRow In dt.Rows
        totalWeight += CDbl(row("Weight"))
    Next

    ' 生成0到总权重之间的随机值
    Dim randomValue As Double = rand.NextDouble() * totalWeight
    Dim cumulativeWeight As Double = 0

    ' 遍历找到对应的闪卡索引
    For i As Integer = 0 To dt.Rows.Count - 1
        cumulativeWeight += CDbl(dt.Rows(i)("Weight"))
        If cumulativeWeight >= randomValue Then
            Return i
        End If
    Next

    ' 兜底返回最后一个闪卡(防止极端情况)
    Return dt.Rows.Count - 1
End Function

2.3 修改展示按钮逻辑

更新btnDisplay_Click,记录当前闪卡的ID:

Private Sub btnDisplay_Click(sender As Object, e As EventArgs) Handles btnDisplay.Click
    btnDisplay.Enabled = False
    Dim index = GetWeightedRandomCardIndex()
    If index = -1 Then
        MsgBox("No flashcards available!")
        Return
    End If
    currentCardId = CInt(dt.Rows(index)(0)) ' 假设第0列是主键ID
    txtFront.Text = dt.Rows(index)(2).ToString()
    txtBack.Visible = False
    txtBack.Text = dt.Rows(index)(3).ToString()
End Sub

2.4 重构反馈按钮逻辑(复用代码+更新权重)

提取公共方法处理权重更新和切换闪卡,避免重复代码:

' 公共方法:更新当前闪卡权重并切换到下一张
Private Sub UpdateCardWeightAndNext(weightMultiplier As Double)
    If Not txtBack.Visible Then
        MsgBox("Please first reveal the back of the flashcard")
        Return
    End If

    ' 找到当前闪卡的行,更新权重
    Dim currentRow As DataRow = dt.Select($"ID = {currentCardId}")(0)
    Dim currentWeight As Double = CDbl(currentRow("Weight"))
    
    ' 根据用户反馈调整权重:Hard提升,Easy降低,Good保持
    ' 你可以根据需求调整乘数(比如Hard用2.0,Easy用0.3)
    currentRow("Weight") = currentWeight * weightMultiplier

    ' !重要:把更新后的权重写回数据库,否则重启程序后丢失
    ' 假设你用OleDbDataAdapter,调用以下代码:
    ' adapter.Update(dt)

    ' 切换到下一张加权随机闪卡
    Dim index = GetWeightedRandomCardIndex()
    If index = -1 Then
        MsgBox("No flashcards available!")
        Return
    End If
    currentCardId = CInt(dt.Rows(index)(0))
    txtFront.Text = dt.Rows(index)(2).ToString()
    txtBack.Visible = False
    txtBack.Text = dt.Rows(index)(3).ToString()
End Sub

Private Sub btnEasy_Click(sender As Object, e As EventArgs) Handles btnEasy.Click
    ' Easy:降低权重,减少后续展示概率
    UpdateCardWeightAndNext(0.5)
End Sub

Private Sub btnGood_Click(sender As Object, e As EventArgs) Handles btnGood.Click
    ' Good:权重保持不变(或轻微调整,比如乘以1.1)
    UpdateCardWeightAndNext(1.0)
End Sub

Private Sub btnHard_Click(sender As Object, e As EventArgs) Handles btnHard.Click
    ' Hard:提升权重,增加后续展示概率
    UpdateCardWeightAndNext(1.5)
End Sub

3. 关键细节说明

  • 权重范围限制:可以给权重加个上下限(比如最小0.1,最大5.0),避免某些闪卡永远出现或彻底消失,比如在更新权重时加判断:
    currentRow("Weight") = Math.Max(0.1, Math.Min(5.0, currentWeight * weightMultiplier))
    
  • 数据库持久化:一定要确保更新后的权重被写回数据库,否则每次重启程序都会回到初始值,这一步依赖你原来的DataAdapter配置。
  • 乘数调整:你可以根据实际使用情况调整权重乘数,比如Hard用2.0让难的闪卡出现频率翻倍,Easy用0.4让简单闪卡出现频率大幅降低。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 22:57:37