Skip to content

Instantly share code, notes, and snippets.

@enimiste
Last active April 10, 2024 20:51
Show Gist options
  • Select an option

  • Save enimiste/0e37145e49ba6deaf4f721dfd19c5358 to your computer and use it in GitHub Desktop.

Select an option

Save enimiste/0e37145e49ba6deaf4f721dfd19c5358 to your computer and use it in GitHub Desktop.
Simulation of heat transmission
/*
<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