鸿蒙轻松背单词应用开发实战(四)-随机涂抹背诵与学习进度管理

前言

随机涂抹背诵是手动涂抹的进阶功能,系统自动随机选择单词并智能遮挡,帮助用户更高效地记忆。本文详细介绍随机涂抹背诵功能的实现及学习进度管理。

为什么需要随机涂抹?

  1. 避免顺序记忆:打乱顺序,避免位置记忆
  2. 智能优先级:优先复习错误单词
  3. 自动化学习:减少用户操作,提高效率
  4. 科学复习:基于艾宾浩斯遗忘曲线

随机涂抹流程

智能选词

随机遮挡

用户回忆

显示答案

标记结果

更新进度

继续学习?

生成报告

一、智能选词算法

1.1 选词策略

export enum WordSelectionStrategy {
  RANDOM = 'random',           // 纯随机
  WEIGHTED = 'weighted',       // 加权随机
  SEQUENTIAL = 'sequential',   // 顺序
  PRIORITY = 'priority'        // 优先错误单词
}

export class WordSelector {
  private words: WordModel[];
  private strategy: WordSelectionStrategy;
  
  constructor(words: WordModel[], strategy: WordSelectionStrategy) {
    this.words = words;
    this.strategy = strategy;
  }
  
  selectNext(): WordModel | null {
    switch (this.strategy) {
      case WordSelectionStrategy.RANDOM:
        return this.selectRandom();
      case WordSelectionStrategy.WEIGHTED:
        return this.selectWeighted();
      case WordSelectionStrategy.PRIORITY:
        return this.selectPriority();
      default:
        return this.selectSequential();
    }
  }
}

1.2 纯随机选词

selectRandom(): WordModel | null {
  const unlearnedWords = this.words.filter(w => !w.isLearned);
  
  if (unlearnedWords.length === 0) {
    return null;
  }
  
  const randomIndex = Math.floor(Math.random() * unlearnedWords.length);
  return unlearnedWords[randomIndex];
}

1.3 加权随机选词

selectWeighted(): WordModel | null {
  const unlearnedWords = this.words.filter(w => !w.isLearned);
  
  if (unlearnedWords.length === 0) {
    return null;
  }
  
  // 计算权重(错误次数越多,权重越高)
  const weights = unlearnedWords.map(w => 1 + w.errorCount * 2);
  const totalWeight = weights.reduce((sum, w) => sum + w, 0);
  
  // 随机选择
  let random = Math.random() * totalWeight;
  
  for (let i = 0; i < unlearnedWords.length; i++) {
    random -= weights[i];
    if (random <= 0) {
      return unlearnedWords[i];
    }
  }
  
  return unlearnedWords[0];
}

1.4 选词流程图

随机

加权

优先

开始选词

选词策略

过滤未学习

计算权重

排序错误单词

随机选择

加权随机

有错误单词?

70%选择错误单词

随机数<0.7?

返回错误单词

返回选中单词

二、随机遮挡实现

2.1 遮挡模式

export enum MaskMode {
  WORD = 'word',               // 遮挡单词
  TRANSLATION = 'translation', // 遮挡翻译
  RANDOM = 'random'            // 随机遮挡
}

export class MaskGenerator {
  static generateMaskMode(mode: MaskMode): 'word' | 'translation' {
    if (mode === MaskMode.RANDOM) {
      return Math.random() < 0.5 ? 'word' : 'translation';
    }
    return mode;
  }
  
  static generateMaskedText(text: string): string {
    const maskChar = '■';
    return maskChar.repeat(text.length);
  }
}

2.2 遮挡效果展示

@Builder
MaskedContent(word: WordModel, maskMode: 'word' | 'translation') {
  Column() {
    // 单词行
    if (maskMode === 'word') {
      Text(MaskGenerator.generateMaskedText(word.word))
        .fontSize(28)
        .fontColor('#333333')
        .fontWeight(FontWeight.Bold);
    } else {
      Text(word.word)
        .fontSize(28)
        .fontColor('#333333')
        .fontWeight(FontWeight.Bold);
    }
    
    Divider().width('80%').color('#E0E0E0').margin({ top: 20, bottom: 20 });
    
    // 翻译行
    if (maskMode === 'translation') {
      Text(MaskGenerator.generateMaskedText(word.translation))
        .fontSize(24)
        .fontColor('#333333');
    } else {
      Text(word.translation)
        .fontSize(24)
        .fontColor('#333333');
    }
  }
  .width('100%')
  .alignItems(HorizontalAlign.Center);
}

图 1 遮挡效果展示
在这里插入图片描述

三、学习进度管理

3.1 进度数据结构

export class StudyProgress {
  wordId: number;
  totalAttempts: number = 0;
  correctAttempts: number = 0;
  errorAttempts: number = 0;
  lastStudyTime: number = 0;
  nextReviewTime: number = 0;
  masteryLevel: number = 0;  // 掌握等级(0-5)
  
  constructor(wordId: number) {
    this.wordId = wordId;
  }
  
  getAccuracy(): number {
    if (this.totalAttempts === 0) return 0;
    return Math.round((this.correctAttempts / this.totalAttempts) * 100);
  }
  
  isMastered(): boolean {
    return this.masteryLevel >= 4 && this.getAccuracy() >= 80;
  }
}

3.2 进度管理器

export class ProgressManager {
  private progressMap: Map<number, StudyProgress> = new Map();
  private static instance: ProgressManager;
  
  static getInstance(): ProgressManager {
    if (!ProgressManager.instance) {
      ProgressManager.instance = new ProgressManager();
    }
    return ProgressManager.instance;
  }
  
