/// Note: Since txTick() takes a significant amount of time, the /// fastest the metronome will currently go is 240 bpm. void txMetronome(MorseToken) { uint8_t bpm(60); switch (symbolStackSize()) { case 3: bpm = 100 * s(2).m2i() + 10 * s(1).m2i() + s(0).m2i(); popN(3); break; case 2: bpm = 10 * s(1).m2i() + s(0).m2i(); popN(2); break; case 1: bpm = s(0).m2i(); popN(1); break; default: txError(); } uint32_t timeout(60 * 1000000 / bpm); elapsedMicros sinceTick(0); while (!touchPoll(dahPin)) { if (timeout < sinceTick) { sinceTick = 0; txTick(MorseToken()); } } }
void txAlfaBravoCharlie(MorseToken code) { // uint8_t n(m2a(code) - 'A'); uint8_t n(0); if (1 < symbolStackSize()) { n = 10 * s(1).m2i() + s(0).m2i(); popN(2); } else if (symbolStackSize()) { n = m2i(s(0)); popN(1); } if (0 <= n && n <= ('Z' - 'A')) { char letterName[1 + sizeof "NOVEMBER"]; const char* p(alphaBravoCharlie); size_t i(0); while (*p) { if (*p == ' ') { if (n) { --n; } else { break; } } else if (!n) { letterName[i++] = *p; } ++p; } letterName[i] = '\000'; txString(letterName); } else { txError(); Serial.println("txAlfaBravoCharlie: Range error."); } }
static void applySTRICT(void) { push(getN(2)); eval(); popN(1); push(newcell(APPLY)); top()->left = getN(2); top()->right = getN(3); }
/// The top three entries on the stack are two digits to add and their /// proported sum mod 10. Transmit Y/N to indicate whether or not the /// sum is correct. If the sum is not correct, transmit the correct /// sum. Update the weights to bias future random number selection. void gradeSum(MorseToken) { if (2 < symbolStackSize()) { uint8_t s1(s(1).m2i()); uint8_t s2(s(2).m2i()); uint8_t s0(s(0).toChar()); uint8_t sum((s1 + s2) % 10); Serial.print(s2); Serial.print(" "); Serial.print(s1); Serial.print(" "); Serial.print(s0); Serial.print(" sum: "); Serial.println(sum); bool correct(s(0).m2i() == sum); if (correct) { txString("Y"); // Decrease the error counts associated with the digits the user // just added incorrectly, taking care not to underflow. uint8_t d1(!!digitErr[s1]); uint8_t d2(!!digitErr[s2]); digitErr[s1] -= d1; digitErr[s2] -= d2; digitErrCount -= (d1 + d2); Serial.print("Decrementing "); Serial.print(s1); Serial.print(". New weight is: "); Serial.println(digitErr[s1]); Serial.print("Decrementing "); Serial.print(s2); Serial.print(". New weight is: "); Serial.println(digitErr[s2]); } else { // 012345678901 char buffer[] = "N a + b = c"; buffer[3] = s2 + '0'; buffer[7] = s1 + '0'; buffer[11] = sum + '0'; txString(buffer); // Increase the error counts associated with the digits the user // just added incorrectly, taking care not to overflow. uint8_t d1(3 * (digitErr[s1] - 3 < 255)); uint8_t d2(3 * (digitErr[s2] - 3 < 255)); digitErr[s1] += d1; digitErr[s2] += d2; digitErrCount += d1 + d2; Serial.print("Incrementing "); Serial.print(s1); Serial.print(". New weight is: "); Serial.println(digitErr[s1]); Serial.print("Incrementing "); Serial.print(s2); Serial.print(". New weight is: "); Serial.println(digitErr[s2]); } // If the user plays long enough without a reset to saturate two // of the digits chosen at random, divide all the error counts // by 2. if (digitErr[s1] == 255 && digitErr[s2] == 255) { for (uint8_t i(0); i < 10; ++i) { digitErr[i] <<= 1; } digitErrCount <<= 1; Serial.println("Halving all weights."); } Serial.print("Digit error count is: "); Serial.println(digitErrCount); popN(3); } else { txError(); } }
void slide(int n) { Cell *temp = pop(); popN(n); push(temp); }