珠心算画盘
// 文档加载完成后执行的函数,用于初始化页面上的事件监听器和逻辑处理。
$(document).ready(function () {
//校验位数和笔数输入框的值不能超过最大值
$('#digits').on('input', function() {
var max = parseInt($(this).attr('max'), 10);
var value = parseInt($(this).val(), 10);
if (value > max) {
$(this).val(max);
}
});
// Ensure penCount does not exceed max value
$('#penCount').on('input', function() {
var max = parseInt($(this).attr('max'), 10);
var value = parseInt($(this).val(), 10);
if (value > max) {
$(this).val(max);
}
});
// 确保在页面加载时容器是显示的
$('#penCountContainer').show();
$('#displayModeContainer').show();
// 监听操作选择框的变化,根据所选操作显示或隐藏笔数和显示方式的设置。
$('#operation').change(function () {
let operation = $(this).val();
if (operation === 'multiply' || operation === 'divide') {
$('#penCountContainer').hide(); // 如果是乘法或除法,隐藏笔数选择
$('#displayModeContainer').hide(); // 如果是乘法或除法,隐藏显示方式选择
} else {
$('#penCountContainer').show(); // 其他操作显示笔数选择
$('#displayModeContainer').show(); // 其他操作显示显示方式选择
}
}).trigger('change'); // 触发一次change事件以初始化显示状态
// 开始训练按钮点击事件,收集用户设置并启动训练流程。
$('#start').click(function () {
//校验
var digits = parseInt($('#digits').val(), 10);
var penCount = parseInt($('#penCount').val(), 10);
// Validate digits
if (digits < 1 || digits > 5) {
alert('位数必须在1到5之间');
return;
}
// Validate penCount
if (penCount < 1 || penCount > 10) {
alert('笔数必须在1到10之间');
return;
}
var displayMode = null;
var operation = $('#operation').val();
var digits = parseInt($('#digits').val());
var penCount = parseInt($('#penCount').val());
if (operation === 'multiply' || operation === 'divide') {
displayMode = 'all';
} else {
displayMode = $('#displayMode').val();
}
var frequency = parseInt($('#frequency').val());
startTraining(operation, digits, penCount, displayMode, frequency);
});
// 提交答案按钮点击事件,验证用户输入的答案是否正确。
$('#submit').click(function () {
var userAnswer = $('#answer').val();
checkAnswer(userAnswer);
});
});
// 初始化全局变量,用于存储当前练习、开始时间以及算盘对象。
var currentExercise = null;
var startTime = null;
var abacus = null;
// 启动训练过程,根据用户设置生成练习题目、清空训练区域、初始化算盘并开始显示练习。
function startTraining(operation, digits, penCount, displayMode, frequency) {
$('#exerciseArea').empty();
$('#resultText').empty();
$('#answer').val('');
currentExercise = generateExercise(operation, digits, penCount);
console.log('digits', digits);
abacus = new Calculate('abacusCanvas', { number_of_bars: 10 });
displayExercise(currentExercise, displayMode, frequency, operation);
startTime = new Date().getTime();
}
// 生成练习题目,根据操作类型(加、减、乘、除、加减混合)和位数生成随机数序列和计算结果。
function generateExercise(operation, digits, penCount) {
var numbers = [];
var result = 0;
if (operation === 'subtract' || operation === 'addSubtract') {
// Start with a random initial positive number for subtract operations
result = Math.floor(Math.random() * Math.pow(10, digits));
numbers.push(result);
for (var i = 1; i < penCount; i++) {
var number = Math.floor(Math.random() * Math.pow(10, digits));
if (operation === 'subtract' || (operation === 'addSubtract' && Math.random() > 0.5)) {
number = Math.min(result, number);
numbers.push(-number);
result -= number;
} else {
numbers.push(number);
result += number;
}
}
} else if (operation === 'divide') {
result = generateInitialDivisibleNumber(digits);
numbers.push(result);
console.log("divide start");
for (var i = 1; i < penCount; i++) {
var number = generateDivisibleNumber(result, digits);
numbers.push(number);
result = Math.floor(result / number);
}
console.log("divide end");
} else {
for (var i = 0; i < penCount; i++) {
var number = Math.floor(Math.random() * Math.pow(10, digits));
if (operation === 'add') {
numbers.push(number);
result += number;
} else if (operation === 'multiply') {
if (i === 0) {
result = number;
} else {
result *= number;
}
numbers.push(number);
}
}
}
return { numbers: numbers, result: result };
}
// 生成一个初始的可整除的随机数
function generateInitialDivisibleNumber(digits) {
return Math.floor(Math.random() * (Math.pow(10, digits) - 2)) + 2;
}
// 获取一个数字的所有因数
function getFactors(number) {
const factors = [];
for (let i = 2; i <= number; i++) {
if (number % i === 0) {
factors.push(i);
}
}
return factors;
}
// 生成一个能够整除当前结果的随机数,并且结果大于1
function generateDivisibleNumber(currentResult, digits) {
const factors = getFactors(currentResult);
console.log("Factors of", currentResult, ":", factors);
if (factors.length === 0) {
return 1; // 如果没有找到因数,则返回1,确保不会返回undefined
}
let number;
do {
number = factors[Math.floor(Math.random() * factors.length)];
} while (number >= Math.pow(10, digits));
return number;
}
// 显示练习题目,根据用户选择的显示方式进行不同类型的展示。
function displayExercise(exercise, displayMode, frequency, operation) {
if (displayMode === 'all') {
$('#exerciseArea').text(exercise.numbers.join(' '));
updateAbacus(exercise.numbers, exercise.result, operation);
} else if ((operation === 'add' || operation === 'subtract' || operation === 'addSubtract') && displayMode === 'sequential') {
displaySequential(exercise.numbers, 0, frequency);
} else if ((operation === 'add' || operation === 'subtract' || operation === 'addSubtract') && displayMode === 'random') {
displayRandom(exercise.numbers, 0, frequency);
} else {
$('#exerciseArea').text(exercise.numbers.join(' '));
updateAbacus(exercise.numbers, exercise.result, displayMode);
}
}
// 顺序显示数字,按顺序将数字逐个显示在训练区域。
function displaySequential(numbers, index, frequency) {
if (index >= numbers.length) return;
$('#exerciseArea').text(numbers[index]);
abacus.setUpNumber(numbers.slice(0, index + 1).reduce((a, b) => a + b, 0));
setTimeout(function () {
displaySequential(numbers, index + 1, frequency);
}, frequency);
}
// 随机位置显示数字,每次在训练区域随机位置显示下一个数字。
function displayRandom(numbers, index, frequency) {
if (index >= numbers.length) return;
var randomX = Math.floor(Math.random() * ($('#exerciseArea').width() - 50));
var randomY = Math.floor(Math.random() * ($('#exerciseArea').height() - 50));
$('#exerciseArea').css({ position: 'relative' });
$('#exerciseArea').html('<div style="position:absolute; left:' + randomX + 'px; top:' + randomY + 'px;">' + numbers[index] + '</div>');
abacus.setUpNumber(numbers.slice(0, index + 1).reduce((a, b) => a + b, 0));
setTimeout(function () {
displayRandom(numbers, index + 1, frequency);
}, frequency);
}
// 更新算盘显示,根据数字序列设置算盘的显示状态。
function updateAbacus(numbers, result, operation) {
console.log("number:", numbers, "; result:", result, "; displayMode:", operation);
let computedResult;
if (operation === 'multiply') {
// 初始值设置为1,因为乘法以1为初始值才有效
computedResult = numbers.reduce((a, b) => a * b, 1);
} else if (operation === 'divide') {
// 初始值设置为数组的第一个元素,并从第二个元素开始进行除法运算
computedResult = numbers.slice(1).reduce((a, b) => a / b, numbers[0]);
} else if (operation === 'subtract') {
// 初始值设置为数组的第一个元素,并从第二个元素开始进行减法运算
computedResult = numbers.slice(1).reduce((a, b) => a + b, numbers[0]);
} else {
// 默认是加法,初始值设置为0
computedResult = numbers.reduce((a, b) => a + b, 0);
}
abacus.setUpNumber(computedResult);
console.log("computed result:", computedResult);
}
运行js代码
// 检查用户提交的答案是否正确,并显示结果信息。
function checkAnswer(userAnswer) {
var endTime = new Date().getTime();
var timeTaken = (endTime - startTime) / 1000;
if (parseInt(userAnswer) === currentExercise.result) {
$('#resultText').text('正确! 用时: ' + timeTaken + '秒');
} else {
$('#resultText').text('错误! 正确答案是: ' + currentExercise.result);
}
}
点击事件
// 文档加载完成后执行的函数,用于初始化页面上的事件监听器和逻辑处理。
$(document).ready(function () {
//校验位数和笔数输入框的值不能超过最大值
$('#digits').on('input', function() {
var max = parseInt($(this).attr('max'), 10);
var value = parseInt($(this).val(), 10);
if (value > max) {
$(this).val(max);
}
});
// Ensure penCount does not exceed max value
$('#penCount').on('input', function() {
var max = parseInt($(this).attr('max'), 10);
var value = parseInt($(this).val(), 10);
if (value > max) {
$(this).val(max);
}
});
// 确保在页面加载时容器是显示的
$('#penCountContainer').show();
$('#displayModeContainer').show();
// 监听操作选择框的变化,根据所选操作显示或隐藏笔数和显示方式的设置。
$('#operation').change(function () {
let operation = $(this).val();
if (operation === 'multiply' || operation === 'divide') {
$('#penCountContainer').hide(); // 如果是乘法或除法,隐藏笔数选择
$('#displayModeContainer').hide(); // 如果是乘法或除法,隐藏显示方式选择
} else {
$('#penCountContainer').show(); // 其他操作显示笔数选择
$('#displayModeContainer').show(); // 其他操作显示显示方式选择
}
}).trigger('change'); // 触发一次change事件以初始化显示状态
// 开始训练按钮点击事件,收集用户设置并启动训练流程。
$('#start').click(function () {
//校验
var digits = parseInt($('#digits').val(), 10);
var penCount = parseInt($('#penCount').val(), 10);
// Validate digits
if (digits < 1 || digits > 5) {
alert('位数必须在1到5之间');
return;
}
// Validate penCount
if (penCount < 1 || penCount > 10) {
alert('笔数必须在1到10之间');
return;
}
var displayMode = null;
var operation = $('#operation').val();
var digits = parseInt($('#digits').val());
var penCount = parseInt($('#penCount').val());
if (operation === 'multiply' || operation === 'divide') {
displayMode = 'all';
} else {
displayMode = $('#displayMode').val();
}
var frequency = parseInt($('#frequency').val());
startTraining(operation, digits, penCount, displayMode, frequency);
});
// 提交答案按钮点击事件,验证用户输入的答案是否正确。
$('#submit').click(function () {
var userAnswer = $('#answer').val();
checkAnswer(userAnswer);
});
});
// 初始化全局变量,用于存储当前练习、开始时间以及算盘对象。
var currentExercise = null;
var startTime = null;
var abacus = null;
// 启动训练过程,根据用户设置生成练习题目、清空训练区域、初始化算盘并开始显示练习。
function startTraining(operation, digits, penCount, displayMode, frequency) {
$('#exerciseArea').empty();
$('#resultText').empty();
$('#answer').val('');
currentExercise = generateExercise(operation, digits, penCount);
console.log('digits', digits);
abacus = new Calculate('abacusCanvas', { number_of_bars: 10 });
displayExercise(currentExercise, displayMode, frequency, operation);
startTime = new Date().getTime();
}
// 生成练习题目,根据操作类型(加、减、乘、除、加减混合)和位数生成随机数序列和计算结果。
function generateExercise(operation, digits, penCount) {
var numbers = [];
var result = 0;
if (operation === 'subtract' || operation === 'addSubtract') {
// Start with a random initial positive number for subtract operations
result = Math.floor(Math.random() * Math.pow(10, digits));
numbers.push(result);
for (var i = 1; i < penCount; i++) {
var number = Math.floor(Math.random() * Math.pow(10, digits));
if (operation === 'subtract' || (operation === 'addSubtract' && Math.random() > 0.5)) {
number = Math.min(result, number);
numbers.push(-number);
result -= number;
} else {
numbers.push(number);
result += number;
}
}
} else if (operation === 'divide') {
result = generateInitialDivisibleNumber(digits);
numbers.push(result);
console.log("divide start");
for (var i = 1; i < penCount; i++) {
var number = generateDivisibleNumber(result, digits);
numbers.push(number);
result = Math.floor(result / number);
}
console.log("divide end");
} else {
for (var i = 0; i < penCount; i++) {
var number = Math.floor(Math.random() * Math.pow(10, digits));
if (operation === 'add') {
numbers.push(number);
result += number;
} else if (operation === 'multiply') {
if (i === 0) {
result = number;
} else {
result *= number;
}
numbers.push(number);
}
}
}
return { numbers: numbers, result: result };
}
// 生成一个初始的可整除的随机数
function generateInitialDivisibleNumber(digits) {
return Math.floor(Math.random() * (Math.pow(10, digits) - 2)) + 2;
}
// 获取一个数字的所有因数
function getFactors(number) {
const factors = [];
for (let i = 2; i <= number; i++) {
if (number % i === 0) {
factors.push(i);
}
}
return factors;
}
// 生成一个能够整除当前结果的随机数,并且结果大于1
function generateDivisibleNumber(currentResult, digits) {
const factors = getFactors(currentResult);
console.log("Factors of", currentResult, ":", factors);
if (factors.length === 0) {
return 1; // 如果没有找到因数,则返回1,确保不会返回undefined
}
let number;
do {
number = factors[Math.floor(Math.random() * factors.length)];
} while (number >= Math.pow(10, digits));
return number;
}
// 显示练习题目,根据用户选择的显示方式进行不同类型的展示。
function displayExercise(exercise, displayMode, frequency, operation) {
if (displayMode === 'all') {
$('#exerciseArea').text(exercise.numbers.join(' '));
updateAbacus(exercise.numbers, exercise.result, operation);
} else if ((operation === 'add' || operation === 'subtract' || operation === 'addSubtract') && displayMode === 'sequential') {
displaySequential(exercise.numbers, 0, frequency);
} else if ((operation === 'add' || operation === 'subtract' || operation === 'addSubtract') && displayMode === 'random') {
displayRandom(exercise.numbers, 0, frequency);
} else {
$('#exerciseArea').text(exercise.numbers.join(' '));
updateAbacus(exercise.numbers, exercise.result, displayMode);
}
}
// 顺序显示数字,按顺序将数字逐个显示在训练区域。
function displaySequential(numbers, index, frequency) {
if (index >= numbers.length) return;
$('#exerciseArea').text(numbers[index]);
abacus.setUpNumber(numbers.slice(0, index + 1).reduce((a, b) => a + b, 0));
setTimeout(function () {
displaySequential(numbers, index + 1, frequency);
}, frequency);
}
// 随机位置显示数字,每次在训练区域随机位置显示下一个数字。
function displayRandom(numbers, index, frequency) {
if (index >= numbers.length) return;
var randomX = Math.floor(Math.random() * ($('#exerciseArea').width() - 50));
var randomY = Math.floor(Math.random() * ($('#exerciseArea').height() - 50));
$('#exerciseArea').css({ position: 'relative' });
$('#exerciseArea').html('<div style="position:absolute; left:' + randomX + 'px; top:' + randomY + 'px;">' + numbers[index] + '</div>');
abacus.setUpNumber(numbers.slice(0, index + 1).reduce((a, b) => a + b, 0));
setTimeout(function () {
displayRandom(numbers, index + 1, frequency);
}, frequency);
}
// 更新算盘显示,根据数字序列设置算盘的显示状态。
function updateAbacus(numbers, result, operation) {
console.log("number:", numbers, "; result:", result, "; displayMode:", operation);
let computedResult;
if (operation === 'multiply') {
// 初始值设置为1,因为乘法以1为初始值才有效
computedResult = numbers.reduce((a, b) => a * b, 1);
} else if (operation === 'divide') {
// 初始值设置为数组的第一个元素,并从第二个元素开始进行除法运算
computedResult = numbers.slice(1).reduce((a, b) => a / b, numbers[0]);
} else if (operation === 'subtract') {
// 初始值设置为数组的第一个元素,并从第二个元素开始进行减法运算
computedResult = numbers.slice(1).reduce((a, b) => a + b, numbers[0]);
} else {
// 默认是加法,初始值设置为0
computedResult = numbers.reduce((a, b) => a + b, 0);
}
abacus.setUpNumber(computedResult);
console.log("computed result:", computedResult);
}
// 检查用户提交的答案是否正确,并显示结果信息。
function checkAnswer(userAnswer) {
var endTime = new Date().getTime();
var timeTaken = (endTime - startTime) / 1000;
if (parseInt(userAnswer) === currentExercise.result) {
$('#resultText').text('正确! 用时: ' + timeTaken + '秒');
} else {
$('#resultText').text('错误! 正确答案是: ' + currentExercise.result);
}
}