feat: Puente Mayúscula-Minúscula + TTS SpeechSynthesis + E2E fixes
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
import type { Stage } from '../types'
|
||||
|
||||
const exercises: any[] = []
|
||||
|
||||
// Count 1-5
|
||||
for (let n = 1; n <= 5; n++) {
|
||||
const emojis = '⭐'.repeat(n)
|
||||
exercises.push({
|
||||
id: `num1-contar-${n}`,
|
||||
stage: 1,
|
||||
skillCode: `contar-${n}`,
|
||||
type: 'sensibilizacion',
|
||||
prerequisites: n === 1 ? [] : [`num1-contar-${n - 1}`],
|
||||
content: {
|
||||
instruction: `Contá. ¿Cuántas estrellas hay?`,
|
||||
audioText: `Uno, dos, tres...`,
|
||||
emoji: emojis,
|
||||
options: [
|
||||
...Array.from({ length: 5 }, (_, i) => i + 1)
|
||||
.filter(j => j !== n)
|
||||
.slice(0, 2)
|
||||
.map(j => ({ label: String(j), correct: false, id: String(j) })),
|
||||
{ label: String(n), correct: true, id: String(n) },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
},
|
||||
functionalContext: `Contar hasta ${n} elementos.`,
|
||||
errorType: 'discriminacion-auditiva',
|
||||
})
|
||||
}
|
||||
|
||||
// Recognize written digits 1-5
|
||||
for (let n = 1; n <= 5; n++) {
|
||||
exercises.push({
|
||||
id: `num1-digito-${n}`,
|
||||
stage: 1,
|
||||
skillCode: `digito-${n}`,
|
||||
type: 'eleccion',
|
||||
prerequisites: [`num1-contar-${n}`],
|
||||
content: {
|
||||
instruction: `Señalá el número ${n}`,
|
||||
audioText: `Buscá el número ${n}`,
|
||||
options: [
|
||||
...Array.from({ length: 5 }, (_, i) => i + 1)
|
||||
.filter(j => j !== n)
|
||||
.slice(0, 2)
|
||||
.map(j => ({ label: String(j), correct: false, id: String(j) })),
|
||||
{ label: String(n), correct: true, id: String(n) },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
emoji: String(n),
|
||||
},
|
||||
functionalContext: `Reconocer el dígito ${n}.`,
|
||||
errorType: 'confusion-letra',
|
||||
})
|
||||
}
|
||||
|
||||
// Trace with finger
|
||||
for (let n = 1; n <= 5; n++) {
|
||||
exercises.push({
|
||||
id: `num1-trazo-${n}`,
|
||||
stage: 1,
|
||||
skillCode: `digito-${n}`,
|
||||
type: 'trazo',
|
||||
prerequisites: [`num1-digito-${n}`],
|
||||
content: {
|
||||
instruction: `Trazá el número ${n} con tu dedo`,
|
||||
text: String(n),
|
||||
audioText: `Trazá el número ${n}`,
|
||||
emoji: '✍️',
|
||||
},
|
||||
functionalContext: `Aprender a trazar el número ${n}.`,
|
||||
errorType: 'confusion-letra',
|
||||
})
|
||||
}
|
||||
|
||||
const stage: Stage = {
|
||||
id: 1,
|
||||
name: 'Conteo del 1 al 5',
|
||||
description: 'Contar objetos, reconocer dígitos y trazar números del 1 al 5.',
|
||||
exercises,
|
||||
}
|
||||
|
||||
export default stage
|
||||
@@ -0,0 +1,99 @@
|
||||
import type { Stage } from '../types'
|
||||
|
||||
const exercises: any[] = []
|
||||
|
||||
// Count 6-10
|
||||
for (let n = 6; n <= 10; n++) {
|
||||
const emojis = '🟢'.repeat(n)
|
||||
exercises.push({
|
||||
id: `num2-contar-${n}`,
|
||||
stage: 2,
|
||||
skillCode: `contar-${n}`,
|
||||
prerequisites: n === 6 ? ['num1-trazo-5'] : [`num2-contar-${n - 1}`],
|
||||
type: 'sensibilizacion',
|
||||
content: {
|
||||
instruction: `¿Cuántos círculos verdes hay?`,
|
||||
audioText: `Contá los círculos`,
|
||||
emoji: emojis,
|
||||
options: [
|
||||
...Array.from({ length: 5 }, (_, i) => i + 6)
|
||||
.filter(j => j !== n)
|
||||
.slice(0, 2)
|
||||
.map(j => ({ label: String(j), correct: false, id: String(j) })),
|
||||
{ label: String(n), correct: true, id: String(n) },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
},
|
||||
functionalContext: `Contar hasta ${n} elementos.`,
|
||||
errorType: 'discriminacion-auditiva',
|
||||
})
|
||||
}
|
||||
|
||||
// Recognize written digits 6-10
|
||||
for (let n = 6; n <= 10; n++) {
|
||||
exercises.push({
|
||||
id: `num2-digito-${n}`,
|
||||
stage: 2,
|
||||
skillCode: `digito-${n}`,
|
||||
type: 'eleccion',
|
||||
prerequisites: [`num2-contar-${n}`],
|
||||
content: {
|
||||
instruction: `Señalá el número ${n}`,
|
||||
audioText: `Buscá el ${n}`,
|
||||
options: [
|
||||
...Array.from({ length: 5 }, (_, i) => i + 6)
|
||||
.filter(j => j !== n)
|
||||
.slice(0, 2)
|
||||
.map(j => ({ label: String(j), correct: false, id: String(j) })),
|
||||
{ label: String(n), correct: true, id: String(n) },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
emoji: String(n),
|
||||
},
|
||||
functionalContext: `Reconocer el dígito ${n}.`,
|
||||
errorType: 'confusion-letra',
|
||||
})
|
||||
}
|
||||
|
||||
// Order sequence 1-10
|
||||
exercises.push({
|
||||
id: 'num2-secuencia-1-10',
|
||||
stage: 2,
|
||||
skillCode: 'secuencia-1-10',
|
||||
type: 'secuencia',
|
||||
prerequisites: ['num2-digito-10'],
|
||||
content: {
|
||||
instruction: 'Ordená los números del 1 al 10',
|
||||
audioText: 'Ordená del 1 al 10',
|
||||
sequence: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'],
|
||||
emoji: '🔢',
|
||||
},
|
||||
functionalContext: 'Conocer la secuencia numérica del 1 al 10.',
|
||||
errorType: 'inversion-letra',
|
||||
})
|
||||
|
||||
// Trace 6-10
|
||||
for (let n = 6; n <= 10; n++) {
|
||||
exercises.push({
|
||||
id: `num2-trazo-${n}`,
|
||||
stage: 2,
|
||||
skillCode: `digito-${n}`,
|
||||
type: 'trazo',
|
||||
prerequisites: [`num2-digito-${n}`, ...(n > 6 ? [`num2-trazo-${n - 1}`] : [])],
|
||||
content: {
|
||||
instruction: `Trazá el número ${n} con tu dedo`,
|
||||
text: String(n),
|
||||
audioText: `Trazá el ${n}`,
|
||||
emoji: '✍️',
|
||||
},
|
||||
functionalContext: `Aprender a trazar el número ${n}.`,
|
||||
errorType: 'confusion-letra',
|
||||
})
|
||||
}
|
||||
|
||||
const stage: Stage = {
|
||||
id: 2,
|
||||
name: 'Conteo del 6 al 10',
|
||||
description: 'Contar objetos, reconocer dígitos y trazar números del 6 al 10, y ordenar del 1 al 10.',
|
||||
exercises,
|
||||
}
|
||||
|
||||
export default stage
|
||||
@@ -0,0 +1,107 @@
|
||||
import type { Stage } from '../types'
|
||||
|
||||
const exercises: any[] = []
|
||||
|
||||
// Pair number with quantity
|
||||
for (let n = 1; n <= 10; n++) {
|
||||
const emojis = ['🐶', '🐱', '🐰', '🐸', '🐵', '🐼', '🐨', '🦊', '🐻', '🐯']
|
||||
const animal = emojis[n - 1]
|
||||
const howMany = animal.repeat(Math.min(n, 5)) + (n > 5 ? ` (${n})` : '')
|
||||
|
||||
exercises.push({
|
||||
id: `num3-cantidad-${n}`,
|
||||
stage: 3,
|
||||
skillCode: `correspondencia-${n}`,
|
||||
type: 'conciencia',
|
||||
prerequisites: n === 1 ? ['num2-trazo-10'] : [`num3-cantidad-${n - 1}`],
|
||||
content: {
|
||||
instruction: `¿Cuántos ${animal} hay?`,
|
||||
audioText: `Contá los animalitos`,
|
||||
text: n <= 5 ? animal.repeat(n) : `${animal.repeat(5)}... +${n - 5}`,
|
||||
options: [
|
||||
...Array.from({ length: 10 }, (_, i) => i + 1)
|
||||
.filter(j => j !== n)
|
||||
.slice(0, 2)
|
||||
.map(j => ({ label: String(j), correct: false, id: String(j) })),
|
||||
{ label: String(n), correct: true, id: String(n) },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
emoji: animal,
|
||||
},
|
||||
functionalContext: 'Asociar cantidad con número.',
|
||||
errorType: 'discriminacion-auditiva',
|
||||
})
|
||||
}
|
||||
|
||||
// Match groups that are equal
|
||||
const pares = [
|
||||
{ a: '🐶🐶🐶', b: '3️⃣', num: 3 },
|
||||
{ a: '🐱🐱🐱🐱', b: '4️⃣', num: 4 },
|
||||
{ a: '🐰🐰🐰🐰🐰', b: '5️⃣', num: 5 },
|
||||
{ a: '🐸🐸', b: '2️⃣', num: 2 },
|
||||
{ a: '🐵🐵🐵🐵🐵🐵', b: '6️⃣', num: 6 },
|
||||
]
|
||||
|
||||
for (const { a, b, num } of pares) {
|
||||
exercises.push({
|
||||
id: `num3-emparejar-${num}`,
|
||||
stage: 3,
|
||||
skillCode: 'correspondencia',
|
||||
type: 'conciencia',
|
||||
prerequisites: [`num3-cantidad-${num}`],
|
||||
content: {
|
||||
instruction: `¿Cuál número le corresponde a ${a}?`,
|
||||
audioText: `¿Qué número es?`,
|
||||
text: a,
|
||||
options: [
|
||||
...pares.filter(p => p.num !== num).slice(0, 2).map(p => ({ label: p.b, correct: false, id: String(p.num) })),
|
||||
{ label: b, correct: true, id: String(num) },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
emoji: '🔄',
|
||||
},
|
||||
functionalContext: 'Emparejar grupos con su número.',
|
||||
errorType: 'confusion-letra',
|
||||
})
|
||||
}
|
||||
|
||||
// More/less comparison
|
||||
const comparaciones = [
|
||||
{ a: 3, b: 5, mas: 5, menos: 3 },
|
||||
{ a: 2, b: 7, mas: 7, menos: 2 },
|
||||
{ a: 4, b: 4, mas: 4, menos: 4 },
|
||||
{ a: 6, b: 3, mas: 6, menos: 3 },
|
||||
{ a: 1, b: 9, mas: 9, menos: 1 },
|
||||
]
|
||||
|
||||
for (const { a, b, mas, menos } of comparaciones) {
|
||||
const idA = '⭐'.repeat(a)
|
||||
const idB = '⭐'.repeat(b)
|
||||
exercises.push({
|
||||
id: `num3-mas-${a}-${b}`,
|
||||
stage: 3,
|
||||
skillCode: 'comparacion',
|
||||
type: 'conciencia',
|
||||
prerequisites: [`num3-cantidad-${Math.max(a, b)}`],
|
||||
content: {
|
||||
instruction: `¿Dónde hay MÁS?`,
|
||||
text: `${idA} vs ${idB}`,
|
||||
audioText: `¿Cuál tiene más?`,
|
||||
options: [
|
||||
{ label: `👈 ${a}`, correct: mas === a, id: `izq-${a}` },
|
||||
{ label: `👉 ${b}`, correct: mas === b, id: `der-${b}` },
|
||||
{ label: '😐 Igual', correct: a === b, id: 'igual' },
|
||||
],
|
||||
emoji: '⚖️',
|
||||
},
|
||||
functionalContext: 'Comparar cantidades (más/menos).',
|
||||
errorType: 'discriminacion-auditiva',
|
||||
})
|
||||
}
|
||||
|
||||
const stage: Stage = {
|
||||
id: 3,
|
||||
name: 'Correspondencia uno a uno',
|
||||
description: 'Asociar cantidades con números, emparejar grupos iguales, comparar más y menos.',
|
||||
exercises,
|
||||
}
|
||||
|
||||
export default stage
|
||||
@@ -0,0 +1,83 @@
|
||||
import type { Stage } from '../types'
|
||||
|
||||
const exercises: any[] = []
|
||||
|
||||
for (let n = 11; n <= 20; n++) {
|
||||
exercises.push({
|
||||
id: `num4-contar-${n}`,
|
||||
stage: 4,
|
||||
skillCode: `contar-${n}`,
|
||||
type: 'conciencia',
|
||||
prerequisites: n === 11 ? ['num3-cantidad-10'] : [`num4-contar-${n - 1}`],
|
||||
content: {
|
||||
instruction: `Contá. ¿Cuántos hay? (${n})`,
|
||||
audioText: `Son ${n}`,
|
||||
text: `🔵🔵🔵🔵🔵 🟣🟣🟣🟣🟣 ${n > 10 ? `+${n - 10}` : ''}`,
|
||||
options: [
|
||||
...Array.from({ length: 5 }, (_, i) => n - 2 + i)
|
||||
.filter(j => j >= 10 && j <= 20 && j !== n)
|
||||
.slice(0, 2)
|
||||
.map(j => ({ label: String(j), correct: false, id: String(j) })),
|
||||
{ label: String(n), correct: true, id: String(n) },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
emoji: String(n),
|
||||
},
|
||||
functionalContext: `Reconocer el número ${n}.`,
|
||||
errorType: 'confusion-letra',
|
||||
})
|
||||
}
|
||||
|
||||
// Decenas y unidades visual
|
||||
for (let n = 10; n <= 20; n++) {
|
||||
const decenas = Math.floor(n / 10)
|
||||
const unidades = n % 10
|
||||
exercises.push({
|
||||
id: `num4-descomponer-${n}`,
|
||||
stage: 4,
|
||||
skillCode: 'decenas-unidades',
|
||||
type: 'eleccion',
|
||||
prerequisites: [`num4-contar-${n}`],
|
||||
content: {
|
||||
instruction: `${n} son ${decenas} decena${decenas > 1 ? 's' : ''} y ${unidades} unidades`,
|
||||
text: `🔟🔟${'●'.repeat(unidades)} = ${n}`,
|
||||
audioText: `${n} es ${decenas} decenas y ${unidades} unidades`,
|
||||
options: [
|
||||
{ label: '🔟 Decenas', correct: false, id: `decenas-${n}` },
|
||||
{ label: String(n), correct: true, id: String(n) },
|
||||
...Array.from({ length: 3 }, (_, i) => n + i - 1)
|
||||
.filter(j => j >= 10 && j <= 20 && j !== n)
|
||||
.slice(0, 1)
|
||||
.map(j => ({ label: String(j), correct: false, id: String(j) })),
|
||||
].sort(() => Math.random() - 0.5),
|
||||
emoji: '🔟',
|
||||
},
|
||||
functionalContext: 'Introducir decenas y unidades.',
|
||||
errorType: 'confusion-letra',
|
||||
})
|
||||
}
|
||||
|
||||
// Secuencia 11-20
|
||||
exercises.push({
|
||||
id: 'num4-secuencia-11-20',
|
||||
stage: 4,
|
||||
skillCode: 'secuencia-11-20',
|
||||
type: 'secuencia',
|
||||
prerequisites: ['num4-descomponer-20'],
|
||||
content: {
|
||||
instruction: 'Ordená los números del 11 al 20',
|
||||
audioText: 'Ordená del 11 al 20',
|
||||
sequence: ['11', '12', '13', '14', '15', '16', '17', '18', '19', '20'],
|
||||
emoji: '🔢',
|
||||
},
|
||||
functionalContext: 'Conocer la secuencia del 11 al 20.',
|
||||
errorType: 'inversion-letra',
|
||||
})
|
||||
|
||||
const stage: Stage = {
|
||||
id: 4,
|
||||
name: 'Números del 11 al 20',
|
||||
description: 'Aprender los números del 11 al 20. Introducir decenas y unidades.',
|
||||
exercises,
|
||||
}
|
||||
|
||||
export default stage
|
||||
@@ -0,0 +1,90 @@
|
||||
import type { Stage } from '../types'
|
||||
|
||||
const sumas = [
|
||||
{ a: 1, b: 1, r: 2, emoji: '🐶+🐶' },
|
||||
{ a: 2, b: 1, r: 3, emoji: '🐱+🐶' },
|
||||
{ a: 2, b: 2, r: 4, emoji: '🐱+🐱' },
|
||||
{ a: 3, b: 1, r: 5, emoji: '🐰+🐶' },
|
||||
{ a: 3, b: 2, r: 5, emoji: '🐰+🐱' },
|
||||
{ a: 4, b: 1, r: 5, emoji: '🐸+🐶' },
|
||||
{ a: 5, b: 1, r: 6, emoji: '🐵+🐶' },
|
||||
{ a: 3, b: 3, r: 6, emoji: '🐰+🐰' },
|
||||
{ a: 5, b: 2, r: 7, emoji: '🐵+🐱' },
|
||||
{ a: 4, b: 3, r: 7, emoji: '🐸+🐰' },
|
||||
{ a: 5, b: 3, r: 8, emoji: '🐵+🐰' },
|
||||
{ a: 4, b: 4, r: 8, emoji: '🐸+🐸' },
|
||||
{ a: 5, b: 4, r: 9, emoji: '🐵+🐸' },
|
||||
{ a: 5, b: 5, r: 10, emoji: '🐵+🐵' },
|
||||
{ a: 6, b: 1, r: 7, emoji: '🐼+🐶' },
|
||||
{ a: 6, b: 2, r: 8, emoji: '🐼+🐱' },
|
||||
{ a: 7, b: 1, r: 8, emoji: '🐨+🐶' },
|
||||
{ a: 7, b: 2, r: 9, emoji: '🐨+🐱' },
|
||||
{ a: 8, b: 1, r: 9, emoji: '🦊+🐶' },
|
||||
{ a: 8, b: 2, r: 10, emoji: '🦊+🐱' },
|
||||
{ a: 9, b: 1, r: 10, emoji: '🐻+🐶' },
|
||||
{ a: 3, b: 4, r: 7, emoji: '🐰+🐸' },
|
||||
{ a: 4, b: 5, r: 9, emoji: '🐸+🐵' },
|
||||
{ a: 6, b: 3, r: 9, emoji: '🐼+🐰' },
|
||||
{ a: 7, b: 3, r: 10, emoji: '🐨+🐰' },
|
||||
]
|
||||
|
||||
const exercises: any[] = []
|
||||
|
||||
for (const { a, b, r, emoji } of sumas) {
|
||||
const id = `num5-suma-${a}-${b}`
|
||||
exercises.push({
|
||||
id,
|
||||
stage: 5,
|
||||
skillCode: 'suma',
|
||||
type: 'problema',
|
||||
prerequisites: a <= 5 && b <= 5 ? ['num4-secuencia-11-20'] : [`num5-suma-${a}-${b - 1}`],
|
||||
content: {
|
||||
instruction: `¿Cuánto es ${a} + ${b}?`,
|
||||
text: `${a} + ${b} = ?`,
|
||||
audioText: `${a} más ${b}`,
|
||||
emoji,
|
||||
options: [
|
||||
...Array.from({ length: 4 }, (_, i) => r - 2 + i + (i >= 2 ? 2 : 0))
|
||||
.filter(j => j >= 1 && j <= 12 && j !== r)
|
||||
.slice(0, 2)
|
||||
.map(j => ({ label: String(j), correct: false, id: String(j) })),
|
||||
{ label: String(r), correct: true, id: String(r) },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
},
|
||||
functionalContext: 'Sumar dos números pequeños.',
|
||||
errorType: 'discriminacion-auditiva',
|
||||
})
|
||||
}
|
||||
|
||||
// Represent sum with objects
|
||||
for (const { a, b, r } of sumas.slice(0, 8)) {
|
||||
exercises.push({
|
||||
id: `num5-suma-visual-${a}-${b}`,
|
||||
stage: 5,
|
||||
skillCode: 'suma-visual',
|
||||
type: 'conciencia',
|
||||
prerequisites: [`num5-suma-${a}-${b}`],
|
||||
content: {
|
||||
instruction: `${a} + ${b} es lo mismo que...`,
|
||||
text: `${'●'.repeat(a)} + ${'●'.repeat(b)}`,
|
||||
audioText: `Juntamos ${a} y ${b}, tenemos ${r}`,
|
||||
options: [
|
||||
{ label: '●'.repeat(r), correct: true, id: String(r) },
|
||||
{ label: '●'.repeat(r + 1), correct: false, id: String(r + 1) },
|
||||
{ label: '●'.repeat(Math.max(1, r - 1)), correct: false, id: String(r - 1) },
|
||||
],
|
||||
emoji: '➕',
|
||||
},
|
||||
functionalContext: 'Visualizar la suma como unión de conjuntos.',
|
||||
errorType: 'discriminacion-auditiva',
|
||||
})
|
||||
}
|
||||
|
||||
const stage: Stage = {
|
||||
id: 5,
|
||||
name: 'Sumas simples (1-10)',
|
||||
description: 'Sumar números del 1 al 10 con ayudas visuales y ejercicios progresivos.',
|
||||
exercises,
|
||||
}
|
||||
|
||||
export default stage
|
||||
@@ -0,0 +1,95 @@
|
||||
import type { Stage } from '../types'
|
||||
|
||||
const restas = [
|
||||
{ a: 2, b: 1, r: 1, emoji: '🍎-🍎' },
|
||||
{ a: 3, b: 1, r: 2, emoji: '🍎🍎-🍎' },
|
||||
{ a: 3, b: 2, r: 1, emoji: '🍎🍎-🍎🍎' },
|
||||
{ a: 4, b: 1, r: 3, emoji: '🍪🍪🍪🍪-🍪' },
|
||||
{ a: 4, b: 2, r: 2, emoji: '🍪🍪🍪🍪-🍪🍪' },
|
||||
{ a: 5, b: 1, r: 4, emoji: '⭐-⭐' },
|
||||
{ a: 5, b: 2, r: 3, emoji: '⭐⭐-⭐⭐' },
|
||||
{ a: 5, b: 3, r: 2, emoji: '⭐⭐⭐-⭐⭐⭐' },
|
||||
{ a: 5, b: 4, r: 1, emoji: '⭐⭐⭐⭐-⭐⭐⭐⭐' },
|
||||
{ a: 6, b: 1, r: 5, emoji: '🌸-🌸' },
|
||||
{ a: 6, b: 2, r: 4, emoji: '🌸🌸-🌸🌸' },
|
||||
{ a: 6, b: 3, r: 3, emoji: '🌸🌸🌸-🌸🌸🌸' },
|
||||
{ a: 7, b: 2, r: 5, emoji: '🌻🌻-🌻🌻' },
|
||||
{ a: 7, b: 3, r: 4, emoji: '🌻🌻🌻-🌻🌻🌻' },
|
||||
{ a: 8, b: 3, r: 5, emoji: '🍄🍄🍄-🍄🍄🍄' },
|
||||
{ a: 8, b: 4, r: 4, emoji: '🍄🍄🍄🍄-🍄🍄🍄🍄' },
|
||||
{ a: 9, b: 4, r: 5, emoji: '🍂🍂🍂🍂-🍂🍂🍂🍂' },
|
||||
{ a: 9, b: 5, r: 4, emoji: '🍂🍂🍂🍂🍂-🍂🍂🍂🍂🍂' },
|
||||
{ a: 10, b: 1, r: 9, emoji: '💎-💎' },
|
||||
{ a: 10, b: 2, r: 8, emoji: '💎💎-💎💎' },
|
||||
{ a: 10, b: 3, r: 7, emoji: '💎💎💎-💎💎💎' },
|
||||
{ a: 10, b: 4, r: 6, emoji: '💎💎💎💎-💎💎💎💎' },
|
||||
{ a: 10, b: 5, r: 5, emoji: '💎💎💎💎💎-💎💎💎💎💎' },
|
||||
{ a: 8, b: 5, r: 3, emoji: '🍀🍀🍀🍀🍀-🍀🍀🍀🍀🍀' },
|
||||
{ a: 7, b: 5, r: 2, emoji: '🌺🌺🌺🌺🌺-🌺🌺🌺🌺🌺' },
|
||||
{ a: 6, b: 5, r: 1, emoji: '🌷🌷🌷🌷🌷-🌷🌷🌷🌷🌷' },
|
||||
]
|
||||
|
||||
const exercises: any[] = []
|
||||
|
||||
for (const { a, b, r, emoji } of restas) {
|
||||
exercises.push({
|
||||
id: `num6-resta-${a}-${b}`,
|
||||
stage: 6,
|
||||
skillCode: 'resta',
|
||||
type: 'problema',
|
||||
prerequisites: a <= 5 ? ['num5-suma-visual-1-1'] : [`num6-resta-${a - 1}-${Math.max(1, b - 1)}` || 'num5-suma-10-1'],
|
||||
content: {
|
||||
instruction: `¿Cuánto es ${a} - ${b}?`,
|
||||
text: `${a} - ${b} = ?`,
|
||||
audioText: `${a} menos ${b}`,
|
||||
emoji,
|
||||
options: [
|
||||
...Array.from({ length: 4 }, (_, i) => r - 2 + i + (i >= 2 ? 2 : 0))
|
||||
.filter(j => j >= 0 && j <= 10 && j !== r)
|
||||
.slice(0, 2)
|
||||
.map(j => ({ label: String(j), correct: false, id: String(j) })),
|
||||
{ label: String(r), correct: true, id: String(r) },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
},
|
||||
functionalContext: 'Restar números pequeños.',
|
||||
errorType: 'discriminacion-auditiva',
|
||||
})
|
||||
}
|
||||
|
||||
// Visual subtraction: take away
|
||||
const visuales = [
|
||||
{ a: 3, b: 1, r: 2 },
|
||||
{ a: 4, b: 2, r: 2 },
|
||||
{ a: 5, b: 3, r: 2 },
|
||||
]
|
||||
for (const { a, b, r } of visuales) {
|
||||
exercises.push({
|
||||
id: `num6-resta-visual-${a}-${b}`,
|
||||
stage: 6,
|
||||
skillCode: 'resta-visual',
|
||||
type: 'conciencia',
|
||||
prerequisites: [`num6-resta-${a}-${b}`],
|
||||
content: {
|
||||
instruction: `${a} - ${b} = ? Sacamos ${b}`,
|
||||
text: `${'🟢'.repeat(a)}\nSacamos ${'🔴'.repeat(b)}\nQuedan...`,
|
||||
audioText: `Sacamos ${b}, quedan ${r}`,
|
||||
options: [
|
||||
{ label: '🟢'.repeat(r), correct: true, id: String(r) },
|
||||
{ label: '🟢'.repeat(r + 2), correct: false, id: String(r + 2) },
|
||||
{ label: '🟢'.repeat(Math.max(1, r + 1)), correct: false, id: String(r + 1) },
|
||||
],
|
||||
emoji: '➖',
|
||||
},
|
||||
functionalContext: 'Visualizar la resta como quitar elementos.',
|
||||
errorType: 'discriminacion-auditiva',
|
||||
})
|
||||
}
|
||||
|
||||
const stage: Stage = {
|
||||
id: 6,
|
||||
name: 'Restas simples (1-10)',
|
||||
description: 'Restar números del 1 al 10 con ayudas visuales.',
|
||||
exercises,
|
||||
}
|
||||
|
||||
export default stage
|
||||
@@ -0,0 +1,103 @@
|
||||
import type { Stage } from '../types'
|
||||
|
||||
const numeros2d = [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 30, 33, 40, 44, 50]
|
||||
|
||||
const exercises: any[] = []
|
||||
|
||||
for (const n of numeros2d) {
|
||||
const dec = Math.floor(n / 10)
|
||||
const uni = n % 10
|
||||
const decStr = '🔟'.repeat(dec)
|
||||
const uniStr = '●'.repeat(uni)
|
||||
|
||||
exercises.push({
|
||||
id: `num7-componer-${n}`,
|
||||
stage: 7,
|
||||
skillCode: 'valor-posicional',
|
||||
type: 'eleccion',
|
||||
prerequisites: n <= 15 ? ['num6-resta-visual-3-1'] : [`num7-componer-${numeros2d[numeros2d.indexOf(n) - 1]}`],
|
||||
content: {
|
||||
instruction: `${dec} decenas + ${uni} unidades = ?`,
|
||||
text: `${dec}×10 + ${uni}×1 = ?`,
|
||||
audioText: `${n}: ${dec} decenas y ${uni} unidades`,
|
||||
options: [
|
||||
...Array.from({ length: 4 }, (_, i) => n - 2 + i + (i >= 2 ? 2 : 0))
|
||||
.filter(j => j >= 10 && j <= 55 && j !== n)
|
||||
.slice(0, 2)
|
||||
.map(j => ({ label: String(j), correct: false, id: String(j) })),
|
||||
{ label: String(n), correct: true, id: String(n) },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
emoji: decStr,
|
||||
},
|
||||
functionalContext: 'Componer números de 2 dígitos en decenas y unidades.',
|
||||
errorType: 'confusion-letra',
|
||||
})
|
||||
}
|
||||
|
||||
// Write the number of tens and units
|
||||
for (const n of [15, 23, 30, 47, 50]) {
|
||||
const dec = Math.floor(n / 10)
|
||||
const uni = n % 10
|
||||
exercises.push({
|
||||
id: `num7-descomponer-${n}`,
|
||||
stage: 7,
|
||||
skillCode: 'valor-posicional',
|
||||
type: 'conciencia',
|
||||
prerequisites: [`num7-componer-${n}`],
|
||||
content: {
|
||||
instruction: `¿Cuántas decenas y unidades tiene ${n}?`,
|
||||
text: `${n} = ? decenas + ? unidades`,
|
||||
audioText: `${n} tiene ${dec} decenas y ${uni} unidades`,
|
||||
options: [
|
||||
{ label: `${dec} dec, ${uni} uni`, correct: true, id: `d${dec}u${uni}` },
|
||||
{ label: `${uni} dec, ${dec} uni`, correct: false, id: `d${uni}u${dec}` },
|
||||
{ label: `${dec + 1} dec, ${Math.max(0, uni - 1)} uni`, correct: false, id: `d${dec + 1}u${Math.max(0, uni - 1)}` },
|
||||
],
|
||||
emoji: '🔟',
|
||||
},
|
||||
functionalContext: 'Descomponer números en decenas y unidades.',
|
||||
errorType: 'inversion-letra',
|
||||
})
|
||||
}
|
||||
|
||||
// Compare 2-digit numbers
|
||||
const comparaciones = [
|
||||
{ a: 15, b: 20 },
|
||||
{ a: 23, b: 18 },
|
||||
{ a: 30, b: 25 },
|
||||
{ a: 42, b: 39 },
|
||||
{ a: 50, b: 49 },
|
||||
]
|
||||
|
||||
for (const { a, b } of comparaciones) {
|
||||
const mayor = a > b ? a : b
|
||||
const menor = a < b ? a : b
|
||||
exercises.push({
|
||||
id: `num7-comparar-${a}-${b}`,
|
||||
stage: 7,
|
||||
skillCode: 'comparacion-2d',
|
||||
type: 'eleccion',
|
||||
prerequisites: [`num7-descomponer-${mayor}`],
|
||||
content: {
|
||||
instruction: `¿Cuál número es más grande?`,
|
||||
text: `${a} vs ${b}`,
|
||||
audioText: `¿Cuál es más grande?`,
|
||||
options: [
|
||||
{ label: String(a), correct: a === mayor, id: String(a) },
|
||||
{ label: String(b), correct: b === mayor, id: String(b) },
|
||||
],
|
||||
emoji: '📏',
|
||||
},
|
||||
functionalContext: 'Comparar números de 2 dígitos.',
|
||||
errorType: 'confusion-letra',
|
||||
})
|
||||
}
|
||||
|
||||
const stage: Stage = {
|
||||
id: 7,
|
||||
name: 'Decenas y unidades',
|
||||
description: 'Componer y descomponer números de 2 dígitos en decenas y unidades. Comparar números.',
|
||||
exercises,
|
||||
}
|
||||
|
||||
export default stage
|
||||
@@ -0,0 +1,214 @@
|
||||
import type { Stage } from '../types'
|
||||
|
||||
const problemas = [
|
||||
{
|
||||
text: 'Tenés 2 manzanas. Mamá te da 1 más. ¿Cuántas manzanas tenés?',
|
||||
respuesta: 3,
|
||||
opciones: [2, 3, 4],
|
||||
emoji: '🍎',
|
||||
op: 'suma',
|
||||
},
|
||||
{
|
||||
text: 'Hay 3 pájaros en el árbol. 1 se va volando. ¿Cuántos quedan?',
|
||||
respuesta: 2,
|
||||
opciones: [1, 2, 4],
|
||||
emoji: '🐦',
|
||||
op: 'resta',
|
||||
},
|
||||
{
|
||||
text: 'Tenés 4 galletitas. Te comés 1. ¿Cuántas te quedan?',
|
||||
respuesta: 3,
|
||||
opciones: [2, 3, 5],
|
||||
emoji: '🍪',
|
||||
op: 'resta',
|
||||
},
|
||||
{
|
||||
text: 'En el patio hay 2 perros y 3 gatos. ¿Cuántos animales hay?',
|
||||
respuesta: 5,
|
||||
opciones: [3, 4, 5],
|
||||
emoji: '🐕',
|
||||
op: 'suma',
|
||||
},
|
||||
{
|
||||
text: 'Tenés 5 lápices. Tu amiga te presta 2 más. ¿Cuántos lápices tenés ahora?',
|
||||
respuesta: 7,
|
||||
opciones: [5, 7, 8],
|
||||
emoji: '✏️',
|
||||
op: 'suma',
|
||||
},
|
||||
{
|
||||
text: 'Hay 6 flores en el jardín. Cortás 2 para mamá. ¿Cuántas quedan?',
|
||||
respuesta: 4,
|
||||
opciones: [3, 4, 8],
|
||||
emoji: '🌸',
|
||||
op: 'resta',
|
||||
},
|
||||
{
|
||||
text: 'En la mesa hay 3 platos y 3 vasos. ¿Cuántas cosas hay?',
|
||||
respuesta: 6,
|
||||
opciones: [5, 6, 9],
|
||||
emoji: '🍽️',
|
||||
op: 'suma',
|
||||
},
|
||||
{
|
||||
text: 'Tenés 7 stickers. Le das 2 a tu hermana. ¿Cuántos te quedan?',
|
||||
respuesta: 5,
|
||||
opciones: [4, 5, 9],
|
||||
emoji: '⭐',
|
||||
op: 'resta',
|
||||
},
|
||||
{
|
||||
text: 'Compraste 8 globos. 3 se explotan. ¿Cuántos globos quedan?',
|
||||
respuesta: 5,
|
||||
opciones: [3, 5, 11],
|
||||
emoji: '🎈',
|
||||
op: 'resta',
|
||||
},
|
||||
{
|
||||
text: 'En la pecera hay 4 peces naranjas y 2 azules. ¿Cuántos peces hay?',
|
||||
respuesta: 6,
|
||||
opciones: [4, 6, 8],
|
||||
emoji: '🐠',
|
||||
op: 'suma',
|
||||
},
|
||||
{
|
||||
text: 'Tenés 9 bloques. Usás 4 para hacer una torre. ¿Cuántos sobran?',
|
||||
respuesta: 5,
|
||||
opciones: [4, 5, 13],
|
||||
emoji: '🧱',
|
||||
op: 'resta',
|
||||
},
|
||||
{
|
||||
text: 'En tu plato hay 5 frutillas y 3 uvas. ¿Cuántas frutas tenés?',
|
||||
respuesta: 8,
|
||||
opciones: [5, 8, 15],
|
||||
emoji: '🍓',
|
||||
op: 'suma',
|
||||
},
|
||||
{
|
||||
text: 'Hay 10 libros en el estante. Sacás 4 para leer. ¿Cuántos quedan?',
|
||||
respuesta: 6,
|
||||
opciones: [4, 6, 14],
|
||||
emoji: '📚',
|
||||
op: 'resta',
|
||||
},
|
||||
{
|
||||
text: 'Tenés 2 manos. Cada mano tiene 5 dedos. ¿Cuántos dedos tenés en total?',
|
||||
respuesta: 10,
|
||||
opciones: [5, 7, 10],
|
||||
emoji: '🖐️',
|
||||
op: 'suma',
|
||||
},
|
||||
{
|
||||
text: 'Compartís 6 caramelos con tu amiga. Le das la mitad. ¿Cuántos te quedan?',
|
||||
respuesta: 3,
|
||||
opciones: [2, 3, 6],
|
||||
emoji: '🍬',
|
||||
op: 'resta',
|
||||
},
|
||||
{
|
||||
text: 'Hay 7 días en la semana. Ya pasaron 3. ¿Cuántos días quedan?',
|
||||
respuesta: 4,
|
||||
opciones: [3, 4, 10],
|
||||
emoji: '📅',
|
||||
op: 'resta',
|
||||
},
|
||||
{
|
||||
text: 'Viste 3 mariquitas en una hoja y 2 en otra. ¿Cuántas viste?',
|
||||
respuesta: 5,
|
||||
opciones: [3, 5, 6],
|
||||
emoji: '🐞',
|
||||
op: 'suma',
|
||||
},
|
||||
{
|
||||
text: 'Tenés 4 monedas. Encontrás 3 más en tu bolsillo. ¿Cuántas tenés?',
|
||||
respuesta: 7,
|
||||
opciones: [4, 7, 12],
|
||||
emoji: '🪙',
|
||||
op: 'suma',
|
||||
},
|
||||
{
|
||||
text: 'Son las 3 de la tarde. Pasaron 2 horas. ¿Qué hora es?',
|
||||
respuesta: 5,
|
||||
opciones: [1, 5, 6],
|
||||
emoji: '🕐',
|
||||
op: 'suma',
|
||||
},
|
||||
{
|
||||
text: 'El nene tiene 8 años. La nena tiene 3 años menos. ¿Cuántos años tiene la nena?',
|
||||
respuesta: 5,
|
||||
opciones: [3, 5, 11],
|
||||
emoji: '👶',
|
||||
op: 'resta',
|
||||
},
|
||||
{
|
||||
text: 'En la granja hay 2 caballos, 3 vacas y 1 cerdo. ¿Cuántos animales?',
|
||||
respuesta: 6,
|
||||
opciones: [4, 6, 7],
|
||||
emoji: '🐴',
|
||||
op: 'suma',
|
||||
},
|
||||
{
|
||||
text: 'Papá horneó 12 galletitas. Te comiste 2. ¿Cuántas quedan?',
|
||||
respuesta: 10,
|
||||
opciones: [8, 10, 14],
|
||||
emoji: '🍪',
|
||||
op: 'resta',
|
||||
},
|
||||
{
|
||||
text: 'Un tren tiene 4 vagones rojos y 4 azules. ¿Cuántos vagones tiene?',
|
||||
respuesta: 8,
|
||||
opciones: [4, 8, 16],
|
||||
emoji: '🚂',
|
||||
op: 'suma',
|
||||
},
|
||||
{
|
||||
text: 'Tenés 5 años. Cuando cumplas 5 más, ¿cuántos vas a tener?',
|
||||
respuesta: 10,
|
||||
opciones: [5, 10, 15],
|
||||
emoji: '🎂',
|
||||
op: 'suma',
|
||||
},
|
||||
{
|
||||
text: 'El árbol tiene 10 manzanas. Caen 3. ¿Cuántas manzanas quedan en el árbol?',
|
||||
respuesta: 7,
|
||||
opciones: [3, 7, 13],
|
||||
emoji: '🍎',
|
||||
op: 'resta',
|
||||
},
|
||||
]
|
||||
|
||||
const exercises: any[] = []
|
||||
|
||||
for (let i = 0; i < problemas.length; i++) {
|
||||
const p = problemas[i]
|
||||
exercises.push({
|
||||
id: `num8-problema-${i + 1}`,
|
||||
stage: 8,
|
||||
skillCode: 'problemas-cotidianos',
|
||||
type: 'problema',
|
||||
prerequisites: i === 0 ? ['num7-comparar-15-20'] : [`num8-problema-${i}`],
|
||||
content: {
|
||||
instruction: 'Escuchá bien el problema',
|
||||
text: p.text,
|
||||
audioText: p.text,
|
||||
emoji: p.emoji,
|
||||
options: p.opciones.map(o => ({
|
||||
label: String(o),
|
||||
correct: o === p.respuesta,
|
||||
id: String(o),
|
||||
})).sort(() => Math.random() - 0.5),
|
||||
},
|
||||
functionalContext: 'Resolver problemas matemáticos de la vida cotidiana.',
|
||||
errorType: p.op === 'resta' ? 'inversion-letra' : 'discriminacion-auditiva',
|
||||
})
|
||||
}
|
||||
|
||||
const stage: Stage = {
|
||||
id: 8,
|
||||
name: 'Problemas de la vida cotidiana',
|
||||
description: 'Resolver problemas cotidianos que requieren sumar y restar números hasta 12.',
|
||||
exercises,
|
||||
}
|
||||
|
||||
export default stage
|
||||
Reference in New Issue
Block a user