Atom Square
About
A magic square is a grid of numbers arranged such that the sum of the numbers in each row, column, and diagonal is the same.
As a magician, you can use a magic square for mentalism or as a mathematical magic trick. Ask a spectator to choose any number between 22 and 117, and then reveal the sum of the numbers in any row, column, or diagonal that contains that number.
This mini-app helps you create a magic square based on a chosen number. Simply enter the number provided by the spectator, and copy the resulting numbers displayed on the PeekSmith 3 screen.
// the number
let num = '';
// the array will contain the numbers of the 4x4 square
let square = newUint8Array(16);
function main() {
ps.connect();
}
function formatNumber(n) {
if (n < 10) return `\xA0${n}`;
return `${n}`;
}
function buildSquare(n) {
// we can calculate a magic square for numbers
// between 22 and 117 when we would like to end with
// max. two digit positive numbers
if (n < 22 || n > 117) {
ps.print(`${n}\nINVALID`);
return;
}
let correction = (n - 22) / 6 | 0;
if (n > 25) correction += rand(2);
square[0] = 7 + correction;
square[1] = 12 + correction;
square[2] = 1 + correction;
square[3] = n - 20 - correction * 3;
square[4] = 2 + correction;
square[5] = n - 21 - correction * 3;
square[6] = 8 + correction;
square[7] = 11 + correction;
square[8] = n - 18 - correction * 3;
square[9] = 3 + correction;
square[10] = 10 + correction;
square[11] = 5 + correction;
square[12] = 9 + correction;
square[13] = 6 + correction;
square[14] = n - 19 - correction * 3;
square[15] = 4 + correction;
let vFlipped = rand(0, 2);
let rotated = rand(0, 2);
let startRow = vFlipped === 1 ? 3 : 0;
let endRow = vFlipped === 1 ? -1 : 4;
let step = vFlipped === 1 ? -1 : 1;
let result = '';
for (let row = startRow; row !== endRow; row += step) {
for (let col = 0; col < 4; col++) {
if (rotated === 0) {
result += formatNumber(square[row * 4 + col]);
} else { // col <==> row
result += formatNumber(square[col * 4 + row]);
}
result += col < 3 ? ' ' : '\n';
}
}
ps.print(result);
}
let layout = [
'1', '2', '3',
'4', '5', '6',
'7', '8', '9',
's', '0', '<'
];
function calc() {
if (num === '') return;
clearTimeout(timer);
buildSquare(parseInt(num));
num = '';
}
let timer;
function onButtonClick(buttonId) {
let key = layout[buttonId];
switch (key) {
case 's':
calc();
return;
case '<':
num = strSub(num, 0, -1);
break;
default:
if (strLen(num) < 3) num += key;
break;
}
clearTimeout(timer);
const processAfter = config.get('keyboard.submit.after');
if (processAfter > 0) timer = setTimeout(() => {
calc();
}, processAfter);
printNumberEntered();
}
function printNumberEntered() {
let rest = '';
for (let i = strLen(num); i < 3; i++) {
rest += '_';
}
let text = `${num}${rest}\n`;
ps.print(text);
}
function onEvent(e) {
if (e.source === 'ps:ble' && e.type === 'connected') {
ps.print('Atom\nSquare');
setTimeout(printNumberEntered, 2000);
return;
}
if (e.source === 'atom:button') {
const buttonId = parseInt(e.value);
if (e.type === 'click') {
onButtonClick(buttonId);
}
if (strSub(e.type, 0, 5) === 'click' && strLen(e.type) === 6) {
const clickCount = parseInt(strCharAt(e.type, 5));
for (let i = 0; i < clickCount; i++) {
onButtonClick(buttonId);
}
}
}
}
General
πΒ First Steps
MagiScript Editor
πΒ Basics
πΒ Running Your First Program
πΒ App Store
πΒ Atom Settings (Editor)
πΒ Debugging Techniques
Examples
πΒ Atom Time
ποΈ Time Practice
πΒ Atom Pi (Pi Revelations)
πΒ Atom Drum
ποΈ Atom Stack
πΒ Atom Square
πΒ Atom Level
πΒ Atom THMPR
πΒ Poker Hands
πΒ Keyboard Numeric
πΒ Keyboard NOKIA
πΒ Keyboard Cursor
πΒ Keyboard Media
πΒ Keyboard Custom
Input/Output
πΒ Buttons
πΒ Vibration Motor
πΒ RGB LED
πΒ Devices
πΒ PeekSmith
πΒ SB Watch
πΒ Bluetooth Keyboard
πΒ Bluetooth Mouse
πΒ Timers
πΒ Database
πΒ Events
πΒ System (exit, sleep, rand)
πΒ Objects (card, time)
Language
πΒ Summary
πΒ Comments
πΒ Variable Declarations
πΒ Operators
πΒ Control Flow
πΒ Functions
πΒ Numbers
πΒ Strings
πΒ Arrays
πΒ Objects
πΒ Uint8Array