La Máquina de Turing es una simulación interactiva de una máquina de Turing básica. Esta página web proporciona una interfaz que permite a los usuarios interactuar con una cinta, definir transiciones y realizar operaciones básicas propias de una máquina de Turing.
HTML: Define la estructura de la página web, incluyendo la cinta, los controles de interacción y un modal para definir transiciones.
CSS: Establece los estilos visuales de la página, incluyendo la apariencia de la cinta, los botones y el diseño general de la interfaz.
JavaScript: Contiene la lógica para el funcionamiento interactivo de la máquina de Turing, incluyendo la manipulación de la cinta, los movimientos, la modificación de símbolos y la definición de transiciones.
Interacción con la Cinta: Permite agregar y eliminar símbolos en la cinta, así como moverse hacia la izquierda o derecha en la cinta.
Cambio de Símbolos: Permite cambiar el símbolo actual en la posición de la cinta y ejecutar la transición definida para ese estado y símbolo.
Definición de Transiciones: Abre un modal que permite al usuario definir transiciones para la máquina de Turing, especificando el nuevo estado, el símbolo leído, el símbolo a escribir y el movimiento a realizar (izquierda o derecha).
addSymbol(), removeSymbol(), move(): Gestiona la adición, eliminación y movimiento en la cinta respectivamente.
changeSymbol(): Modifica el símbolo actual en la cinta y ejecuta la transición definida para ese estado y símbolo.
openTransitionModal(), closeTransitionModal(), setTransition(): Gestionan la apertura y cierre del modal para definir transiciones, así como la definición de las mismas.
<!DOCTYPE html>
<html>
<head>
<title>Máquina de Turing</title>
<style>
body {
font-family: 'Roboto Mono', monospace;
text-align: center;
background-color: #f7f7f7;
margin: 50px auto 0;
padding: 30px;
min-height: 100vh;
box-sizing: border-box;
color: #0041a5;
}
.title {
font-size: 36px;
font-weight: bold;
margin-top: 30px;
}
.subtitle {
font-size: 24px;
margin-bottom: 20px;
}
.machine {
margin-top: 30px;
}
.tape-container {
display: flex;
align-items: center;
justify-content: center;
border: 1px solid #ccc;
padding: 20px;
margin-bottom: 40px;
overflow-x: auto;
width: 80%;
margin: auto;
background-color: #fff;
border-radius: 10px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.tape {
display: flex;
border: 1px solid #999;
padding: 20px;
overflow: hidden;
flex-wrap: nowrap;
}
.symbol {
width: 60px;
height: 60px;
border: 1px solid #999;
display: flex;
align-items: center;
justify-content: center;
margin: 0 3px;
transition: background-color 0.3s ease;
font-size: 20px;
}
.controls {
margin-bottom: 40px;
}
.controls label {
font-size: 18px;
margin-right: 10px;
}
.controls input[type="text"] {
padding: 8px;
font-size: 16px;
border-radius: 5px;
border: 1px solid #ccc;
}
.controls button {
margin: 10px;
padding: 12px 30px;
font-size: 18px;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s ease;
color: #fff;
background-color: #3498db;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.controls button:hover {
background-color: #2980b9;
}
.current-symbol {
background-color: #ffa500;
}
/* Estilos para el modal */
.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0,0,0,0.4);
}
.modal-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 60%;
border-radius: 5px;
}
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
</style>
</head>
<body>
<div class="title">Máquina de Turing</div>
<div class="subtitle">Simulación interactiva</div>
<div class="machine">
<p>
Utiliza los botones para interactuar con la cinta y definir transiciones.
Puedes agregar y eliminar símbolos, moverte en la cinta, cambiar símbolos y definir transiciones.
</p>
<div class="tape-container">
<div class="tape" id="tape"></div>
</div>
<div class="controls">
<label for="newSymbol">Nuevo Símbolo:</label>
<input type="text" id="newSymbol" maxlength="1">
<button onclick="addSymbol()"><span class="icon">➕</span>Agregar Símbolo</button>
<button onclick="removeSymbol()"><span class="icon">➖</span>Eliminar Símbolo</button>
<button onclick="move('L')"><span class="icon">⬅️</span>Izquierda</button>
<button onclick="move('R')"><span class="icon">➡️</span>Derecha</button>
<button onclick="changeSymbol()"><span class="icon">✏️</span>Cambiar Símbolo</button>
<button onclick="openTransitionModal()"><span class="icon">⚙️</span>Definir Transición</button>
</div>
</div>
<!-- Modal para definir transiciones -->
<div id="transitionModal" class="modal">
<div class="modal-content">
<span class="close" onclick="closeTransitionModal()">×</span>
<label for="newState">Nuevo Estado:</label>
<input type="text" id="newState" placeholder="Nuevo estado (Ejemplo: B)"><br>
<label for="newSymbolTransition">Símbolo:</label>
<input type="text" id="newSymbolTransition" maxlength="1" placeholder="Símbolo leído"><br>
<label for="newSymbolWrite">Símbolo a escribir:</label>
<input type="text" id="newSymbolWrite" maxlength="1" placeholder="Nuevo símbolo"><br>
<label for="newMove">Movimiento (L/R):</label>
<select id="newMove">
<option value="L">L (Izquierda)</option>
<option value="R">R (Derecha)</option>
</select><br>
<button onclick="setTransition()">Definir Transición</button>
</div>
</div>
<script>
let tape = ['0', '1', '1', '0', '1']; // Ejemplo de cinta
let currentPosition = 0;
let currentState = 'A'; // Estado inicial
let tapeDiv = document.getElementById('tape');
let transitions = {};
function addSymbol() {
let newSymbol = document.getElementById('newSymbol').value;
if (newSymbol) {
tape.splice(currentPosition + 1, 0, newSymbol);
updateTapeDisplay();
}
}
function removeSymbol() {
if (tape.length > 1) {
tape.splice(currentPosition, 1);
if (currentPosition >= tape.length) {
currentPosition = tape.length - 1;
}
updateTapeDisplay();
}
}
function move(direction) {
if (direction === 'L' && currentPosition > 0) {
currentPosition--;
} else if (direction === 'R' && currentPosition < tape.length - 1) {
currentPosition++;
}
updateTapeDisplay();
}
function changeSymbol() {
let inputSymbol = tape[currentPosition];
let transition = transitions[currentState]?.[inputSymbol];
if (transition) {
tape[currentPosition] = transition.write;
if (transition.move === 'R') {
currentPosition = Math.min(currentPosition + 1, tape.length - 1);
} else if (transition.move === 'L') {
currentPosition = Math.max(currentPosition - 1, 0);
}
currentState = transition.newState;
updateTapeDisplay();
} else {
alert('No hay transición definida para el estado y símbolo actuales.');
}
}
function openTransitionModal() {
document.getElementById('transitionModal').style.display = 'block';
}
function closeTransitionModal() {
document.getElementById('transitionModal').style.display = 'none';
}
function setTransition() {
let newSymbol = document.getElementById('newSymbolTransition').value;
let newState = document.getElementById('newState').value;
let writeSymbol = document.getElementById('newSymbolWrite').value;
let move = document.getElementById('newMove').value;
if (newSymbol && newState && writeSymbol && (move === 'L' || move === 'R')) {
if (!transitions[currentState]) {
transitions[currentState] = {};
}
transitions[currentState][newSymbol] = {
write: writeSymbol,
move: move,
newState: newState
};
alert('Transición definida correctamente.');
closeTransitionModal();
} else {
alert('Ingresa correctamente los valores para definir la transición.');
}
}
function updateTapeDisplay() {
tapeDiv.innerHTML = '';
tape.forEach((symbol, index) => {
let symbolDiv = document.createElement('div');
symbolDiv.className = 'symbol';
symbolDiv.textContent = symbol;
if (index === currentPosition) {
symbolDiv.classList.add('current-symbol');
}
tapeDiv.appendChild(symbolDiv);
});
}
updateTapeDisplay(); // Actualizar visualización inicial
</script>
</body>
</html>