Game of Life MPP

John Conway’s Game of Life in MPP ¯\_(ツ)_/¯

  1. // ==UserScript==
  2. // @name Game of Life MPP
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.4.1
  5. // @description John Conway’s Game of Life in MPP ¯\_(ツ)_/¯
  6. // @author Hustandant#1917
  7. // @match *://multiplayerpiano.net/*
  8. // @license MIT
  9. // @icon https://github.com/Hustoroff/mpp/blob/main/icon.png?raw=true
  10. // @grant none
  11. // @run-at document-end
  12. // ==/UserScript==
  13. window.addEventListener('load', (event) => {
  14. var mashtab = 10, matr = [], indstrt = false, webBool = false, delay = 0.5, f = 0, LifeC = 0, setTime;
  15.  
  16. MPP.client.on("a", function(msg) {
  17. let message = msg.a.split(" ");
  18. if(message[0] == "delay" && msg.p.id == MPP.client.participantId && !isNaN(Number(message[1]))) {
  19. delay = (Number(message[1]) > 3) ? 3 : (Number(message[1]) <= 0) ? 0.001 : Number(message[1]);
  20. document.getElementById("delay").innerText = delay;
  21. }
  22. });
  23.  
  24. MPP.client.emit("notification", {
  25. title: "Game of Life script (by Hustandant#1917)",
  26. id:"Script_notification",
  27. duration:20000,
  28. target:"#piano",
  29. html:`<p><h3>F2 - start<br> F4 - clear canvas<br> Tab - grid</br></h3> ${delay} sec. - current delay (<span style="background-color: black"><font color="red">to chat "delay [min - 0.001 max - 3]"</font></span>)<br>ctrl + left mouse button - clear rect</p> Join our discord server: <a target="_blank" href="https://discord.gg/A3SDgxS2Q2">https://discord.gg/A3SDgxS2Q2<a>`
  30. });
  31.  
  32. const statGM = document.createElement("div");
  33. statGM.id = "statGM";
  34. statGM.style.opacity = "1";
  35. statGM.style.position = "fixed";
  36. statGM.style["z-index"] = 150;
  37. statGM.style.display = "block";
  38. statGM.style.float = "right";
  39. statGM.style.margin = "auto";
  40. statGM.style.top = `${document.getElementById("piano").height}px`;
  41. statGM.style["background-color"] = "rgba(137, 137, 137, 0.414)";
  42. statGM.style["backdrop-filter"] = "blur(1px)";
  43. statGM.style["font-size"] = "21px"
  44. statGM.innerHTML = `<span id="start">Start (F2)</span>, Delay: <span id="delay">${delay}</span>, Сells: <span id="LifeC">0</span>, FPS: <span id="fps">0</span>`;
  45. statGM.style.marginLeft = `${String(document.getElementById("piano").offsetLeft + document.getElementById("piano").getElementsByTagName("canvas")[0].offsetLeft)}px`;
  46.  
  47. const canvas = document.createElement("canvas");
  48. canvas.height = parseInt(document.getElementById("piano").style["margin-top"]);
  49. canvas.width = window.innerWidth;
  50. canvas.id = "canv";
  51. canvas.style.opacity = "1";
  52. canvas.style.top = "0";
  53. canvas.style.display = "block";
  54. canvas.style.float = "right";
  55. canvas.style.position = "fixed";
  56. canvas.style.margin = "auto";canvas.style["z-index"] = 200;
  57. canvas.style["background-color"] = "black";
  58.  
  59. const ctx = window.ctx = canvas.getContext("2d");
  60.  
  61. const canvas_web = document.createElement("canvas");
  62.  
  63. canvas_web.height = parseInt(document.getElementById("piano").style["margin-top"]),
  64. canvas_web.width = window.innerWidth;
  65. canvas_web.id = "canv_web";
  66. canvas_web.style.opacity = "1";
  67. canvas_web.style.top = "0";
  68. canvas_web.style.display = "none";
  69. canvas_web.style.float = "right";
  70. canvas_web.style.position = "fixed";
  71. canvas_web.style.margin = "auto";
  72. canvas_web.style["pointer-events"] = "none";
  73. canvas_web.style["z-index"] = 201;
  74.  
  75. const ctx_web = window.ctx = canvas_web.getContext("2d");
  76.  
  77. document.body.append(canvas);
  78. document.body.append(canvas_web);
  79. document.body.append(statGM);
  80.  
  81. window.addEventListener("keyup", function (key) {
  82. key.code == "F2" ? start() : key.code == "F4" ? clearSpace() : key.code == "Tab" ? web() : console.log("ничего");
  83. });
  84.  
  85. function start() {
  86. indstrt = !indstrt;
  87. document.getElementById("start").innerText = indstrt ? "Stop (F2)" : "Start (F2)";
  88. if (indstrt) scanCanvas();
  89. };
  90.  
  91. setInterval(() => {
  92. document.getElementById("fps").innerText = f;
  93. f = 0;
  94. }, 1e3);
  95. window.requestAnimationFrame(fps);
  96.  
  97. function fps() {
  98. f++;
  99. window.requestAnimationFrame(fps);
  100. };
  101.  
  102. function clearSpace() {
  103. ctx.clearRect(0, 0, canvas.width, canvas.height);
  104. for (var i = 0; i < Math.floor(canvas.height / mashtab); i++) {
  105. for (var j = 0; j < Math.floor(canvas.width / mashtab); j++) {
  106. matr[i][j] = 0;
  107. ctx.fillStyle = canvas.style["background-color"] == "white" ? "white" : "black";
  108. ctx.fillRect(j * mashtab, i * mashtab, 10, 10);
  109. }
  110. }
  111. drawRect();
  112. };
  113.  
  114. function web() {
  115. webBool = !webBool;
  116. canvas_web.style.display = webBool ? "block" : "none";
  117. };
  118.  
  119. function drawWeb() {
  120. for (let i = 0; i < Math.floor(canvas_web.height / mashtab); i ++) {
  121. for (let j = 0; j < Math.floor(canvas_web.width / mashtab); j ++) {
  122. ctx_web.strokeStyle = "white";
  123. ctx_web.lineWidth = "0.2";
  124. ctx_web.strokeRect(j * mashtab, i * mashtab, 10, 10);
  125. }
  126. }
  127. };
  128.  
  129. drawWeb();
  130.  
  131. function matrDraw() {
  132. for (var i = 0; i < Math.floor(canvas.height / mashtab); i++) {
  133. matr[i] = [];
  134. for (var j = 0; j < Math.floor(canvas.width / mashtab); j++) {
  135. matr[i][j] = 0;
  136. }
  137. }
  138. };
  139.  
  140. matrDraw();
  141.  
  142. function drawRect() {
  143. LifeC = 0;
  144. ctx.clearRect(0, 0, canvas.width, canvas.height);
  145. for (var i = 0; i < Math.floor(canvas.height / mashtab); i++) {
  146. for (var j = 0; j < Math.floor(canvas.width / mashtab); j++) {
  147. ctx.fillStyle = matr[i][j] == 1 ? "white" : "black";
  148. ctx.fillRect(j * mashtab, i * mashtab, 10, 10);
  149. if(matr[i][j] == 1) LifeC++;
  150. }
  151. }
  152. document.getElementById("LifeC").innerText = LifeC;
  153. };
  154.  
  155. canvas.onclick = function(event) {
  156. if (!indstrt && !event.ctrlKey) {
  157. matr[Math.floor(event.offsetY / mashtab)][Math.floor(event.offsetX / mashtab)] = 1;
  158. drawMouse(1, Math.floor(event.offsetY / mashtab), Math.floor(event.offsetX / mashtab));
  159. } else {
  160. if(!indstrt && event.ctrlKey) {
  161. matr[Math.floor(event.offsetY / mashtab)][Math.floor(event.offsetX / mashtab)] = 0;
  162. drawMouse(0, Math.floor(event.offsetY / mashtab), Math.floor(event.offsetX / mashtab));
  163. }
  164. }
  165. };
  166.  
  167. canvas.onmousemove = (event) => {
  168. if(!indstrt && event.which == 1 && !event.ctrlKey) {
  169. matr[Math.floor(event.offsetY / mashtab)][Math.floor(event.offsetX / mashtab)] = 1;
  170. drawMouse(1, Math.floor(event.offsetY / mashtab), Math.floor(event.offsetX / mashtab));
  171. } else {
  172. if(!indstrt && event.which == 1 && event.ctrlKey) {
  173. matr[Math.floor(event.offsetY / mashtab)][Math.floor(event.offsetX / mashtab)] = 0;
  174. drawMouse(0, Math.floor(event.offsetY / mashtab), Math.floor(event.offsetX / mashtab));
  175. }
  176. }
  177. };
  178.  
  179. function drawMouse(stat, y, x) {
  180. ctx.fillStyle = stat == 1 ? "white" : "black";
  181. ctx.fillRect(x * mashtab, y * mashtab, 10, 10);
  182. };
  183.  
  184. function scanCanvas(step) {
  185. if(indstrt){
  186. LifeC = 0;
  187. var arr = [];
  188. for (var i = 0; i < Math.floor(canvas.height / mashtab); i++) {
  189. arr[i] = [];
  190. for (var j = 0; j < Math.floor(canvas.width / mashtab); j++) {
  191. var c = 0;
  192. if(matr[i][j] == 1) LifeC++;
  193. if (matr[(i == 0 ? Math.floor(canvas.height / mashtab) : i) - 1][j] == 1) c++;
  194. if (matr[i][(j == Math.floor(canvas.width / mashtab) - 1 ? -1 : j) + 1] == 1) c++;
  195. if (matr[(i == Math.floor(canvas.height / mashtab) - 1 ? -1 : i) + 1][j] == 1) c++;
  196. if (matr[i][(j == 0 ? Math.floor(canvas.width / mashtab) : j) - 1] == 1) c++;
  197. if (matr[(i == 0 ? Math.floor(canvas.height / mashtab) : i) - 1][(j == Math.floor(canvas.width / mashtab) - 1 ? -1 : j) + 1] == 1) c++;
  198. if (matr[(i == Math.floor(canvas.height / mashtab) - 1 ? -1 : i) + 1][(j == Math.floor(canvas.width / mashtab) - 1 ? -1 : j) + 1] == 1) c++;
  199. if (matr[(i == Math.floor(canvas.height / mashtab) - 1 ? -1 : i) + 1][(j == 0 ? Math.floor(canvas.width / mashtab) : j) - 1] == 1) c++;
  200. if (matr[(i == 0 ? Math.floor(canvas.height / mashtab) : i) - 1][(j == 0 ? Math.floor(canvas.width / mashtab) : j) - 1] == 1) c++;
  201. arr[i][j] = matr[i][j] == 0 ? c == 3 ? 1 : 0 : c == 2 || c == 3 ? 1 : 0;
  202. }
  203. }
  204. matr = arr;
  205. document.getElementById("LifeC").innerText = LifeC;
  206. drawRect();
  207. setTime = setTimeout(scanCanvas, delay*1000);
  208. }
  209. };
  210. });