Skip to content

Instantly share code, notes, and snippets.

@notcallumfisher
Created December 3, 2025 19:10
Show Gist options
  • Select an option

  • Save notcallumfisher/66fcb8ca3fa59241fb0fb4c74064b9dd to your computer and use it in GitHub Desktop.

Select an option

Save notcallumfisher/66fcb8ca3fa59241fb0fb4c74064b9dd to your computer and use it in GitHub Desktop.
Math Opponent for Multiplayer Piano
/*
callum fisher
2018.07.25 - 2024.12.06
Published for archival purposes.
Made to work against Math Teacher for Multiplayer Piano.
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <https://unlicense.org>
*/
//Math Opponent:
//variables
var a = true; // on or off
var time = 8000 // default minimum response time in ms
var learn = false; // learn
var lvl = 0; // bot level
var learnaccuracy = 0 // learning mode level
var impossiblemsg = true; // message that displays when bot is op
var gamerunning = false; // whether or not a math game is active
var bot_ID = "" //Math bot _id
//functions:
function defaultname(){
MPP.client.sendArray([{
m: "userset",
set: {
"name": "MathBot [say \"mathbot\" for more]"
}
}]);
}
function lvlUp(){
lvl=lvl+0.5
console.log('lvl up: '+lvl);
MPP.client.sendArray([{
m: "userset",
set: {
"name": "MathBot [LEVEL UP ^^]: "+lvl
}
}]);
setTimeout(function(){
defaultname();
}, 2000);
}
function lvlDown(){
lvl=lvl-0.5
console.log('lvl down: '+lvl);
MPP.client.sendArray([{
m: "userset",
set: {
"name": "MathBot [LEVEL DOWN vv]: "+lvl
}
}]);
setTimeout(function(){
defaultname();
}, 2000);
}
function reset(){
time=8000;
lvl=0;
learnaccuracy=0;
impossiblemsg=true;
MPP.chat.send('My statistics were reset!');
}
function toggle(){
if(a){
a=false;
MPP.chat.send('I won\'t answer any math questions now! (Disabled)');
} else {
a=true;
MPP.chat.send('I will play the /math game now! (Enabled)');
}
}
function display_help(){
MPP.chat.send('MathBot commands 1:');
setTimeout(function(){
MPP.chat.send('Say "mathbot reset" to reset me.');
MPP.chat.send('Say "mathbot 2" for more.');
}, 2000);
}
function display_help2(){
MPP.chat.send('MathBot commands 2:');
setTimeout(function(){
MPP.chat.send('Say "mathbot toggle" to turn me on or off.');
MPP.chat.send('Say "mathbot stats" to see my statistics.');
}, 2000);
}
function display_statistics(){
MPP.chat.send('[🕒] Time to calculate: '+Math.floor((time/1000) % 60)+'s'+' || [-->-|] Accuracy Points: '+learnaccuracy+' || [^v] Level: '+lvl+'');
}
function display_welcome(){
MPP.chat.send('Hi, I\'m MathBot, I\'m an opponent for the /math command. Beat my scores!');
MPP.chat.send('Say "mathbot" for more.');
}
//setup:
display_welcome();
defaultname();
//Listen for messages:
MPP.client.on("a",function(msg){
//reset command:
if(msg.a.toLowerCase().startsWith('mathbot reset')){
reset();
}
//toggle command:
if(msg.a.toLowerCase().startsWith('mathbot toggle')){
toggle();
}
//default response:
if(msg.a.toLowerCase()=='mathbot'){
display_help();
}
//default response2
if(msg.a.toLowerCase()=='mathbot 2'){
display_help2();
}
//stats command:
if(msg.a.toLowerCase()=='mathbot stats'){
display_statistics();
}
//time up:
if(a){
if(msg.a.startsWith('It\'s been a minute! Math game is over, the anwser was')){
gamerunning=false;
setTimeout(function(){
//become more of a challenge
MPP.chat.send('Oh no. Level down. I won\'t be beaten now!');
time=3000;
if(learn){
learnaccuracy--;
console.log('got worse');
}
lvlDown();
setTimeout(function(){
if(!gamerunning){
MPP.chat.send('.math');
}
}, 800);
}, 800);
}
}
//only process the message if it's the bot sending it:
if(msg.p._id==bot_ID){
if(a){
//game start:
if(msg.a.startsWith("Alright, "+MPP.client.getOwnParticipant().name+" started the math game! Get ready.")){
gamerunning=true;
}
//bot asks math question:
if(msg.a.startsWith('What is')){
setTimeout(function(){
//respond in time:
console.log(eval(msg.a.split('?')[0].split('What is')[1].trim()))
if(lvl!==5){
MPP.chat.send(JSON.stringify(eval(msg.a.split('?')[0].split('What is')[1].trim())));
setTimeout(function(){
if(!gamerunning){
MPP.chat.send('/math');
}
}, 800);
} else {
MPP.chat.send(JSON.stringify(eval(msg.a.split('?')[0].split('What is')[1].trim())));
setTimeout(function(){
if(!gamerunning){
MPP.chat.send('/math');
}
}, 800);
}
}, time);
//bot announces that the answer was correct by this bot
} else if(msg.a.toLowerCase().startsWith(MPP.client.getOwnParticipant().name.toLowerCase()+' found the answer,')){
lvlUp(); //lvl up
gamerunning = false;
if(learn){
//get better & faster:
learnaccuracy++;
time=time-500;
console.log('got better');
//when bot gets too hard to beat:
if(time<2500){
if(impossiblemsg){
impossiblemsg=false;
MPP.chat.send('I\'m practically impossible to beat!!');
}
}
}
//bot announces that somebody else got the answer before this bot
} else if(msg.a.toLowerCase().includes('found the answer,')) {
lvlDown(); //lvl down
gamerunning = false;
if(learn){
//get worse & slower:
learnaccuracy--;
time=time+500;
console.log('got worse');
}
}
}
}
});

Comments are disabled for this gist.