xxxxxxxxxx
433
// this project uses the p5.js library
// the p5.js library can be found at https://p5js.org
// the editor used to create and run this code can be found at https://editor.p5js.org
const arraySize = 50
var cellArray = [];
var paused = false;
class Cell {
constructor(type = "air", heatEnergy = 2, heatCapacity = 0.1, col = [20,20,20], life = 0, pressure = 50, phase = "gas"){
this.type = type
this.heatEnergy = heatEnergy
this.heatCapacity = heatCapacity
this.col = col
this.life = life
this.pressure = pressure
this.phase = "gas"
}
}
var ceramic = new Cell()
ceramic.type = "ceramic";
ceramic.heatCapacity = 10
ceramic.heatEnergy = 200
ceramic.col = [140,140,140]
ceramic.phase = "solid"
var iron = new Cell()
iron.type = "iron";
iron.heatCapacity = 0.5
iron.heatEnergy = 10
iron.col = [100,100,100]
iron.phase = "solid"
var moltenIron = new Cell()
moltenIron.type = "molten iron"
moltenIron.heatCapacity = 0.5
moltenIron.heatEnergy = 1538 * iron.heatCapacity
moltenIron.col = [200,100,0]
moltenIron.phase = "liquid"
var water = new Cell()
water.type = "water"
water.heatCapacity = 4
water.heatEnergy = 80
water.col = [0,10,100]
water.phase = "liquid"
var ice = new Cell()
ice.type = "ice"
ice.heatCapacity = 4
ice.heatEnergy = 0
ice.col = [210,230,255]
ice.phase = "solid"
var steam = new Cell()
steam.type = "steam"
steam.heatCapacity = 4
steam.heatEnergy = 400
steam.col = [230,230,230]
steam.phase = "gas"
var coal = new Cell()
coal.type = "coal"
coal.heatCapacity = 1.4
coal.heatEnergy = 20 * coal.heatCapacity
coal.col = [50,50,50]
coal.phase = "solid"
var fire = new Cell()
fire.type = "fire"
fire.heatCapacity = 1
fire.heatEnergy = 800
fire.col = [200,170,20]
fire.phase = "gas"
fire.life = 30
var COLD = new Cell()
COLD.type = "COLD"
COLD.heatCapacity = 10
COLD.heatEnergy = -100000
COLD.col = [150,200,255]
COLD.phase = "solid"
var HOT = new Cell()
HOT.type = "HOT"
HOT.heatCapacity = 10
HOT.heatEnergy = 100000
HOT.col = [255,0,0]
HOT.phase = "solid"
function setCell(x,y,base){
cellArray[x][y].type = base.type
cellArray[x][y].heatEnergy = base.heatEnergy
cellArray[x][y].heatCapacity = base.heatCapacity
cellArray[x][y].col = base.col
cellArray[x][y].life = base.life
cellArray[x][y].pressure = base.pressure
cellArray[x][y].phase = base.phase
}
function convertCell(x,y,base){
cellArray[x][y].type = base.type
cellArray[x][y].heatCapacity = base.heatCapacity
cellArray[x][y].col = base.col
cellArray[x][y].life = base.life
cellArray[x][y].phase = base.phase
}
function swapCell(x,y,newx,newy){
if(newx < arraySize && newx >= 0 && newy < arraySize && newy >= 0){
let temp = cellArray[newx][newy]
cellArray[newx][newy] = cellArray[x][y];
cellArray[x][y] = temp
} else {
cellArray[x][y] = new Cell()
}
}
function getCell(x,y){
if(x >= 0 && y >= 0 && x < arraySize && y < arraySize){
return cellArray[x][y]
} else {
return new Cell()
}
}
function getAdjacentCells(x,y){
let cells = []
for(let i = -1; i < 2; i++){
cells[cells.length] = [x+i,y+1,
getCell(x+i, y+1)
]
}
for(let i = -1; i < 2; i++){
cells[cells.length] = [x+i,y-1,
getCell(x+i, y-1)
]
}
cells[cells.length] = [x-1,y,
getCell(x-1, y)
]
cells[cells.length] = [x+1,y,
getCell(x+1, y)
]
return cells
}
function getTouchingCells(x,y){
let cells = []
cells[cells.length] = [x,y+1,
getCell(x, y+1)
]
cells[cells.length] = [x,y-1,
getCell(x, y-1)
]
cells[cells.length] = [x-1,y,
getCell(x-1, y)
]
cells[cells.length] = [x+1,y,
getCell(x+1, y)
]
return cells
}
function getTemp(x,y){
return ( getCell(x,y).heatEnergy / getCell(x,y).heatCapacity )
}
function setup() {
createCanvas(450, 450);
frameRate(30);
for(let x = 0; x < arraySize; x++){
cellArray[x] = [];
for(let y = 0; y < arraySize; y++){
cellArray[x][y] = new Cell()
}
}
}
var cellList = [new Cell(), iron, ceramic, moltenIron, water, ice, steam, coal, fire, HOT, COLD]
var selectedCell = 0
let cellsToSwap = []
let gasesToSwap = []
function liquidBehavior(x,y){
let possiblePos = []
for(let i = -1; i < 2; i++){
if(getCell(x + i, y + 1).phase == "gas"){
possiblePos[possiblePos.length] = [x + i, y + 1]
}
}
if(possiblePos.length > 0){
let rand = round(random(0,possiblePos.length - 1))
queueSwap(x,y,possiblePos[rand][0],possiblePos[rand][1])
} else {
possiblePos = []
if(getCell(x-1,y).phase == "gas") possiblePos[possiblePos.length] = [x-1,y]
if(getCell(x+1,y).phase == "gas") possiblePos[possiblePos.length] = [x+1,y]
if(possiblePos.length > 0){
let rand = round(random(0,possiblePos.length - 1))
queueSwap(x,y,possiblePos[rand][0],possiblePos[rand][1])
}
}
}
function gasBehavior(x,y){
let possiblePos = []
for(let i = -1; i < 2; i++){
if(getCell(x + i, y + 1).phase == "gas"){
possiblePos[possiblePos.length] = [x+i,y+1,
100/( getTemp(x+i,y+1) * getCell(x+i,y+1).pressure )
]
}
}
for(let i = -1; i < 2; i++){
if(getCell(x + i, y - 1).phase == "gas"){
possiblePos[possiblePos.length] = [x+i,y-1,
100/( getTemp(x+i,y-1) * getCell(x+i,y+1).pressure )
]
}
}
if(getCell(x-1,y).phase == "gas") {
possiblePos[possiblePos.length] = [x-1,y,
100/( getTemp(x-1,y) * getCell(x-1,y).pressure )
]
}
if(getCell(x+1,y).phase == "gas") {
possiblePos[possiblePos.length] = [x+1,y,
100/( getTemp(x+1,y) * getCell(x+1,y).pressure )
]
}
if(possiblePos.length > 0){
let totalScore = 0
for(let i = 0; i < possiblePos.length; i++){
totalScore += possiblePos[i][2]
}
let check = 0
let rand = random(0,totalScore)
for(let i = 0; i < possiblePos.length; i++){
if(rand < check + possiblePos[i][2]){
queueGasSwap(x,y,possiblePos[i][0],possiblePos[i][1])
return null
}
check += possiblePos[i][2]
}
}
}
function queueSwap(x,y,newX,newY){
cellsToSwap[cellsToSwap.length] = [x,y,newX,newY]
}
function queueGasSwap(x,y,newX,newY){
gasesToSwap[gasesToSwap.length] = [x,y,newX,newY]
}
function keyPressed(){
if(keyCode == 32) paused = !paused
if(keyCode == 69) selectedCell++
if(keyCode == 81) selectedCell--
if(selectedCell < 0) selectedCell = cellList.length - 1
}
function draw() {
background(20);
noStroke()
var cX = floor(mouseX/(400/arraySize))
var cY = floor(mouseY/(400/arraySize))
if(mouseX < 400 && mouseY < 400){
fill(255)
textSize(20)
text(round(cellArray[cX][cY].heatEnergy/cellArray[cX][cY].heatCapacity),410,20)
}
if(mouseIsPressed && mouseX < 400 && mouseY < 400){
setCell(cX,cY,cellList[selectedCell%cellList.length])
}
textSize(12)
fill(255)
noStroke()
text(cellList[((selectedCell+cellList.length-2)%cellList.length)].type,20,430)
text(cellList[((selectedCell+cellList.length-1)%cellList.length)].type,80,430)
text("<Q",140, 430)
text(cellList[selectedCell%cellList.length].type,180,430)
text("E>",240, 430)
text(cellList[(selectedCell+1)%cellList.length].type,280,430)
text(cellList[(selectedCell+2)%cellList.length].type,340,430)
for(let x = 0; x < arraySize; x++){
for(let y = 0; y < arraySize; y++){
fill(color(cellArray[x][y].col))
rect(x*(400/arraySize),y*(400/arraySize),(400/arraySize),(400/arraySize))
}
}
if(!paused){
cellsToSwap = []
gasesToSwap = []
let executionOrder = []
for(let x = 0; x < arraySize; x++){
for(let y = 0; y < arraySize; y++){
executionOrder[executionOrder.length] = [x,y]
}
}
executionOrder = shuffle(executionOrder)
for(let e = 0; e < executionOrder.length; e++){
let x = executionOrder[e][0]
let y = executionOrder[e][1]
switch(cellArray[x][y].type){
case "water":
if(getCell(x,y).heatEnergy/getCell(x,y).heatCapacity > 100){ convertCell(x,y,steam); break; }
if(getCell(x,y).heatEnergy/getCell(x,y).heatCapacity < 0) { convertCell(x,y,ice); break; }
liquidBehavior(x,y)
break
case "steam":
if(getCell(x,y).heatEnergy/getCell(x,y).heatCapacity < 100){ convertCell(x,y,water); break; }
gasBehavior(x,y)
break
case "ice":
if(getCell(x,y).heatEnergy/getCell(x,y).heatCapacity > 0){ convertCell(x,y,water); break; }
break
case "COLD":
cellArray[x][y].heatEnergy = -100000
break
case "HOT":
cellArray[x][y].heatEnergy = 100000
break
case "iron":
if(getCell(x,y).heatEnergy/getCell(x,y).heatCapacity > 1538) { convertCell(x,y,moltenIron) }
break
case "molten iron":
liquidBehavior(x,y)
if(getCell(x,y).heatEnergy/getCell(x,y).heatCapacity < 1538) { convertCell(x,y,iron) }
break
case "coal":
if(getCell(x,y).heatEnergy/getCell(x,y).heatCapacity > 500){
getCell(x,y).heatEnergy += 300
convertCell(x,y,fire)
}
break
case "fire":
gasBehavior(x,y)
if(getCell(x,y).life <= 0){
convertCell(x,y,new Cell())
}
getCell(x,y).life --
break
}
}
executionOrder = shuffle(executionOrder)
for(let e = 0; e < executionOrder.length; e++){
let x = executionOrder[e][0]
let y = executionOrder[e][1]
if(y+1 < cellArray.length){
let tempDiff = (cellArray[x][y+1].heatEnergy/cellArray[x][y+1].heatCapacity) - (cellArray[x][y].heatEnergy/cellArray[x][y].heatCapacity)
let lowerCap = min(cellArray[x][y+1].heatCapacity,cellArray[x][y].heatCapacity)
cellArray[x][y].heatEnergy += (tempDiff * lowerCap)/10
cellArray[x][y+1].heatEnergy -= (tempDiff * lowerCap)/12
}
if(x+1 < cellArray.length){
let tempDiff = (cellArray[x+1][y].heatEnergy/cellArray[x+1][y].heatCapacity) - (cellArray[x][y].heatEnergy/cellArray[x][y].heatCapacity)
let lowerCap = min(cellArray[x+1][y].heatCapacity,cellArray[x][y].heatCapacity)
cellArray[x][y].heatEnergy += (tempDiff * lowerCap)/10
cellArray[x+1][y].heatEnergy -= (tempDiff * lowerCap)/10
}
if(y-1 >= 0){
let tempDiff = (cellArray[x][y-1].heatEnergy/cellArray[x][y-1].heatCapacity) - (cellArray[x][y].heatEnergy/cellArray[x][y].heatCapacity)
let lowerCap = min(cellArray[x][y-1].heatCapacity,cellArray[x][y].heatCapacity)
cellArray[x][y].heatEnergy += (tempDiff * lowerCap)/10
cellArray[x][y-1].heatEnergy -= (tempDiff * lowerCap)/10
}
if(x-1 >= 0){
let tempDiff = (cellArray[x-1][y].heatEnergy/cellArray[x-1][y].heatCapacity) - (cellArray[x][y].heatEnergy/cellArray[x][y].heatCapacity)
let lowerCap = min(cellArray[x-1][y].heatCapacity,cellArray[x][y].heatCapacity)
cellArray[x][y].heatEnergy += (tempDiff * lowerCap)/12
cellArray[x-1][y].heatEnergy -= (tempDiff * lowerCap)/10
}
}
for(let i = 0; i < gasesToSwap.length; i++){
swapCell(gasesToSwap[i][0],gasesToSwap[i][1],gasesToSwap[i][2],gasesToSwap[i][3])
}
for(let i = 0; i < cellsToSwap.length; i++){
swapCell(cellsToSwap[i][0],cellsToSwap[i][1],cellsToSwap[i][2],cellsToSwap[i][3])
}
}
}