  recordResult(wordId: number, isCorrect: boolean) {
    let progress = this.progressMap.get(wordId);
    
    if (!progress) {
      progress = new StudyProgress(wordId);
      this.progressMap.set(wordId, progress);
    }
    
    progress.totalAttempts++;
    if (isCorrect) {
      progress.correctAttempts++;
      progress.masteryLevel = Math.min(5, progress.masteryLevel + 1);
    } else {
      progress.errorAttempts++;
      progress.masteryLevel = Math.max(0, progress.masteryLevel - 1);
    }
    
    progress.lastStudyTime = Date.now();
    progress.nextReviewTime = this.calculateNextReview(progress);
  }
}

3.3 进度更新流程

进度数据 进度管理器 页面 用户 进度数据 进度管理器 页面 用户 标记正确/错误 recordResult(id, isCorrect) 更新尝试次数 更新正确/错误次数 更新掌握等级 计算下次复习时间 返回更新结果 显示进度更新

四、艾宾浩斯遗忘曲线

4.1 复习间隔计算

export class EbbinghausCalculator {
  // 艾宾浩斯遗忘曲线复习间隔(小时)
  private static readonly REVIEW_INTERVALS = [
    0.5, 1, 2, 6, 12, 24, 48, 72, 168, 336, 720
  ];
  
  static calculateNextReview(progress: StudyProgress): number {
    const level = Math.min(progress.masteryLevel, this.REVIEW_INTERVALS.length - 1);
    const intervalHours = this.REVIEW_INTERVALS[level];
    return Date.now() + intervalHours * 60 * 60 * 1000;
  }
  
  static needsReview(progress: StudyProgress): boolean {
    return Date.now() >= progress.nextReviewTime;
  }
}

4.2 遗忘曲线示意图

学习新单词

30分钟后复习

1小时后复习

2小时后复习

6小时后复习

12小时后复习

1天后复习

2天后复习

7天后复习

14天后复习

30天后复习

长期记忆

五、随机涂抹页面实现

5.1 页面状态

@Entry
@Component
struct RandomStudyPage {
  @State currentWord: WordModel | null = null;
  @State maskMode: 'word' | 'translation' = 'word';
  @State showAnswer: boolean = false;
  @State studyCount: number = 0;
  @State correctCount: number = 0;
  @State isComplete: boolean = false;
  
  private selector: WordSelector | null = null;
  private progressManager: ProgressManager = ProgressManager.getInstance();
  
  aboutToAppear() {
    const words = WordDataManager.getInstance().getCurrentBook()?.words || [];
    this.selector = new WordSelector(words, WordSelectionStrategy.PRIORITY);
    this.loadNextWord();
  }
  
  loadNextWord() {
    if (!this.selector) return;
    
    const word = this.selector.selectNext();
    
    if (word) {
      this.currentWord = word;
      this.maskMode = MaskGenerator.generateMaskMode(MaskMode.RANDOM);
      this.showAnswer = false;
    } else {
      this.isComplete = true;
    }
  }
}

5.2 标记结果

markResult(isCorrect: boolean) {
  if (!this.currentWord) return;
  
  // 记录进度
  this.progressManager.recordResult(this.currentWord.id, isCorrect);
  
  // 更新统计
  this.studyCount++;
  if (isCorrect) {
    this.correctCount++;
  }
  
  // 加载下一个单词
  this.loadNextWord();
}

六、学习报告生成

6.1 报告数据结构

export class StudyReport {
  totalWords: number = 0;
  studiedWords: number = 0;
  masteredWords: number = 0;
  averageAccuracy: number = 0;
  studyTime: number = 0;
  wordDetails: WordReportDetail[] = [];
  
  getSummary(): string {
    return `本次学习共${this.studiedWords}个单词,正确率${this.averageAccuracy}%,已掌握${this.masteredWords}个单词`;
  }
}

6.2 报告展示

@Builder
ReportView(report: StudyReport) {
  Column() {
    Text('学习报告')
      .fontSize(24)
      .fontWeight(FontWeight.Bold)
      .margin({ bottom: 20 });
    
    Row() {
      this.StatCard('总单词', report.totalWords, '#4A90E2');
      this.StatCard('已学习', report.studiedWords, '#67C23A');
      this.StatCard('已掌握', report.masteredWords, '#E6A23C');
    }
    .width('100%')
    .justifyContent(FlexAlign.SpaceEvenly);
    
    Column() {
      Text('平均正确率')
        .fontSize(16)
        .fontColor('#999999');
      
      Text(`${report.averageAccuracy}%`)
        .fontSize(36)
        .fontColor('#67C23A')
        .fontWeight(FontWeight.Bold);
    }
    .margin({ top: 30 });
  }
  .width('90%')
  .padding(20)
  .backgroundColor('#FFFFFF')
  .borderRadius(15);
}

图 2 报告展示
在这里插入图片描述

七、总结

本文详细介绍了随机涂抹背诵功能的实现。通过智能选词算法、随机遮挡机制、学习进度管理和艾宾浩斯遗忘曲线,实现了科学高效的单词记忆功能。

核心要点

  1. 智能选词:多种选词策略,优先错误单词
  2. 随机遮挡:灵活的遮挡模式,增加学习趣味性
  3. 进度管理:详细记录学习过程,可视化学习效果
  4. 科学复习:基于遗忘曲线,合理安排复习时间

系列文章导航:
下期预告: 鸿蒙轻松背单词应用开发实战(五)-UI界面设计与交互优化

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