XTaylorSpenceX

Byte-Sized Universe Birth

Sep 23rd, 2025
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 20.84 KB | None | 0 0
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     <title>Byte-Sized Universe Birth</title>
  7.     <style>
  8.         * {
  9.             margin: 0;
  10.             padding: 0;
  11.             box-sizing: border-box;
  12.         }
  13.  
  14.         body {
  15.             font-family: 'Courier New', monospace;
  16.             background: linear-gradient(135deg, #000428 0%, #004e92 100%);
  17.             color: #e0f7fa;
  18.             display: flex;
  19.             justify-content: center;
  20.             align-items: center;
  21.             min-height: 100vh;
  22.             overflow: hidden;
  23.         }
  24.  
  25.         .container {
  26.             text-align: center;
  27.             padding: 20px;
  28.             background: rgba(0, 0, 0, 0.7);
  29.             border-radius: 20px;
  30.             box-shadow: 0 0 40px rgba(0, 255, 255, 0.3);
  31.         }
  32.  
  33.         h1 {
  34.             font-size: 2.5em;
  35.             margin-bottom: 10px;
  36.             background: linear-gradient(45deg, #00ffff, #ff00ff, #ffff00);
  37.             -webkit-background-clip: text;
  38.             -webkit-text-fill-color: transparent;
  39.             animation: glow 3s ease-in-out infinite;
  40.         }
  41.  
  42.         @keyframes glow {
  43.             0%, 100% { filter: brightness(1); }
  44.             50% { filter: brightness(1.3); }
  45.         }
  46.  
  47.         .subtitle {
  48.             color: #80deea;
  49.             margin-bottom: 20px;
  50.             font-size: 0.9em;
  51.         }
  52.  
  53.         canvas {
  54.             border: 2px solid #00ffff;
  55.             border-radius: 10px;
  56.             cursor: crosshair;
  57.             box-shadow: 0 0 20px rgba(0, 255, 255, 0.5);
  58.             image-rendering: pixelated;
  59.             image-rendering: crisp-edges;
  60.         }
  61.  
  62.         .controls {
  63.             margin-top: 20px;
  64.             display: flex;
  65.             gap: 15px;
  66.             justify-content: center;
  67.             flex-wrap: wrap;
  68.         }
  69.  
  70.         button {
  71.             padding: 10px 20px;
  72.             background: linear-gradient(45deg, #1a237e, #3949ab);
  73.             color: #fff;
  74.             border: none;
  75.             border-radius: 25px;
  76.             cursor: pointer;
  77.             font-size: 14px;
  78.             transition: all 0.3s;
  79.             box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
  80.         }
  81.  
  82.         button:hover {
  83.             transform: translateY(-2px);
  84.             box-shadow: 0 6px 20px rgba(0, 255, 255, 0.4);
  85.             background: linear-gradient(45deg, #283593, #5c6bc0);
  86.         }
  87.  
  88.         button:active {
  89.             transform: translateY(0);
  90.         }
  91.  
  92.         .info {
  93.             margin-top: 20px;
  94.             display: grid;
  95.             grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  96.             gap: 10px;
  97.             font-size: 12px;
  98.         }
  99.  
  100.         .info-item {
  101.             padding: 8px;
  102.             background: rgba(255, 255, 255, 0.1);
  103.             border-radius: 10px;
  104.             border: 1px solid rgba(0, 255, 255, 0.3);
  105.         }
  106.  
  107.         .info-label {
  108.             color: #80deea;
  109.             display: block;
  110.             margin-bottom: 3px;
  111.         }
  112.  
  113.         .info-value {
  114.             color: #ffff00;
  115.             font-weight: bold;
  116.             font-size: 16px;
  117.         }
  118.  
  119.         .preset-seeds {
  120.             margin-top: 15px;
  121.             display: flex;
  122.             gap: 10px;
  123.             justify-content: center;
  124.             flex-wrap: wrap;
  125.         }
  126.  
  127.         .preset-btn {
  128.             padding: 5px 12px;
  129.             font-size: 12px;
  130.             background: linear-gradient(45deg, #00695c, #00897b);
  131.         }
  132.  
  133.         .preset-btn:hover {
  134.             background: linear-gradient(45deg, #00796b, #009688);
  135.         }
  136.  
  137.         .speed-control {
  138.             margin-top: 15px;
  139.             display: flex;
  140.             align-items: center;
  141.             justify-content: center;
  142.             gap: 10px;
  143.         }
  144.  
  145.         input[type="range"] {
  146.             width: 150px;
  147.             height: 5px;
  148.             background: rgba(255, 255, 255, 0.2);
  149.             outline: none;
  150.             border-radius: 5px;
  151.         }
  152.  
  153.         input[type="range"]::-webkit-slider-thumb {
  154.             appearance: none;
  155.             width: 15px;
  156.             height: 15px;
  157.             background: #00ffff;
  158.             cursor: pointer;
  159.             border-radius: 50%;
  160.             box-shadow: 0 0 10px rgba(0, 255, 255, 0.8);
  161.         }
  162.  
  163.         .legend {
  164.             margin-top: 15px;
  165.             font-size: 11px;
  166.             display: flex;
  167.             gap: 15px;
  168.             justify-content: center;
  169.             flex-wrap: wrap;
  170.         }
  171.  
  172.         .legend-item {
  173.             display: flex;
  174.             align-items: center;
  175.             gap: 5px;
  176.         }
  177.  
  178.         .color-box {
  179.             width: 15px;
  180.             height: 15px;
  181.             border-radius: 3px;
  182.             border: 1px solid rgba(255, 255, 255, 0.3);
  183.         }
  184.     </style>
  185. </head>
  186. <body>
  187.     <div class="container">
  188.         <h1>Byte-Sized Universe Birth</h1>
  189.         <div class="subtitle">Click to seed • Watch galaxies bloom • Entropy awaits</div>
  190.        
  191.         <canvas id="universe"></canvas>
  192.        
  193.         <div class="controls">
  194.             <button id="clearBtn">Clear Universe</button>
  195.             <button id="randomBtn">Random Seed</button>
  196.             <button id="pauseBtn">Pause</button>
  197.             <button id="stepBtn">Single Step</button>
  198.         </div>
  199.  
  200.         <div class="preset-seeds">
  201.             <button class="preset-btn" data-preset="glider">Glider</button>
  202.             <button class="preset-btn" data-preset="pulsar">Pulsar</button>
  203.             <button class="preset-btn" data-preset="galaxy">Galaxy</button>
  204.             <button class="preset-btn" data-preset="nebula">Nebula</button>
  205.             <button class="preset-btn" data-preset="supernova">Supernova</button>
  206.         </div>
  207.  
  208.         <div class="speed-control">
  209.             <span>Speed:</span>
  210.             <input type="range" id="speedSlider" min="1" max="20" value="10">
  211.             <span id="speedValue">10</span>
  212.         </div>
  213.  
  214.         <div class="info">
  215.             <div class="info-item">
  216.                 <span class="info-label">Generation</span>
  217.                 <span class="info-value" id="generation">0</span>
  218.             </div>
  219.             <div class="info-item">
  220.                 <span class="info-label">Active Bytes</span>
  221.                 <span class="info-value" id="population">0</span>
  222.             </div>
  223.             <div class="info-item">
  224.                 <span class="info-label">Entropy</span>
  225.                 <span class="info-value" id="entropy">0%</span>
  226.             </div>
  227.             <div class="info-item">
  228.                 <span class="info-label">Peak Bytes</span>
  229.                 <span class="info-value" id="peak">0</span>
  230.             </div>
  231.         </div>
  232.  
  233.         <div class="legend">
  234.             <div class="legend-item">
  235.                 <div class="color-box" style="background: #00ffff;"></div>
  236.                 <span>Young Star</span>
  237.             </div>
  238.             <div class="legend-item">
  239.                 <div class="color-box" style="background: #ff00ff;"></div>
  240.                 <span>Nebula</span>
  241.             </div>
  242.             <div class="legend-item">
  243.                 <div class="color-box" style="background: #ffff00;"></div>
  244.                 <span>Supernova</span>
  245.             </div>
  246.             <div class="legend-item">
  247.                 <div class="color-box" style="background: #ff6b6b;"></div>
  248.                 <span>Red Giant</span>
  249.             </div>
  250.         </div>
  251.     </div>
  252.  
  253.     <script>
  254.         const canvas = document.getElementById('universe');
  255.         const ctx = canvas.getContext('2d');
  256.        
  257.         const CELL_SIZE = 4;
  258.         const GRID_WIDTH = 150;
  259.         const GRID_HEIGHT = 100;
  260.        
  261.         canvas.width = GRID_WIDTH * CELL_SIZE;
  262.         canvas.height = GRID_HEIGHT * CELL_SIZE;
  263.        
  264.         let grid = [];
  265.         let nextGrid = [];
  266.         let generation = 0;
  267.         let population = 0;
  268.         let peakPopulation = 0;
  269.         let isPaused = false;
  270.         let speed = 10;
  271.         let entropyLevel = 0;
  272.         let cellAge = [];
  273.        
  274.         // Initialize grids
  275.         function initializeGrid() {
  276.             grid = Array(GRID_HEIGHT).fill().map(() => Array(GRID_WIDTH).fill(0));
  277.             nextGrid = Array(GRID_HEIGHT).fill().map(() => Array(GRID_WIDTH).fill(0));
  278.             cellAge = Array(GRID_HEIGHT).fill().map(() => Array(GRID_WIDTH).fill(0));
  279.             generation = 0;
  280.             population = 0;
  281.             peakPopulation = 0;
  282.             entropyLevel = 0;
  283.             updateStats();
  284.         }
  285.        
  286.         // Count neighbors with different weights for varied patterns
  287.         function countNeighbors(x, y) {
  288.             let count = 0;
  289.             let pattern = { young: 0, old: 0, dying: 0 };
  290.            
  291.             for (let dy = -1; dy <= 1; dy++) {
  292.                for (let dx = -1; dx <= 1; dx++) {
  293.                    if (dx === 0 && dy === 0) continue;
  294.                    
  295.                    const nx = (x + dx + GRID_WIDTH) % GRID_WIDTH;
  296.                    const ny = (y + dy + GRID_HEIGHT) % GRID_HEIGHT;
  297.                    
  298.                    if (grid[ny][nx] === 1) {
  299.                        count++;
  300.                        const age = cellAge[ny][nx];
  301.                        if (age < 5) pattern.young++;
  302.                        else if (age < 15) pattern.old++;
  303.                        else pattern.dying++;
  304.                    }
  305.                }
  306.            }
  307.            
  308.            return { count, pattern };
  309.        }
  310.        
  311.        // Update rules with entropy and varied evolution
  312.        function updateCell(x, y) {
  313.            const { count, pattern } = countNeighbors(x, y);
  314.            const current = grid[y][x];
  315.            const age = cellAge[y][x];
  316.            
  317.            // Add entropy factor
  318.            const entropyFactor = Math.random() < (entropyLevel / 1000);
  319.            
  320.            if (current === 1) {
  321.                // Living cell rules
  322.                cellAge[y][x]++;
  323.                
  324.                // Death by entropy or age
  325.                if (entropyFactor || age > 30) {
  326.                     return 0;
  327.                 }
  328.                
  329.                 // Classic Conway rules with modifications
  330.                 if (count < 2 || count > 3) {
  331.                     // Higher chance of survival if surrounded by young cells
  332.                     if (pattern.young >= 2 && Math.random() < 0.3) {
  333.                        return 1;
  334.                     }
  335.                     return 0;
  336.                 }
  337.                
  338.                 return 1;
  339.             } else {
  340.                 // Dead cell rules
  341.                 if (count === 3) {
  342.                     cellAge[y][x] = 0;
  343.                     return 1;
  344.                 } else if (count === 2 && pattern.young >= 2 && Math.random() < 0.1) {
  345.                    // Small chance of spontaneous birth near young cells
  346.                    cellAge[y][x] = 0;
  347.                     return 1;
  348.                 }
  349.                
  350.                 return 0;
  351.             }
  352.         }
  353.        
  354.         // Single evolution step
  355.         function evolve() {
  356.             population = 0;
  357.            
  358.             for (let y = 0; y < GRID_HEIGHT; y++) {
  359.                for (let x = 0; x < GRID_WIDTH; x++) {
  360.                    nextGrid[y][x] = updateCell(x, y);
  361.                    if (nextGrid[y][x] === 1) population++;
  362.                }
  363.            }
  364.            
  365.            // Swap grids
  366.            [grid, nextGrid] = [nextGrid, grid];
  367.            
  368.            generation++;
  369.            entropyLevel = Math.min(100, generation * 0.5 + (peakPopulation - population) * 0.1);
  370.            
  371.            if (population > peakPopulation) {
  372.                 peakPopulation = population;
  373.             }
  374.            
  375.             updateStats();
  376.         }
  377.        
  378.         // Get color based on cell age and state
  379.         function getCellColor(x, y) {
  380.             if (grid[y][x] === 0) return null;
  381.            
  382.             const age = cellAge[y][x];
  383.            
  384.             if (age < 3) {
  385.                return '#00ffff'; // Young star - cyan
  386.            } else if (age < 8) {
  387.                return '#ff00ff'; // Nebula - magenta
  388.            } else if (age < 15) {
  389.                return '#ffff00'; // Supernova - yellow
  390.            } else if (age < 25) {
  391.                return '#ff6b6b'; // Red giant
  392.            } else {
  393.                return '#4a148c'; // Dying star - deep purple
  394.            }
  395.        }
  396.        
  397.        // Draw the universe
  398.        function draw() {
  399.            ctx.fillStyle = '#000014';
  400.            ctx.fillRect(0, 0, canvas.width, canvas.height);
  401.            
  402.            // Draw grid lines (subtle)
  403.            ctx.strokeStyle = 'rgba(255, 255, 255, 0.03)';
  404.            ctx.lineWidth = 0.5;
  405.            
  406.            for (let x = 0; x <= GRID_WIDTH; x++) {
  407.                ctx.beginPath();
  408.                ctx.moveTo(x * CELL_SIZE, 0);
  409.                ctx.lineTo(x * CELL_SIZE, canvas.height);
  410.                ctx.stroke();
  411.            }
  412.            
  413.            for (let y = 0; y <= GRID_HEIGHT; y++) {
  414.                ctx.beginPath();
  415.                ctx.moveTo(0, y * CELL_SIZE);
  416.                ctx.lineTo(canvas.width, y * CELL_SIZE);
  417.                ctx.stroke();
  418.            }
  419.            
  420.            // Draw cells with glow effect
  421.            for (let y = 0; y < GRID_HEIGHT; y++) {
  422.                for (let x = 0; x < GRID_WIDTH; x++) {
  423.                    const color = getCellColor(x, y);
  424.                    if (color) {
  425.                        // Add glow
  426.                        const age = cellAge[y][x];
  427.                        const glowSize = age < 5 ? 2 : 1;
  428.                        
  429.                        ctx.shadowColor = color;
  430.                        ctx.shadowBlur = glowSize * 2;
  431.                        
  432.                        ctx.fillStyle = color;
  433.                        ctx.fillRect(
  434.                            x * CELL_SIZE,
  435.                            y * CELL_SIZE,
  436.                            CELL_SIZE,
  437.                            CELL_SIZE
  438.                        );
  439.                        
  440.                        ctx.shadowBlur = 0;
  441.                    }
  442.                }
  443.            }
  444.        }
  445.        
  446.        // Update statistics
  447.        function updateStats() {
  448.            document.getElementById('generation').textContent = generation;
  449.            document.getElementById('population').textContent = population;
  450.            document.getElementById('entropy').textContent = Math.floor(entropyLevel) + '%';
  451.            document.getElementById('peak').textContent = peakPopulation;
  452.        }
  453.        
  454.        // Preset patterns
  455.        const presets = {
  456.            glider: [
  457.                [0, 1], [1, 2], [2, 0], [2, 1], [2, 2]
  458.            ],
  459.            pulsar: [
  460.                [2,4],[2,5],[2,6],[2,10],[2,11],[2,12],
  461.                [4,2],[5,2],[6,2],[4,7],[5,7],[6,7],[4,9],[5,9],[6,9],[4,14],[5,14],[6,14],
  462.                [7,4],[7,5],[7,6],[7,10],[7,11],[7,12],
  463.                [9,4],[9,5],[9,6],[9,10],[9,11],[9,12],
  464.                [10,2],[11,2],[12,2],[10,7],[11,7],[12,7],[10,9],[11,9],[12,9],[10,14],[11,14],[12,14],
  465.                [14,4],[14,5],[14,6],[14,10],[14,11],[14,12]
  466.            ],
  467.            galaxy: function() {
  468.                const pattern = [];
  469.                for (let i = 0; i < 50; i++) {
  470.                    const angle = (i / 50) * Math.PI * 2;
  471.                    const radius = i * 0.5;
  472.                    const x = Math.floor(GRID_WIDTH / 2 + Math.cos(angle) * radius);
  473.                    const y = Math.floor(GRID_HEIGHT / 2 + Math.sin(angle) * radius);
  474.                    if (x >= 0 && x < GRID_WIDTH && y >= 0 && y < GRID_HEIGHT) {
  475.                        pattern.push([y, x]);
  476.                     }
  477.                 }
  478.                 return pattern;
  479.             },
  480.             nebula: function() {
  481.                 const pattern = [];
  482.                 const cx = GRID_WIDTH / 2;
  483.                 const cy = GRID_HEIGHT / 2;
  484.                 for (let i = 0; i < 100; i++) {
  485.                    const angle = Math.random() * Math.PI * 2;
  486.                    const radius = Math.random() * 20;
  487.                    const x = Math.floor(cx + Math.cos(angle) * radius);
  488.                    const y = Math.floor(cy + Math.sin(angle) * radius);
  489.                    if (x >= 0 && x < GRID_WIDTH && y >= 0 && y < GRID_HEIGHT) {
  490.                        pattern.push([y, x]);
  491.                     }
  492.                 }
  493.                 return pattern;
  494.             },
  495.             supernova: function() {
  496.                 const pattern = [];
  497.                 const cx = GRID_WIDTH / 2;
  498.                 const cy = GRID_HEIGHT / 2;
  499.                 for (let r = 5; r < 15; r += 3) {
  500.                    for (let a = 0; a < Math.PI * 2; a += 0.3) {
  501.                        const x = Math.floor(cx + Math.cos(a) * r);
  502.                        const y = Math.floor(cy + Math.sin(a) * r);
  503.                        if (x >= 0 && x < GRID_WIDTH && y >= 0 && y < GRID_HEIGHT) {
  504.                            pattern.push([y, x]);
  505.                         }
  506.                     }
  507.                 }
  508.                 return pattern;
  509.             }
  510.         };
  511.        
  512.         // Place preset pattern
  513.         function placePreset(name) {
  514.             initializeGrid();
  515.             const pattern = typeof presets[name] === 'function' ? presets[name]() : presets[name];
  516.            
  517.             const offsetX = Math.floor((GRID_WIDTH - 20) / 2);
  518.             const offsetY = Math.floor((GRID_HEIGHT - 20) / 2);
  519.            
  520.             for (const [y, x] of pattern) {
  521.                 const nx = x + offsetX;
  522.                 const ny = y + offsetY;
  523.                 if (nx >= 0 && nx < GRID_WIDTH && ny >= 0 && ny < GRID_HEIGHT) {
  524.                    grid[ny][nx] = 1;
  525.                     cellAge[ny][nx] = 0;
  526.                 }
  527.             }
  528.            
  529.             draw();
  530.         }
  531.        
  532.         // Canvas click handler
  533.         canvas.addEventListener('click', (e) => {
  534.             const rect = canvas.getBoundingClientRect();
  535.             const x = Math.floor((e.clientX - rect.left) / CELL_SIZE);
  536.             const y = Math.floor((e.clientY - rect.top) / CELL_SIZE);
  537.            
  538.             // Create a small cluster for better effect
  539.             for (let dy = -1; dy <= 1; dy++) {
  540.                for (let dx = -1; dx <= 1; dx++) {
  541.                    const nx = x + dx;
  542.                    const ny = y + dy;
  543.                    if (nx >= 0 && nx < GRID_WIDTH && ny >= 0 && ny < GRID_HEIGHT) {
  544.                        if (Math.random() < 0.6) {
  545.                            grid[ny][nx] = 1;
  546.                             cellAge[ny][nx] = 0;
  547.                         }
  548.                     }
  549.                 }
  550.             }
  551.            
  552.             draw();
  553.         });
  554.        
  555.         // Control buttons
  556.         document.getElementById('clearBtn').addEventListener('click', () => {
  557.             initializeGrid();
  558.             draw();
  559.         });
  560.        
  561.         document.getElementById('randomBtn').addEventListener('click', () => {
  562.             initializeGrid();
  563.             for (let y = 0; y < GRID_HEIGHT; y++) {
  564.                for (let x = 0; x < GRID_WIDTH; x++) {
  565.                    if (Math.random() < 0.15) {
  566.                        grid[y][x] = 1;
  567.                        cellAge[y][x] = Math.floor(Math.random() * 5);
  568.                    }
  569.                }
  570.            }
  571.            draw();
  572.        });
  573.        
  574.        document.getElementById('pauseBtn').addEventListener('click', () => {
  575.             isPaused = !isPaused;
  576.             document.getElementById('pauseBtn').textContent = isPaused ? 'Resume' : 'Pause';
  577.         });
  578.        
  579.         document.getElementById('stepBtn').addEventListener('click', () => {
  580.             evolve();
  581.             draw();
  582.         });
  583.        
  584.         // Preset buttons
  585.         document.querySelectorAll('.preset-btn').forEach(btn => {
  586.             btn.addEventListener('click', (e) => {
  587.                 placePreset(e.target.dataset.preset);
  588.             });
  589.         });
  590.        
  591.         // Speed control
  592.         document.getElementById('speedSlider').addEventListener('input', (e) => {
  593.             speed = parseInt(e.target.value);
  594.             document.getElementById('speedValue').textContent = speed;
  595.         });
  596.        
  597.         // Animation loop
  598.         let frameCount = 0;
  599.         function animate() {
  600.             if (!isPaused) {
  601.                 frameCount++;
  602.                 if (frameCount >= (21 - speed)) {
  603.                     evolve();
  604.                     draw();
  605.                     frameCount = 0;
  606.                 }
  607.             }
  608.            
  609.             requestAnimationFrame(animate);
  610.         }
  611.        
  612.         // Initialize
  613.         initializeGrid();
  614.         draw();
  615.         animate();
  616.     </script>
  617. </body>
  618. </html>
  619.  
Advertisement
Add Comment
Please, Sign In to add comment