129 lines
3.6 KiB
TypeScript
129 lines
3.6 KiB
TypeScript
import BreakTenDraw from '../shared/service/breakTenDraw';
|
|
import {
|
|
createMathPage,
|
|
CanvasDataState,
|
|
} from '../shared/common/mathPageMixin';
|
|
|
|
createMathPage({
|
|
canvas: null as Canvas | null,
|
|
ctx: null as RenderingContext | null,
|
|
boxHeight: 0,
|
|
boxWidth: 0,
|
|
drawService: null as BreakTenDraw | null,
|
|
breakTenData: null as {
|
|
problems: Array<{
|
|
minuend: number; // 被减数
|
|
subtrahend: number; // 减数
|
|
result: number;
|
|
}>;
|
|
} | null,
|
|
|
|
data: {
|
|
pageTitle: '破十法练习',
|
|
subTitle: '通过破十法学习20以内退位减法',
|
|
functionId: '',
|
|
hasContent: false,
|
|
showShareDialog: false,
|
|
} as CanvasDataState,
|
|
|
|
onLoad(options: { id?: string }) {
|
|
const functionId = options.id || 'break-ten';
|
|
this.initPageInfo(functionId, '破十法练习');
|
|
},
|
|
|
|
onReady() {
|
|
this.initCanvas({
|
|
createDrawService: (
|
|
canvas: Canvas,
|
|
ctx: RenderingContext,
|
|
options?: Record<string, any>,
|
|
) => {
|
|
return new BreakTenDraw(canvas, ctx, options);
|
|
},
|
|
drawServiceOptions: {
|
|
subTitle: this.data.subTitle,
|
|
},
|
|
onCanvasReady: () => {
|
|
// 初始随机生成
|
|
this.onRandom();
|
|
},
|
|
});
|
|
},
|
|
|
|
/**
|
|
* 绘制Canvas内容
|
|
*/
|
|
async drawCanvas() {
|
|
if (!this.ctx || !this.drawService || !this.breakTenData) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
await this.drawService.draw(this.breakTenData);
|
|
this.setData({ hasContent: true });
|
|
} catch (error) {
|
|
console.error('绘制失败:', error);
|
|
this.setData({ hasContent: false });
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 随机生成
|
|
*/
|
|
onRandom() {
|
|
const problems: Array<{
|
|
minuend: number;
|
|
subtrahend: number;
|
|
result: number;
|
|
}> = [];
|
|
// 用于记录已生成的题目,避免重复
|
|
const usedProblems = new Set<string>();
|
|
|
|
// 生成9道题目(3行3列)
|
|
let attempts = 0;
|
|
const maxAttempts = 1000; // 最大尝试次数,避免无限循环
|
|
|
|
while (problems.length < 9 && attempts < maxAttempts) {
|
|
attempts++;
|
|
// 生成两个数,确保:
|
|
// 1. 被减数大于10且小于等于20
|
|
// 2. 减数小于10
|
|
// 3. 结果大于0(被减数 > 减数)
|
|
const minuend = Math.floor(Math.random() * 10) + 11; // 11-20
|
|
const subtrahend = Math.floor(Math.random() * 9) + 1; // 1-9
|
|
|
|
// 确保被减数 > 减数
|
|
if (minuend <= subtrahend) {
|
|
continue;
|
|
}
|
|
|
|
const result = minuend - subtrahend;
|
|
|
|
// 检查是否重复
|
|
const problemKey = `${minuend},${subtrahend}`;
|
|
if (usedProblems.has(problemKey)) {
|
|
continue;
|
|
}
|
|
|
|
// 添加到已使用集合
|
|
usedProblems.add(problemKey);
|
|
|
|
problems.push({
|
|
minuend,
|
|
subtrahend,
|
|
result,
|
|
});
|
|
}
|
|
|
|
// 如果尝试次数过多仍未生成足够的题目,输出警告
|
|
if (problems.length < 9) {
|
|
console.warn(
|
|
`只生成了 ${problems.length} 道题目,可能符合条件的题目组合不足`,
|
|
);
|
|
}
|
|
|
|
this.breakTenData = { problems };
|
|
this.drawCanvas();
|
|
},
|
|
});
|