diff --git a/miniprogram/app.json b/miniprogram/app.json index d8f7bd5..d7e3575 100644 --- a/miniprogram/app.json +++ b/miniprogram/app.json @@ -36,6 +36,7 @@ "lineRecognition/lineRecognition", "gridReasoning/gridReasoning", "codeConnect/codeConnect", + "dotConnect/dotConnect", "colorShapeMatch/colorShapeMatch" ], "independent": false diff --git a/miniprogram/assets/focusEntrance/dot-connect.png b/miniprogram/assets/focusEntrance/dot-connect.png new file mode 100644 index 0000000..a27eedf Binary files /dev/null and b/miniprogram/assets/focusEntrance/dot-connect.png differ diff --git a/miniprogram/assets/mathEntrance/number-object-fill.png b/miniprogram/assets/mathEntrance/number-object-fill.png new file mode 100644 index 0000000..56c5fa3 Binary files /dev/null and b/miniprogram/assets/mathEntrance/number-object-fill.png differ diff --git a/miniprogram/constants/focusFunctions.ts b/miniprogram/constants/focusFunctions.ts index 439234c..7570b23 100644 --- a/miniprogram/constants/focusFunctions.ts +++ b/miniprogram/constants/focusFunctions.ts @@ -87,10 +87,19 @@ export const FOCUS_FUNCTION_TYPES: FocusFunctionType[] = [ id: 'code-connect', page: 'codeConnect', title: '译码连线', - desc: '按照数字顺序,将数字对应的颜色连起来', + desc: '按照数字顺序,将数字对应的颜色连线', icon: '🔢', img: '/assets/focusEntrance/code-connect.png', }, + // 数字点连线 + { + id: 'dot-connect', + page: 'dotConnect', + title: '数字点连线', + desc: '按数字顺序连点', + icon: '🔗', + img: '/assets/focusEntrance/dot-connect.png', + }, // 格子仿画 { id: 'grid-drawing-3x3', diff --git a/miniprogram/constants/mathFunctions.ts b/miniprogram/constants/mathFunctions.ts index 987e9c7..fdb5d29 100644 --- a/miniprogram/constants/mathFunctions.ts +++ b/miniprogram/constants/mathFunctions.ts @@ -46,11 +46,19 @@ export const MATH_FUNCTION_TYPES: MathFunctionType[] = [ { id: 'number-object-match', page: 'numberObjectMatch', - title: '数物对应', + title: '数物连线', desc: '连线相同数量的物品和数字', icon: '🔗', img: '/assets/mathEntrance/number-object-match.png', }, + { + id: 'number-object-fill', + page: 'numberObjectMatch', + title: '数物填写', + desc: '数一数物品数量,填写对应的数字', + icon: '✏️', + img: '/assets/mathEntrance/number-object-fill.png', + }, { id: 'counting-select', page: 'countingSelect', diff --git a/miniprogram/focusPages/colorPattern/colorPattern.ts b/miniprogram/focusPages/colorPattern/colorPattern.ts index 90d2c1f..c3cb9ed 100644 --- a/miniprogram/focusPages/colorPattern/colorPattern.ts +++ b/miniprogram/focusPages/colorPattern/colorPattern.ts @@ -88,7 +88,7 @@ createFocusPage({ const selectedShape = selectedShapes[groupIndex]; // 每一行独立选择2种或3种颜色 - const colorCount = Math.random() < 0.5 ? 2 : 3; // 随机选择2种或3种 + const colorCount = 2; const shuffledColors = [...allColors].sort( () => Math.random() - 0.5, ); diff --git a/miniprogram/focusPages/dotConnect/dotConnect.json b/miniprogram/focusPages/dotConnect/dotConnect.json new file mode 100644 index 0000000..1581412 --- /dev/null +++ b/miniprogram/focusPages/dotConnect/dotConnect.json @@ -0,0 +1,13 @@ +{ + "navigationBarTitleText": "数字点连线", + "navigationBarBackgroundColor": "#FFD719", + "homeButton": true, + "backgroundColor": "#F6F6F6", + "enablePullDownRefresh": false, + "usingComponents": { + "toy-button": "../../ui/button/button", + "share-guide-popup": "../../components/share-guide-popup/share-guide-popup", + "math-bottom-buttons": "../../components/math-bottom-buttons/math-bottom-buttons", + "draw-ad": "../../components/draw-ad/draw-ad" + } +} diff --git a/miniprogram/focusPages/dotConnect/dotConnect.ts b/miniprogram/focusPages/dotConnect/dotConnect.ts new file mode 100644 index 0000000..e7c4352 --- /dev/null +++ b/miniprogram/focusPages/dotConnect/dotConnect.ts @@ -0,0 +1,180 @@ +import DotConnectDraw from '../shared/service/dotConnectDraw'; +import { createFocusPage } from '../shared/common/focusPageMixin'; +import { DotConnectData } from '../shared/service/dotConnectDraw'; +import { getRandomUniqueNumberColors } from '../../constants/colors'; + +createFocusPage({ + canvas: null as Canvas | null, + ctx: null as RenderingContext | null, + boxHeight: 0, + boxWidth: 0, + drawService: null as DotConnectDraw | null, + dotConnectData: null as DotConnectData | null, + + data: { + pageTitle: '数字点连线', + functionId: '', + hasContent: false, + showShareDialog: false, + }, + + onLoad(options: { id?: string }) { + const functionId = options.id || 'dot-connect'; + this.setData({ + functionId, + }); + this.initPageInfo(functionId, '数字点连线'); + }, + + onReady() { + this.initCanvas({ + createDrawService: ( + canvas: Canvas, + ctx: RenderingContext, + options?: Record, + ) => { + return new DotConnectDraw(canvas, ctx, options); + }, + drawServiceOptions: { + title: this.data.pageTitle, + functionId: this.data.functionId, + }, + onCanvasReady: () => { + // 初始随机生成 + this.onRandom(); + }, + }); + }, + + /** + * 绘制Canvas内容 + */ + async drawCanvas() { + if (!this.ctx || !this.drawService || !this.dotConnectData) { + return; + } + + try { + await this.drawService.draw(this.dotConnectData); + this.setData({ hasContent: true }); + } catch (error) { + console.error('绘制失败:', error); + this.setData({ hasContent: false }); + } + }, + + /** + * 生成不走回头路的数字序列 + * @param length 序列长度 + * @returns 数字序列数组 + */ + generateNonBacktrackingSequence(length: number): number[] { + // 3x3 网格中数字的位置映射 + // 1: (0,0), 2: (1,0), 3: (2,0) + // 4: (0,1), 5: (1,1), 6: (2,1) + // 7: (0,2), 8: (1,2), 9: (2,2) + const getPosition = (num: number): [number, number] => { + const row = Math.floor((num - 1) / 3); + const col = (num - 1) % 3; + return [row, col]; + }; + + // 检查从位置A到位置B再到位置C是否走回头路 + const isBacktrack = ( + posA: [number, number], + posB: [number, number], + posC: [number, number], + ): boolean => { + // 如果C等于A,说明走回头路了 + return posC[0] === posA[0] && posC[1] === posA[1]; + }; + + const sequence: number[] = []; + const used = new Set(); + + // 随机选择起始数字 + const startNum = Math.floor(Math.random() * 9) + 1; + sequence.push(startNum); + used.add(startNum); + + let prevPos = getPosition(startNum); + let prevPrevPos: [number, number] | null = null; + + // 生成剩余的数字 + while (sequence.length < length) { + const candidates: number[] = []; + for (let num = 1; num <= 9; num++) { + if (used.has(num)) continue; + + const currentPos = getPosition(num); + // 如果有前前一个位置,检查是否走回头路 + if (prevPrevPos) { + if (isBacktrack(prevPrevPos, prevPos, currentPos)) { + continue; + } + } + candidates.push(num); + } + + if (candidates.length === 0) { + // 如果没有候选数字,随机选择一个未使用的数字 + const remaining = Array.from( + { length: 9 }, + (_, i) => i + 1, + ).filter((n) => !used.has(n)); + if (remaining.length === 0) break; + const nextNum = + remaining[Math.floor(Math.random() * remaining.length)]; + sequence.push(nextNum); + used.add(nextNum); + prevPrevPos = prevPos; + prevPos = getPosition(nextNum); + } else { + // 随机选择一个候选数字 + const nextNum = + candidates[Math.floor(Math.random() * candidates.length)]; + sequence.push(nextNum); + used.add(nextNum); + prevPrevPos = prevPos; + prevPos = getPosition(nextNum); + } + } + + return sequence; + }, + + /** + * 随机生成 + */ + onRandom() { + // 生成1-9的数字颜色映射(每个数字使用随机颜色) + const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]; + const colors = getRandomUniqueNumberColors(9); + const colorMap = numbers.map((number, index) => ({ + number, + color: colors[index], + })); + + // 生成9个组的题目 + const groups: Array<{ + sequence: number[]; + }> = []; + + for (let i = 0; i < 9; i++) { + // 生成不走回头路的数字序列,长度在4-6之间 + const sequenceLength = Math.floor(Math.random() * 3) + 4; // 4, 5, 或 6 + const sequence = + this.generateNonBacktrackingSequence(sequenceLength); + groups.push({ + sequence, + }); + } + + this.dotConnectData = { + colorMap, + groups, + }; + + this.drawCanvas(); + }, +}); diff --git a/miniprogram/focusPages/dotConnect/dotConnect.wxml b/miniprogram/focusPages/dotConnect/dotConnect.wxml new file mode 100644 index 0000000..3b70e13 --- /dev/null +++ b/miniprogram/focusPages/dotConnect/dotConnect.wxml @@ -0,0 +1,6 @@ + + + +