Turing machine #2

Merged
Simponic merged 4 commits from turing-machine into main 2023-10-25 01:44:38 -04:00
3 changed files with 202 additions and 0 deletions
Showing only changes of commit 1d15cdcb2a - Show all commits

View File

@ -0,0 +1,90 @@
* {
font-family: "Trebuchet MS", sans-serif;
}
button {
background: #bbbbbb;
border: 1px solid white;
border-radius: 0.2rem;
padding: 0.2rem;
}
button:hover {
background: #cccccc;
}
body {
margin: 0;
background-color: #aaaaaa;
}
.container {
display: flex;
width: 90%;
margin-left: auto;
margin-right: auto;
flex-direction: column;
padding: 2rem;
}
.tape {
display: flex;
padding: 1rem;
align-items: center;
gap: 1rem;
height: 5rem;
max-width: 100%;
border: 1px solid black;
overflow-x: scroll;
overflow-y: hidden;
}
.cell {
position: relative;
height: 80%;
border: 3px solid black;
transition: border 0.1s ease-in-out;
transition: background 0.1s ease-in-out;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
flex: 1;
gap: 0.2rem;
padding: 0.2rem;
}
.circle {
position: absolute;
bottom: -15px;
left: 50%;
transform: translateX(-50%);
width: 10px;
height: 10px;
background-color: wheat;
border-radius: 50%;
opacity: 0.001;
transition: opacity 0.1s ease-in-out;
}
.cell.reading .circle {
opacity: 1;
}
.reading {
border-color: green;
background-color: wheat;
}
.cell-input {
width: 50px;
text-align: center;
}

14
turing-machine/index.html Normal file
View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title>Turing Machine Simulator</title>
<link rel="stylesheet" type="text/css" href="css/styles.css">
</head>
<body>
<div class="container">
<h1>Simponic's State System</h1>
<div id="tape" class="tape"></div>
</div>
<script src="js/main.js"></script>
</body>
</html>

98
turing-machine/js/main.js Normal file
View File

@ -0,0 +1,98 @@
const DISPLAY_CELLS = 15;
const TAPE_LEN = 200;
const MESSAGES = {
SET_CELL: "SET_CELL",
PAUSE: "PAUSE",
SIMULATE: "SIMULATE",
SET_READER: "SET_READER",
};
class Observable {
constructor() {
this.observers = [];
}
subscribe(f) {
this.observers.push(f);
}
unsubscribe(f) {
this.observers = this.observers.filter((subscriber) => subscriber !== f);
}
notify(data) {
this.observers.forEach((observer) => observer(data));
}
}
const state = new Observable();
const tape = Array(TAPE_LEN).fill(0);
state.subscribe((msg) => {
if (msg.type == MESSAGES.SET_CELL) {
tape[msg.cellId] = msg.value;
}
});
const tapeEl = document.getElementById("tape");
const inputCellId = (cellId) => `${cellId}-input`;
const updateCellButtonId = (cellId) => `${cellId}-button-update`;
const setCellFromInput = (cellId, inputId) => {
const input = document.getElementById(inputId);
tape[cellId] = input.value;
};
const cell = (cellId, initValue = 0) => {
const cellDiv = document.createElement("div");
cellDiv.classList.add("cell");
cellDiv.id = cellId;
const readingHead = document.createElement("div");
readingHead.classList.add("circle");
const input = document.createElement("input");
const inputId = inputCellId(cellId);
input.classList.add("cell-input");
input.id = inputId;
input.value = initValue;
input.addEventListener("focusin", () =>
state.notify({ type: MESSAGES.PAUSE })
);
input.addEventListener("focusout", () =>
state.notify({ type: MESSAGES.SET_CELL, cell: cellId, value: input.value })
);
state.subscribe((msg) => {
if (msg.type == MESSAGES.SET_CELL && msg.cell == cellId) {
input.value = msg.value;
}
if (msg.type == MESSAGES.SET_READER) {
if (msg.cell == cellId) {
cellDiv.classList.add("reading");
cellDiv.scrollIntoView({
behavior: "smooth",
});
} else cellDiv.classList.remove("reading");
}
});
cellDiv.appendChild(input);
cellDiv.appendChild(readingHead);
return cellDiv;
};
const main = () => {
const cells = tape.map((_, cellId) => cell(cellId));
for (const cell of cells) {
tapeEl.appendChild(cell);
}
state.notify({ type: MESSAGES.SET_READER, cell: 0 });
setTimeout(() => {}, 1000);
};
main();