Skip to content

Instantly share code, notes, and snippets.

@ItsAminZamani
Created February 5, 2023 14:27
Embed
What would you like to do?
Game Of Life model for Political Revolution and Political Polarization
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>The Game of Life</title>
<link
href="https://cdn.jsdelivr.net/gh/rastikerdar/vazirmatn@v33.003/Vazirmatn-font-face.css"
rel="stylesheet"
type="text/css"
/>
<style>
* {
direction: rtl !important;
font-family: Vazirmatn, Vazir;
}
#gridContainer {
padding-bottom: 10px;
}
table {
background-color: #c5d6c6;
border-spacing: 0;
}
td {
border: 1px solid #f1f5da;
border-radius: 3px;
width: 10px;
height: 10px;
}
span {
color: #222;
}
#start,
#clear,
#random {
padding: 0.75em;
border-radius: 5px;
border: none;
background: linear-gradient(to bottom right, #c5dec6, #587559);
}
td.dead {
background-color: transparent;
}
td.live {
background-color: #cc4774;
border-radius: 10px;
}
td.right {
background-color: blue;
border-radius: 10px;
}
</style>
</head>
<body>
<div id="gridContainer"></div>
<div class="controls">
<button id="start"><span>شروع</span></button>
<button id="clear"><span>پاک کردن</span></button>
<button id="random"><span>رندوم</span></button>
</div>
<script>
var rows = 30;
var cols = 100;
var playing = false;
var grid = new Array(rows);
var nextGrid = new Array(rows);
var timer;
var reproductionTime = 100;
function initializeGrids() {
for (var i = 0; i < rows; i++) {
grid[i] = new Array(cols);
nextGrid[i] = new Array(cols);
}
}
function resetGrids() {
for (var i = 0; i < rows; i++) {
for (var j = 0; j < cols; j++) {
grid[i][j] = 0;
nextGrid[i][j] = 0;
}
}
}
function copyAndResetGrid() {
for (var i = 0; i < rows; i++) {
for (var j = 0; j < cols; j++) {
grid[i][j] = nextGrid[i][j];
nextGrid[i][j] = 0;
}
}
}
// Initialize
function initialize() {
createTable();
initializeGrids();
resetGrids();
setupControlButtons();
randomButtonHandler();
}
// Lay out the board
function createTable() {
var gridContainer = document.getElementById("gridContainer");
if (!gridContainer) {
// Throw error
console.error("Problem: No div for the drid table!");
}
var table = document.createElement("table");
for (var i = 0; i < rows; i++) {
var tr = document.createElement("tr");
for (var j = 0; j < cols; j++) {
//
var cell = document.createElement("td");
cell.setAttribute("id", i + "_" + j);
cell.setAttribute("class", "dead");
cell.onclick = cellClickHandler;
tr.appendChild(cell);
}
table.appendChild(tr);
}
gridContainer.appendChild(table);
}
function cellClickHandler() {
var rowcol = this.id.split("_");
var row = rowcol[0];
var col = rowcol[1];
var classes = this.getAttribute("class");
if (classes.indexOf("live") > -1) {
this.setAttribute("class", "dead");
grid[row][col] = 0;
} else {
this.setAttribute("class", "live");
grid[row][col] = 1;
}
}
function updateView() {
for (var i = 0; i < rows; i++) {
for (var j = 0; j < cols; j++) {
var cell = document.getElementById(i + "_" + j);
if (grid[i][j] == 0) {
cell.setAttribute("class", "dead");
} else if (grid[i][j] == 2) {
cell.setAttribute("class", "right");
} else {
cell.setAttribute("class", "live");
}
}
}
}
function setupControlButtons() {
// button to start
var startButton = document.getElementById("start");
startButton.onclick = startButtonHandler;
// button to clear
var clearButton = document.getElementById("clear");
clearButton.onclick = clearButtonHandler;
// button to set random initial state
var randomButton = document.getElementById("random");
randomButton.onclick = randomButtonHandler;
}
function randomButtonHandler() {
if (playing) return;
clearButtonHandler();
for (var i = 0; i < rows; i++) {
for (var j = 0; j < cols; j++) {
if (Math.random() > 0.9) {
var cell = document.getElementById(i + "_" + j);
cell.setAttribute("class", "right");
grid[i][j] = 2;
} else if (Math.random() > 0.8) {
var cell = document.getElementById(i + "_" + j);
cell.setAttribute("class", "live");
grid[i][j] = 1;
}
}
}
}
// clear the grid
function clearButtonHandler() {
console.log("Clear the game: stop playing, clear the grid");
playing = false;
var startButton = document.getElementById("start");
startButton.innerHTML = "شروع";
clearTimeout(timer);
var cellsList = document.getElementsByClassName("live");
// convert to array first, otherwise, you're working on a live node list
// and the update doesn't work!
var cells = [];
for (var i = 0; i < cellsList.length; i++) {
cells.push(cellsList[i]);
}
for (var i = 0; i < cells.length; i++) {
cells[i].setAttribute("class", "dead");
}
cellsList = document.getElementsByClassName("right");
var cells = [];
for (var i = 0; i < cellsList.length; i++) {
cells.push(cellsList[i]);
}
for (var i = 0; i < cells.length; i++) {
cells[i].setAttribute("class", "dead");
}
resetGrids;
}
// start/pause/continue the game
function startButtonHandler() {
if (playing) {
console.log("Pause the game");
playing = false;
this.innerHTML = "Continue";
clearTimeout(timer);
} else {
console.log("Continue the game");
playing = true;
this.innerHTML = "Pause";
play();
}
}
// run the life game
function play() {
computeNextGen();
if (playing) {
timer = setTimeout(play, reproductionTime);
}
}
function computeNextGen() {
for (var i = 0; i < rows; i++) {
for (var j = 0; j < cols; j++) {
applyRules(i, j);
}
}
modelPoliticalPolarization(0.3);
modelPoliticalRevolution(50, 15, 20);
// copy NextGrid to grid, and reset nextGrid
copyAndResetGrid();
// copy all 1 values to "live" in the table
updateView();
}
// RULES
// Any live cell with fewer than two live neighbours dies, as if caused by under-population.
// Any live cell with two or three live neighbours lives on to the next generation.
// Any live cell with more than three live neighbours dies, as if by overcrowding.
// Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
function applyRules(row, col) {
let status = grid[row][col];
let numNeighborsOne = countNeighborsOne(row, col);
let numNeighborsTwo = countNeighborsTwo(row, col);
if (status == 1 || status == 2) {
if (numNeighborsOne + numNeighborsTwo < 2) {
nextGrid[row][col] = 0;
} else if (numNeighborsOne + numNeighborsTwo > 3) {
nextGrid[row][col] = 0;
} else if (numNeighborsTwo == 2 || numNeighborsTwo == 3) {
nextGrid[row][col] = 2;
} else if (numNeighborsOne == 2 || numNeighborsOne == 3) {
nextGrid[row][col] = 1;
}
} else if (status == 0) {
let numNeighborsOne = countNeighborsOne(row, col);
let numNeighborsTwo = countNeighborsTwo(row, col);
if (numNeighborsOne + numNeighborsTwo == 3) {
if (numNeighborsOne > numNeighborsTwo) {
nextGrid[row][col] = 1;
} else {
nextGrid[row][col] = 2;
}
}
}
}
function modelPoliticalRevolution(location_x, location_y, strength) {
for (var i = 0; i < rows; i++) {
for (var j = 0; j < cols; j++) {
let distance = Math.sqrt(
Math.pow(location_x - i, 2) + Math.pow(location_y - j, 2)
);
if (distance <= strength) {
var cell = document.getElementById(i + "_" + j);
if (grid[i][j] == 0) {
if (Math.random() > 0.5) {
grid[i][j] = 2;
} else {
grid[i][j] = 1;
}
grid[i][j] = 1;
} else if (grid[i][j] == 1 || grid[i][j] == 2) {
grid[i][j] = 0;
}
}
}
}
}
function modelPoliticalPolarization(value) {
for (var i = 0; i < rows; i++) {
for (var j = 0; j < cols; j++) {
if (grid[i][j] == 1) {
if (Math.random() < value) {
grid[i][j] = 2;
}
} else if (grid[i][j] == 2) {
if (Math.random() < value) {
grid[i][j] = 1;
}
}
}
}
}
function countNeighborsOne(row, col) {
var count = 0;
if (row - 1 >= 0) {
if (grid[row - 1][col] == 1) count++;
}
if (row - 1 >= 0 && col - 1 >= 0) {
if (grid[row - 1][col - 1] == 1) count++;
}
if (row - 1 >= 0 && col + 1 < cols) {
if (grid[row - 1][col + 1] == 1) count++;
}
if (col - 1 >= 0) {
if (grid[row][col - 1] == 1) count++;
}
if (col + 1 < cols) {
if (grid[row][col + 1] == 1) count++;
}
if (row + 1 < rows) {
if (grid[row + 1][col] == 1) count++;
}
if (row + 1 < rows && col - 1 >= 0) {
if (grid[row + 1][col - 1] == 1) count++;
}
if (row + 1 < rows && col + 1 < cols) {
if (grid[row + 1][col + 1] == 1) count++;
}
return count;
}
function countNeighborsTwo(row, col) {
var count = 0;
if (row - 1 >= 0) {
if (grid[row - 1][col] == 2) count++;
}
if (row - 1 >= 0 && col - 1 >= 0) {
if (grid[row - 1][col - 1] == 2) count++;
}
if (row - 1 >= 0 && col + 1 < cols) {
if (grid[row - 1][col + 1] == 2) count++;
}
if (col - 1 >= 0) {
if (grid[row][col - 1] == 2) count++;
}
if (col + 1 < cols) {
if (grid[row][col + 1] == 2) count++;
}
if (row + 1 < rows) {
if (grid[row + 1][col] == 2) count++;
}
if (row + 1 < rows && col - 1 >= 0) {
if (grid[row + 1][col - 1] == 2) count++;
}
if (row + 1 < rows && col + 1 < cols) {
if (grid[row + 1][col + 1] == 2) count++;
}
return count;
}
// Start everything
window.onload = initialize;
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment