Last active
April 10, 2024 20:51
-
-
Save enimiste/0e37145e49ba6deaf4f721dfd19c5358 to your computer and use it in GitHub Desktop.
Simulation of heat transmission
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| <html> | |
| <head> | |
| <meta charset="utf-8"/> | |
| </head> | |
| <body style="border-color: #edecec3b;"> | |
| <div> | |
| <h2 id="title">Game</h2> | |
| <canvas style="border: 1px solid gray;" data-size="900"></canvas> | |
| <br/> | |
| <br/> | |
| <button id="start_game">Start game</button> | |
| <br/> | |
| <br/> | |
| <button id="stop_game">Stop game</button> | |
| </div> | |
| <script src="./app.js"></script> | |
| </body> | |
| </html> | |
| */ | |
| window.stop_game_requested = false; | |
| const canvas = document.getElementsByTagName("canvas")[0]; | |
| const title = document.getElementById("title"); | |
| const grid = build_grid(parseInt(canvas.getAttribute('data-size')), 30); | |
| const delay = ms => new Promise(res => setTimeout(res, ms)); | |
| const play = async (max_iterations, interval_sec) => { | |
| console.log("Begin play"); | |
| let iter = 1; | |
| while (iter <= max_iterations && !window.stop_game_requested) { | |
| title.innerText = "Iteration N° : " + iter + "/" + max_iterations; | |
| draw(canvas, grid, true, true); | |
| iter++; | |
| await delay(interval_sec); | |
| update_cells(grid); | |
| } | |
| if (window.stop_game_requested) | |
| title.innerText = title.innerText + " (Game stopped)"; | |
| console.log("End play"); | |
| }; | |
| const stopBtn = document.getElementById("stop_game"); | |
| const startBtn = document.getElementById("start_game"); | |
| stopBtn.addEventListener('click', (e) => { | |
| console.log("Game will be stopped"); | |
| window.stop_game_requested = true; | |
| }); | |
| startBtn.addEventListener('click', (e) => { | |
| console.log("Game started"); | |
| window.stop_game_requested = false; | |
| //************************ GAME | |
| //first_rows_count = Math.ceil(grid.cells.length * 30 / 100); | |
| //fill_first_rows(grid.cells, first_rows_count, 255); | |
| fill_all_cells_random(grid.cells, 10, 255); | |
| play(1000, 500); | |
| }); | |
| //*********************** Functions | |
| function update_cells(grid) { | |
| const old_cells = grid.cells; | |
| const cells = JSON.parse(JSON.stringify(old_cells)); | |
| for (let i = 0, n = cells.length; i < n; i += 1) { | |
| const row = cells[i]; | |
| for (let j = 0, m = row.length; j < m; j += 1) { | |
| const v = row[j]; | |
| let avg = v; | |
| if (j > 0) | |
| avg += old_cells[i][j - 1]; | |
| else | |
| avg += v; | |
| if (i > 0) { | |
| if (j > 0) | |
| avg += old_cells[i - 1][j - 1]; | |
| else | |
| avg += v; | |
| avg += old_cells[i - 1][j]; | |
| if (j < m - 1) | |
| avg += old_cells[i - 1][j + 1]; | |
| } else | |
| avg += v * 3; | |
| if (j < m - 1) | |
| avg += old_cells[i][j + 1]; | |
| if (i < n - 1) { | |
| if (j > 0) | |
| avg += old_cells[i + 1][j - 1]; | |
| else | |
| avg += v; | |
| avg += old_cells[i + 1][j]; | |
| if (j < m - 1) | |
| avg += old_cells[i + 1][j + 1]; | |
| } | |
| cells[i][j] = avg / 9; | |
| } | |
| } | |
| grid.cells = cells; | |
| } | |
| function fill_first_rows(cells, rows_count, value) { | |
| for (let i = 0; i < cells.length; i += 1) { | |
| const row = cells[i]; | |
| for (let j = 0; j < row.length; j += 1) { | |
| row[j] = value; | |
| } | |
| if (i >= rows_count) | |
| break; | |
| } | |
| } | |
| function fill_all_cells_random(cells, min_val, max_val) { | |
| for (let i = 0; i < cells.length; i += 1) { | |
| const row = cells[i]; | |
| let seed = min_val + Math.random() * (max_val - min_val + 1); | |
| for (let j = 0; j < row.length; j += 1) { | |
| row[j] = seed; | |
| } | |
| } | |
| } | |
| function build_grid(size, ds) { | |
| const grid = []; | |
| for (let i = 0, n = size / ds; i < n; i += 1) { | |
| grid[i] = []; | |
| for (let j = 0, m = size / ds; j < m; j += 1) { | |
| grid[i][j] = 0; | |
| } | |
| } | |
| return { | |
| 'cells': grid, | |
| 'width': size, | |
| 'height': size, | |
| 'dx': ds, | |
| 'dy': ds | |
| }; | |
| } | |
| function draw(canvas, { cells, width, height, dx, dy }, stroke, show_text) { | |
| // Create the canvas element | |
| const ctx = canvas.getContext("2d"); | |
| ctx.clearRect(0, 0, width, height); | |
| canvas.width = width;//How many pixels wide do you want the canvas? (Recommended around 1000) | |
| canvas.height = height;//How many pixels high do you want the canvas? (Recommended around 500) | |
| ctx.strokeStyle = "#edecec3b"; | |
| for (let i = 0; i < cells.length; i += 1) { | |
| const row = cells[i]; | |
| for (let j = 0; j < row.length; j += 1) { | |
| const cell_value = row[j]; | |
| ctx.fillStyle = color_gen(cell_value); | |
| ctx.beginPath(); | |
| ctx.rect(j * dy, i * dx, dx, dy); | |
| ctx.fill(); | |
| if(show_text){ | |
| ctx.fillStyle = "black"; | |
| ctx.font = "9px serif"; | |
| ctx.fillText(Math.floor(cell_value), i * dx + dx/2.5, j * dy + dy/2.0, dx); | |
| } | |
| if (stroke) | |
| ctx.stroke(); | |
| } | |
| } | |
| } | |
| function color_gen(v) { | |
| const red = { 'r': 238, 'g': 49, 'b': 63 }; | |
| const orange = { 'r': 233, 'g': 156, 'b': 23 }; | |
| const green = { 'r': 0, 'g': 183, 'b': 0 }; | |
| const color = v < 10 ? green : (v < 37 ? orange : red); | |
| const res = "rgba(" + color.r + ", " + | |
| color.g + ", " + | |
| color.b + ", " + | |
| (0.01 + Math.min(v, 200) / 200) + ")"; | |
| return res; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment