chess / index.html
openfree's picture
Update index.html
86fdb32 verified
raw
history blame
14.2 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Perceptron Passive Radar</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: monospace;
}
body {
background: #001;
color: #0f8;
min-height: 100vh;
overflow: hidden;
}
.main-container {
display: grid;
grid-template-columns: 1fr 400px;
gap: 10px;
padding: 10px;
height: 100vh;
}
.radar-container {
position: relative;
border: 2px solid #0f8;
border-radius: 50%;
background: radial-gradient(circle, rgba(0,255,136,0.05) 0%, rgba(0,0,0,0.9) 100%);
overflow: hidden;
}
.sweep-line {
position: absolute;
top: 50%;
left: 50%;
width: 50%;
height: 2px;
background: linear-gradient(90deg, #0f8, transparent);
transform-origin: left;
animation: radar-sweep 4s linear infinite;
}
.grid-overlay {
position: absolute;
width: 100%;
height: 100%;
background:
linear-gradient(#0f81 1px, transparent 1px),
linear-gradient(90deg, #0f81 1px, transparent 1px);
background-size: 50px 50px;
}
@keyframes radar-sweep {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.control-panel {
display: flex;
flex-direction: column;
gap: 10px;
}
.panel {
background: rgba(0,255,136,0.1);
border: 1px solid #0f8;
padding: 10px;
}
.perceptron-layer {
display: flex;
justify-content: space-between;
align-items: center;
height: 200px;
margin: 10px 0;
position: relative;
}
.layer {
display: flex;
flex-direction: column;
gap: 4px;
}
.neuron {
width: 12px;
height: 12px;
background: #0f8;
border-radius: 50%;
position: relative;
opacity: 0.3;
transition: all 0.2s;
}
.neuron.active {
opacity: 1;
box-shadow: 0 0 10px #0f8;
}
.connections {
position: absolute;
width: 100%;
height: 100%;
pointer-events: none;
}
.spectrum {
height: 120px;
display: flex;
align-items: flex-end;
gap: 2px;
}
.bar {
flex: 1;
background: #0f8;
transition: height 0.1s;
}
.signal {
position: absolute;
width: 8px;
height: 8px;
background: #0f8;
border-radius: 50%;
transform: translate(-50%, -50%);
}
.signal-echo {
position: absolute;
border: 1px solid #0f8;
border-radius: 50%;
transform: translate(-50%, -50%);
animation: echo 2s ease-out forwards;
}
@keyframes echo {
0% {
width: 8px;
height: 8px;
opacity: 1;
}
100% {
width: 60px;
height: 60px;
opacity: 0;
}
}
button {
background: transparent;
border: 1px solid #0f8;
color: #0f8;
padding: 8px;
cursor: pointer;
transition: 0.3s;
}
button:hover {
background: #0f8;
color: #001;
}
.stats {
font-size: 12px;
line-height: 1.5;
}
canvas {
margin-top: 10px;
border: 1px solid #0f8;
}
</style>
</head>
<body>
<div class="main-container">
<div class="radar-container">
<div class="grid-overlay"></div>
<div class="sweep-line"></div>
<div id="signals"></div>
</div>
<div class="control-panel">
<div class="panel">
<h3>Perceptron Network</h3>
<div class="perceptron-layer">
<canvas id="networkCanvas"></canvas>
</div>
<div class="stats" id="networkStats">
Accuracy: 0%<br>
Detections: 0<br>
Signal Strength: 0
</div>
</div>
<div class="panel">
<h3>Frequency Analysis</h3>
<div class="spectrum" id="spectrum"></div>
</div>
<div class="panel">
<button onclick="startRadar()">Start Detection</button>
<button onclick="stopRadar()">Stop</button>
<button onclick="trainPerceptrons()">Train Network</button>
<button onclick="toggleLearning()">Toggle Learning</button>
</div>
</div>
</div>
<script>
class Perceptron {
constructor(inputs) {
this.weights = new Array(inputs).fill(0).map(() => Math.random() * 2 - 1);
this.bias = Math.random() * 2 - 1;
this.learningRate = 0.1;
}
activate(sum) {
return sum > 0 ? 1 : 0;
}
predict(inputs) {
const sum = inputs.reduce((sum, input, i) => sum + input * this.weights[i], 0) + this.bias;
return this.activate(sum);
}
train(inputs, target) {
const prediction = this.predict(inputs);
const error = target - prediction;
for(let i = 0; i < this.weights.length; i++) {
this.weights[i] += error * inputs[i] * this.learningRate;
}
this.bias += error * this.learningRate;
return Math.abs(error);
}
}
class PerceptronNetwork {
constructor(inputSize, hiddenSize, outputSize) {
this.inputLayer = new Array(hiddenSize)
.fill(0)
.map(() => new Perceptron(inputSize));
this.outputLayer = new Array(outputSize)
.fill(0)
.map(() => new Perceptron(hiddenSize));
}
predict(inputs) {
const hiddenOutputs = this.inputLayer.map(p => p.predict(inputs));
return this.outputLayer.map(p => p.predict(hiddenOutputs));
}
train(inputs, targets) {
const hiddenOutputs = this.inputLayer.map(p => p.predict(inputs));
const finalOutputs = this.outputLayer.map(p => p.predict(hiddenOutputs));
let error = 0;
this.outputLayer.forEach((p, i) => {
error += p.train(hiddenOutputs, targets[i]);
});
this.inputLayer.forEach(p => {
error += p.train(inputs, 1);
});
return error / (this.inputLayer.length + this.outputLayer.length);
}
}
// Initialize system
const INPUT_SIZE = 32;
const HIDDEN_SIZE = 16;
const OUTPUT_SIZE = 4;
let isRunning = false;
let isLearning = false;
let network = new PerceptronNetwork(INPUT_SIZE, HIDDEN_SIZE, OUTPUT_SIZE);
let audioContext, analyser, dataArray;
// Setup UI
const spectrum = document.getElementById('spectrum');
for(let i = 0; i < INPUT_SIZE; i++) {
const bar = document.createElement('div');
bar.className = 'bar';
spectrum.appendChild(bar);
}
// Setup canvas
const canvas = document.getElementById('networkCanvas');
canvas.width = 350;
canvas.height = 180;
const ctx = canvas.getContext('2d');
function drawNetwork(inputs, hiddenOutputs, finalOutputs) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.strokeStyle = '#0f8';
ctx.lineWidth = 0.5;
const drawLayer = (nodes, x, active) => {
const spacing = canvas.height / (nodes.length + 1);
return nodes.map((value, i) => {
const y = spacing * (i + 1);
ctx.beginPath();
ctx.arc(x, y, 4, 0, Math.PI * 2);
ctx.fillStyle = `rgba(0,255,136,${active ? value : 0.3})`;
ctx.fill();
return {x, y};
});
};
const inputNodes = drawLayer(inputs, 30, true);
const hiddenNodes = drawLayer(hiddenOutputs, canvas.width/2, true);
const outputNodes = drawLayer(finalOutputs, canvas.width - 30, true);
// Draw connections
ctx.beginPath();
inputNodes.forEach(input => {
hiddenNodes.forEach(hidden => {
ctx.moveTo(input.x, input.y);
ctx.lineTo(hidden.x, hidden.y);
});
});
hiddenNodes.forEach(hidden => {
outputNodes.forEach(output => {
ctx.moveTo(hidden.x, hidden.y);
ctx.lineTo(output.x, output.y);
});
});
ctx.stroke();
}
async function startRadar() {
try {
if(!audioContext) {
audioContext = new (window.AudioContext || window.webkitAudioContext)();
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const source = audioContext.createMediaStreamSource(stream);
analyser = audioContext.createAnalyser();
analyser.fftSize = 64;
source.connect(analyser);
dataArray = new Uint8Array(analyser.frequencyBinCount);
}
isRunning = true;
updateRadar();
} catch(err) {
console.error('Error accessing microphone:', err);
}
}
function stopRadar() {
isRunning = false;
}
function updateRadar() {
if(!isRunning) return;
analyser.getByteFrequencyData(dataArray);
// Update spectrum
const bars = spectrum.children;
for(let i = 0; i < bars.length; i++) {
const height = (dataArray[i] / 255) * 120;
bars[i].style.height = height + 'px';
}
// Normalize input data
const inputs = Array.from(dataArray).map(x => x / 255);
// Get network predictions
const hiddenOutputs = network.inputLayer.map(p => p.predict(inputs));
const outputs = network.outputLayer.map(p => p.predict(hiddenOutputs));
// Draw network state
drawNetwork(inputs, hiddenOutputs, outputs);
// Create signals for strong predictions
outputs.forEach((output, i) => {
if(output > 0.7) {
createSignal(i);
}
});
// Update stats
const avgOutput = outputs.reduce((a,b) => a+b) / outputs.length;
document.getElementById('networkStats').innerHTML =
`Accuracy: ${Math.round(avgOutput * 100)}%<br>` +
`Detections: ${outputs.filter(x => x > 0.7).length}<br>` +
`Signal Strength: ${Math.round(inputs.reduce((a,b) => a+b) / inputs.length * 100)}`;
if(isLearning) {
const target = Array(OUTPUT_SIZE).fill(0);
target[Math.floor(Math.random() * OUTPUT_SIZE)] = 1;
network.train(inputs, target);
}
requestAnimationFrame(updateRadar);
}
function createSignal(type) {
const radar = document.querySelector('.radar-container');
const angle = Math.random() * Math.PI * 2;
const distance = Math.random() * (radar.offsetWidth / 3);
const x = Math.cos(angle) * distance + radar.offsetWidth / 2;
const y = Math.sin(angle) * distance + radar.offsetHeight / 2;
const signal = document.createElement('div');
signal.className = 'signal';
signal.style.left = x + 'px';
signal.style.top = y + 'px';
radar.appendChild(signal);
const echo = document.createElement('div');
echo.className = 'signal-echo';
echo.style.left = x + 'px';
echo.style.top = y + 'px';
radar.appendChild(echo);
setTimeout(() => {
signal.remove();
echo.remove();
}, 2000);
}
function trainPerceptrons() {
let error = 0;
for(let i = 0; i < 100; i++) {
const inputs = Array(INPUT_SIZE).fill(0).map(() => Math.random());
const targets = Array(OUTPUT_SIZE).fill(0);
targets[Math.floor(Math.random() * OUTPUT_SIZE)] = 1;
error += network.train(inputs, targets);
}
document.getElementById('networkStats').innerHTML =
`Training complete<br>Error: ${Math.round(error * 100) / 100}<br>Network ready`;
}
function toggleLearning() {
isLearning = !isLearning;
}
</script>
</body>
</html>