import GridReasoningDraw from '../shared/service/gridReasoningDraw'; import { createFocusPage } from '../shared/common/focusPageMixin'; import { GridReasoningData, GridPosition, } from '../shared/service/gridReasoningDraw'; import { NUMBER_COLORS } from '../../constants/colors'; createFocusPage({ canvas: null as Canvas | null, ctx: null as RenderingContext | null, boxHeight: 0, boxWidth: 0, drawService: null as GridReasoningDraw | null, gridData: null as GridReasoningData | null, data: { pageTitle: '方格推理', functionId: '', hasContent: false, showShareDialog: false, currentOperatorType: 'mixed', // 'addition', 'subtraction', 'mixed' currentOperatorTypeName: '混合运算', operatorTypeActions: [ { name: '加法运算', value: 'addition' }, { name: '减法运算', value: 'subtraction' }, { name: '混合运算', value: 'mixed' }, ], }, onLoad(options: { id?: string }) { const functionId = options.id || 'grid-reasoning'; this.setData({ functionId, }); this.initPageInfo(functionId, '方格推理'); }, onReady() { this.initCanvas({ createDrawService: ( canvas: Canvas, ctx: RenderingContext, options?: Record, ) => { return new GridReasoningDraw(canvas, ctx, options); }, drawServiceOptions: { title: this.data.pageTitle, subTitle: '仔细观察,推理出合并方格并连线', functionId: this.data.functionId, }, onCanvasReady: () => { // 初始随机生成 this.onRandom(); }, }); }, /** * 绘制Canvas内容 */ async drawCanvas() { if (!this.ctx || !this.drawService || !this.gridData) { return; } try { await this.drawService.draw(this.gridData); this.setData({ hasContent: true }); } catch (error) { console.error('绘制失败:', error); this.setData({ hasContent: false }); } }, /** * 选择运算类型 */ onSelectType(event: any) { const { name, value } = event.detail; this.setData({ currentOperatorType: value, currentOperatorTypeName: name, }); // 重新生成题目 this.onRandom(); }, /** * 随机生成 */ onRandom() { // 随机选择一种颜色 const colorKeys = Object.keys(NUMBER_COLORS).map(Number); const randomColorKey = colorKeys[Math.floor(Math.random() * colorKeys.length)]; const selectedColor = NUMBER_COLORS[randomColorKey]; const rows: Array<{ grid1: GridPosition[]; grid2: GridPosition[]; operator: '+' | '-'; result: GridPosition[]; }> = []; const operatorType = this.data.currentOperatorType; // 生成5行的数据 for (let i = 0; i < 5; i++) { // 根据选中的运算类型选择运算符 let operator: '+' | '-'; if (operatorType === 'addition') { operator = '+'; } else if (operatorType === 'subtraction') { operator = '-'; } else { // 混合运算:随机选择运算符 operator = Math.random() > 0.5 ? '+' : '-'; } // 生成第一个网格的涂色位置 // 如果是减法运算,第一个网格至少要有2个位置 let grid1Count: number; if (operator === '-') { grid1Count = Math.floor(Math.random() * 8) + 2; // 2-9个位置 } else { grid1Count = Math.floor(Math.random() * 9) + 1; // 1-9个位置 } const grid1Positions = this.generateRandomPositions(grid1Count); let grid2Positions: GridPosition[]; let resultPositions: GridPosition[]; if (operator === '+') { // 加法:生成第二个网格的涂色位置(至少1个) const grid2Count = Math.floor(Math.random() * 9) + 1; grid2Positions = this.generateRandomPositions(grid2Count); // 结果 = 并集 resultPositions = this.unionPositions( grid1Positions, grid2Positions, ); } else { // 减法:生成第二个网格的涂色位置(必须少于第一个) const maxGrid2Count = grid1Count - 1; const grid2Count = Math.floor(Math.random() * maxGrid2Count) + 1; grid2Positions = this.generateRandomPositions(grid2Count); // 结果 = 差集 resultPositions = this.subtractPositions( grid1Positions, grid2Positions, ); } rows.push({ grid1: grid1Positions, grid2: grid2Positions, operator: operator as '+' | '-', result: resultPositions, }); } // 生成右侧答案选项 // 右侧展示左侧5行的结果(result),顺序随机 const answerOptions: Array<{ positions: GridPosition[]; rowIndex: number; }> = []; for (let i = 0; i < 5; i++) { answerOptions.push({ positions: rows[i].result, rowIndex: i, }); } // 随机打乱顺序 answerOptions.sort(() => Math.random() - 0.5); this.gridData = { rows, answerOptions, color: selectedColor, }; this.drawCanvas(); }, /** * 生成随机位置(不重复) */ generateRandomPositions(count: number): GridPosition[] { const allPositions: GridPosition[] = []; for (let y = 0; y < 3; y++) { for (let x = 0; x < 3; x++) { allPositions.push({ x, y }); } } // 随机打乱 const shuffled = [...allPositions].sort(() => Math.random() - 0.5); // 返回前count个 return shuffled.slice(0, count); }, /** * 计算位置的并集 */ unionPositions(pos1: GridPosition[], pos2: GridPosition[]): GridPosition[] { const set = new Set(); const result: GridPosition[] = []; // 添加第一个数组的位置 for (const pos of pos1) { const key = `${pos.x},${pos.y}`; if (!set.has(key)) { set.add(key); result.push(pos); } } // 添加第二个数组的位置(去重) for (const pos of pos2) { const key = `${pos.x},${pos.y}`; if (!set.has(key)) { set.add(key); result.push(pos); } } return result; }, /** * 计算位置的差集(pos1 - pos2) */ subtractPositions( pos1: GridPosition[], pos2: GridPosition[], ): GridPosition[] { const set2 = new Set(); for (const pos of pos2) { set2.add(`${pos.x},${pos.y}`); } const result: GridPosition[] = []; for (const pos of pos1) { const key = `${pos.x},${pos.y}`; if (!set2.has(key)) { result.push(pos); } } return result; }, });