@hypersocial/cli-games 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -723,7 +723,7 @@ function run2048Game(terminal) {
723
723
  "\u2588 \u2588 \u2588\u2584\u2588 \u2588\u2580\u2588 \u2588\u2580\u2580 \u2588\u2580\u2588 \u2582\u2580\u2580\u2588 \u2580\u2580\u2588 \u2584 \u2588\u2580\u2580 \u2580\u2588\u2580",
724
724
  "\u2588\u2580\u2588 \u2588 \u2588\u2580\u2580 \u2588\u2588\u2584 \u2588\u2580\u2584 \u2584\u2580\u2580\u2584 \u2580\u2580\u2584 \u2588\u2580\u2584 \u2588\u2588\u2584 \u2588 "
725
725
  ];
726
- function spawnParticles2(x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
726
+ function spawnParticles3(x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
727
727
  for (let i = 0; i < count; i++) {
728
728
  const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
729
729
  const speed = 0.3 + Math.random() * 0.5;
@@ -743,12 +743,12 @@ function run2048Game(terminal) {
743
743
  const screenY = gridY * TILE_HEIGHT + TILE_HEIGHT / 2;
744
744
  const color = TILE_COLORS[value] || "\x1B[97m";
745
745
  const dataChars = ["\u2588", "\u2593", "\u2592", "\u2591", "\u25A0", "\u25A1"];
746
- spawnParticles2(screenX, screenY, 8, color, dataChars);
746
+ spawnParticles3(screenX, screenY, 8, color, dataChars);
747
747
  }
748
- function addScorePopup(x, y, text, color = "\x1B[1;33m") {
748
+ function addScorePopup2(x, y, text, color = "\x1B[1;33m") {
749
749
  scorePopups.push({ x, y, text, frames: 20, color });
750
750
  }
751
- function triggerShake(frames, intensity) {
751
+ function triggerShake2(frames, intensity) {
752
752
  shakeFrames = frames;
753
753
  shakeIntensity = intensity;
754
754
  }
@@ -814,7 +814,7 @@ function run2048Game(terminal) {
814
814
  for (let x = 0; x < GRID_SIZE; x++) {
815
815
  if (merged[x] && result[x] > 0) {
816
816
  spawnMergeParticles(x, y, result[x]);
817
- addScorePopup(x * TILE_WIDTH + TILE_WIDTH / 2, y * TILE_HEIGHT + 1, `+${result[x]}`, TILE_COLORS[result[x]]);
817
+ addScorePopup2(x * TILE_WIDTH + TILE_WIDTH / 2, y * TILE_HEIGHT + 1, `+${result[x]}`, TILE_COLORS[result[x]]);
818
818
  }
819
819
  }
820
820
  grid[y] = result;
@@ -830,7 +830,7 @@ function run2048Game(terminal) {
830
830
  for (let x = 0; x < GRID_SIZE; x++) {
831
831
  if (finalMerged[x] && finalRow[x] > 0) {
832
832
  spawnMergeParticles(x, y, finalRow[x]);
833
- addScorePopup(x * TILE_WIDTH + TILE_WIDTH / 2, y * TILE_HEIGHT + 1, `+${finalRow[x]}`, TILE_COLORS[finalRow[x]]);
833
+ addScorePopup2(x * TILE_WIDTH + TILE_WIDTH / 2, y * TILE_HEIGHT + 1, `+${finalRow[x]}`, TILE_COLORS[finalRow[x]]);
834
834
  }
835
835
  }
836
836
  grid[y] = finalRow;
@@ -845,7 +845,7 @@ function run2048Game(terminal) {
845
845
  for (let y = 0; y < GRID_SIZE; y++) {
846
846
  if (merged[y] && result[y] > 0) {
847
847
  spawnMergeParticles(x, y, result[y]);
848
- addScorePopup(x * TILE_WIDTH + TILE_WIDTH / 2, y * TILE_HEIGHT + 1, `+${result[y]}`, TILE_COLORS[result[y]]);
848
+ addScorePopup2(x * TILE_WIDTH + TILE_WIDTH / 2, y * TILE_HEIGHT + 1, `+${result[y]}`, TILE_COLORS[result[y]]);
849
849
  }
850
850
  grid[y][x] = result[y];
851
851
  }
@@ -863,7 +863,7 @@ function run2048Game(terminal) {
863
863
  for (let y = 0; y < GRID_SIZE; y++) {
864
864
  if (finalMerged[y] && finalCol[y] > 0) {
865
865
  spawnMergeParticles(x, y, finalCol[y]);
866
- addScorePopup(x * TILE_WIDTH + TILE_WIDTH / 2, y * TILE_HEIGHT + 1, `+${finalCol[y]}`, TILE_COLORS[finalCol[y]]);
866
+ addScorePopup2(x * TILE_WIDTH + TILE_WIDTH / 2, y * TILE_HEIGHT + 1, `+${finalCol[y]}`, TILE_COLORS[finalCol[y]]);
867
867
  }
868
868
  grid[y][x] = finalCol[y];
869
869
  }
@@ -872,13 +872,13 @@ function run2048Game(terminal) {
872
872
  if (anyMoved) {
873
873
  score += totalMergeScore;
874
874
  if (totalMergeScore > 0) {
875
- triggerShake(4, 1);
875
+ triggerShake2(4, 1);
876
876
  }
877
877
  spawnTile();
878
878
  if (!won && !continuedAfterWin && has2048()) {
879
879
  won = true;
880
880
  if (score > highScore) highScore = score;
881
- triggerShake(8, 2);
881
+ triggerShake2(8, 2);
882
882
  for (let y = 0; y < GRID_SIZE; y++) {
883
883
  for (let x = 0; x < GRID_SIZE; x++) {
884
884
  if (grid[y][x] === 2048) {
@@ -1380,11 +1380,11 @@ function runAsteroidsGame(terminal) {
1380
1380
  if (value >= max) return value - max;
1381
1381
  return value;
1382
1382
  }
1383
- function triggerShake(frames, intensity) {
1383
+ function triggerShake2(frames, intensity) {
1384
1384
  shakeFrames = frames;
1385
1385
  shakeIntensity = intensity;
1386
1386
  }
1387
- function spawnParticles2(x, y, count, color) {
1387
+ function spawnParticles3(x, y, count, color) {
1388
1388
  const chars = ["*", "+", ".", "\xB7"];
1389
1389
  for (let i = 0; i < count; i++) {
1390
1390
  const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
@@ -1416,8 +1416,8 @@ function runAsteroidsGame(terminal) {
1416
1416
  function hitShip() {
1417
1417
  if (invincibilityFrames > 0) return;
1418
1418
  lives--;
1419
- spawnParticles2(ship.x, ship.y, 15, "\x1B[91m");
1420
- triggerShake(10, 3);
1419
+ spawnParticles3(ship.x, ship.y, 15, "\x1B[91m");
1420
+ triggerShake2(10, 3);
1421
1421
  if (lives <= 0) {
1422
1422
  gameOver = true;
1423
1423
  if (score > highScore) highScore = score;
@@ -1430,7 +1430,7 @@ function runAsteroidsGame(terminal) {
1430
1430
  }
1431
1431
  }
1432
1432
  function splitAsteroid(asteroid) {
1433
- spawnParticles2(asteroid.x, asteroid.y, 8, "\x1B[93m");
1433
+ spawnParticles3(asteroid.x, asteroid.y, 8, "\x1B[93m");
1434
1434
  score += ASTEROID_SCORES[asteroid.size];
1435
1435
  if (asteroid.size === "large") {
1436
1436
  for (let i = 0; i < 2; i++) {
@@ -1498,7 +1498,7 @@ function runAsteroidsGame(terminal) {
1498
1498
  bullets.splice(j, 1);
1499
1499
  splitAsteroid(ast);
1500
1500
  asteroids.splice(i, 1);
1501
- triggerShake(4, 1);
1501
+ triggerShake2(4, 1);
1502
1502
  break;
1503
1503
  }
1504
1504
  }
@@ -1781,17 +1781,17 @@ function runBreakoutGame(terminal) {
1781
1781
  ];
1782
1782
  const brickColors = ["\x1B[1;91m", "\x1B[1;93m", "\x1B[1;92m", "\x1B[1;96m", "\x1B[1;95m"];
1783
1783
  const brickPoints = [50, 40, 30, 20, 10];
1784
- function spawnParticles2(x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
1784
+ function spawnParticles3(x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
1785
1785
  for (let i = 0; i < count; i++) {
1786
1786
  const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
1787
1787
  const speed = 0.2 + Math.random() * 0.4;
1788
1788
  particles.push({ x, y, char: chars[Math.floor(Math.random() * chars.length)], color, vx: Math.cos(angle) * speed, vy: Math.sin(angle) * speed * 0.5, life: 10 + Math.floor(Math.random() * 8) });
1789
1789
  }
1790
1790
  }
1791
- function addScorePopup(x, y, text, color = "\x1B[1;33m") {
1791
+ function addScorePopup2(x, y, text, color = "\x1B[1;33m") {
1792
1792
  scorePopups.push({ x, y, text, frames: 18, color });
1793
1793
  }
1794
- function triggerShake(frames, intensity) {
1794
+ function triggerShake2(frames, intensity) {
1795
1795
  shakeFrames = frames;
1796
1796
  shakeIntensity = intensity;
1797
1797
  }
@@ -1848,7 +1848,7 @@ function runBreakoutGame(terminal) {
1848
1848
  powerUps.push({ x, y, type: types[Math.floor(Math.random() * types.length)], vy: 0.15 });
1849
1849
  }
1850
1850
  function applyPowerUp(type) {
1851
- triggerShake(8, 2);
1851
+ triggerShake2(8, 2);
1852
1852
  borderFlash = 15;
1853
1853
  switch (type) {
1854
1854
  case "multiball": {
@@ -1861,18 +1861,18 @@ function runBreakoutGame(terminal) {
1861
1861
  balls.push({ x: src.x, y: src.y, vx: Math.cos(angle) * speed, vy: -Math.abs(Math.sin(angle) * speed), active: true });
1862
1862
  }
1863
1863
  }
1864
- addScorePopup(paddleX, GAME_HEIGHT - 5, "MULTI-BALL!", "\x1B[1;96m");
1864
+ addScorePopup2(paddleX, GAME_HEIGHT - 5, "MULTI-BALL!", "\x1B[1;96m");
1865
1865
  break;
1866
1866
  }
1867
1867
  case "wide":
1868
1868
  paddleWidth = PADDLE_WIDTH_WIDE;
1869
1869
  paddleWidthTimer = 600;
1870
- addScorePopup(paddleX, GAME_HEIGHT - 5, "WIDE PADDLE!", "\x1B[1;92m");
1870
+ addScorePopup2(paddleX, GAME_HEIGHT - 5, "WIDE PADDLE!", "\x1B[1;92m");
1871
1871
  break;
1872
1872
  case "laser":
1873
1873
  laserActive = true;
1874
1874
  laserTimer = 400;
1875
- addScorePopup(paddleX, GAME_HEIGHT - 5, "LASER!", "\x1B[1;91m");
1875
+ addScorePopup2(paddleX, GAME_HEIGHT - 5, "LASER!", "\x1B[1;91m");
1876
1876
  break;
1877
1877
  case "slow":
1878
1878
  slowActive = true;
@@ -1881,11 +1881,11 @@ function runBreakoutGame(terminal) {
1881
1881
  b.vx *= 0.6;
1882
1882
  b.vy *= 0.6;
1883
1883
  }
1884
- addScorePopup(paddleX, GAME_HEIGHT - 5, "SLOW-MO!", "\x1B[1;93m");
1884
+ addScorePopup2(paddleX, GAME_HEIGHT - 5, "SLOW-MO!", "\x1B[1;93m");
1885
1885
  break;
1886
1886
  case "extra":
1887
1887
  lives++;
1888
- addScorePopup(paddleX, GAME_HEIGHT - 5, "+1 LIFE!", "\x1B[1;95m");
1888
+ addScorePopup2(paddleX, GAME_HEIGHT - 5, "+1 LIFE!", "\x1B[1;95m");
1889
1889
  break;
1890
1890
  }
1891
1891
  }
@@ -1961,8 +1961,8 @@ function runBreakoutGame(terminal) {
1961
1961
  brick.alive = false;
1962
1962
  const pts = brickPoints[brick.type] || 10;
1963
1963
  score += pts;
1964
- spawnParticles2(brick.x + brick.width / 2, brick.y, 6, brickColors[brick.type]);
1965
- addScorePopup(brick.x + 1, brick.y - 1, `+${pts}`, brickColors[brick.type]);
1964
+ spawnParticles3(brick.x + brick.width / 2, brick.y, 6, brickColors[brick.type]);
1965
+ addScorePopup2(brick.x + 1, brick.y - 1, `+${pts}`, brickColors[brick.type]);
1966
1966
  spawnPowerUp(brick.x + brick.width / 2, brick.y);
1967
1967
  }
1968
1968
  lasers.splice(i, 1);
@@ -1983,17 +1983,17 @@ function runBreakoutGame(terminal) {
1983
1983
  if (ball.x <= 0) {
1984
1984
  ball.x = 0;
1985
1985
  ball.vx = Math.abs(ball.vx);
1986
- spawnParticles2(0, ball.y, 3, themeColor, ["\xB7", "\u2022"]);
1986
+ spawnParticles3(0, ball.y, 3, themeColor, ["\xB7", "\u2022"]);
1987
1987
  }
1988
1988
  if (ball.x >= GAME_WIDTH - 1) {
1989
1989
  ball.x = GAME_WIDTH - 1;
1990
1990
  ball.vx = -Math.abs(ball.vx);
1991
- spawnParticles2(GAME_WIDTH - 1, ball.y, 3, themeColor, ["\xB7", "\u2022"]);
1991
+ spawnParticles3(GAME_WIDTH - 1, ball.y, 3, themeColor, ["\xB7", "\u2022"]);
1992
1992
  }
1993
1993
  if (ball.y <= 0) {
1994
1994
  ball.y = 0;
1995
1995
  ball.vy = Math.abs(ball.vy);
1996
- spawnParticles2(ball.x, 0, 3, themeColor, ["\xB7", "\u2022"]);
1996
+ spawnParticles3(ball.x, 0, 3, themeColor, ["\xB7", "\u2022"]);
1997
1997
  }
1998
1998
  const pL = paddleX - paddleWidth / 2, pR = paddleX + paddleWidth / 2, pY = GAME_HEIGHT - 2;
1999
1999
  if (ball.vy > 0 && ball.y >= pY - 0.5 && ball.y <= pY + 0.5 && ball.x >= pL - 0.5 && ball.x <= pR + 0.5) {
@@ -2004,7 +2004,7 @@ function runBreakoutGame(terminal) {
2004
2004
  ball.vx = Math.sin(angle) * newSpeed;
2005
2005
  ball.vy = -Math.cos(angle) * newSpeed;
2006
2006
  ball.y = pY - 1;
2007
- spawnParticles2(ball.x, pY, 4, themeColor, ["\u2726", "\u25CF"]);
2007
+ spawnParticles3(ball.x, pY, 4, themeColor, ["\u2726", "\u25CF"]);
2008
2008
  }
2009
2009
  for (const brick of bricks) {
2010
2010
  if (!brick.alive) continue;
@@ -2024,12 +2024,12 @@ function runBreakoutGame(terminal) {
2024
2024
  const totalPts = basePts + comboBonus;
2025
2025
  score += totalPts;
2026
2026
  const intensity = Math.min(comboCount, 8);
2027
- triggerShake(3 + intensity, 1 + Math.floor(intensity / 3));
2028
- spawnParticles2(brick.x + brick.width / 2, brick.y, 6 + intensity, brickColors[brick.type]);
2029
- addScorePopup(brick.x + 1, brick.y - 1, comboCount > 1 ? `+${totalPts}!` : `+${totalPts}`, brickColors[brick.type]);
2027
+ triggerShake2(3 + intensity, 1 + Math.floor(intensity / 3));
2028
+ spawnParticles3(brick.x + brick.width / 2, brick.y, 6 + intensity, brickColors[brick.type]);
2029
+ addScorePopup2(brick.x + 1, brick.y - 1, comboCount > 1 ? `+${totalPts}!` : `+${totalPts}`, brickColors[brick.type]);
2030
2030
  spawnPowerUp(brick.x + brick.width / 2, brick.y);
2031
2031
  } else {
2032
- spawnParticles2(ball.x, ball.y, 3, "\x1B[2m" + brickColors[brick.type], ["\xB7", "x"]);
2032
+ spawnParticles3(ball.x, ball.y, 3, "\x1B[2m" + brickColors[brick.type], ["\xB7", "x"]);
2033
2033
  }
2034
2034
  break;
2035
2035
  }
@@ -2042,12 +2042,12 @@ function runBreakoutGame(terminal) {
2042
2042
  if (lives <= 0) {
2043
2043
  gameOver = true;
2044
2044
  if (score > highScore) highScore = score;
2045
- triggerShake(20, 4);
2046
- spawnParticles2(paddleX, GAME_HEIGHT - 2, 15, "\x1B[1;91m", ["\u2717", "\u2620", "\xD7", "\u2593"]);
2045
+ triggerShake2(20, 4);
2046
+ spawnParticles3(paddleX, GAME_HEIGHT - 2, 15, "\x1B[1;91m", ["\u2717", "\u2620", "\xD7", "\u2593"]);
2047
2047
  } else {
2048
2048
  ballAttached = true;
2049
2049
  balls = [{ x: paddleX, y: GAME_HEIGHT - 3, vx: 0, vy: 0, active: true }];
2050
- triggerShake(10, 2);
2050
+ triggerShake2(10, 2);
2051
2051
  }
2052
2052
  }
2053
2053
  const aliveBricks = bricks.filter((b) => b.alive);
@@ -2056,8 +2056,8 @@ function runBreakoutGame(terminal) {
2056
2056
  gameOver = true;
2057
2057
  level++;
2058
2058
  if (score > highScore) highScore = score;
2059
- triggerShake(12, 2);
2060
- for (let i = 0; i < 5; i++) setTimeout(() => spawnParticles2(Math.random() * GAME_WIDTH, Math.random() * GAME_HEIGHT / 2, 15, brickColors[Math.floor(Math.random() * brickColors.length)], ["\u2605", "\u2726", "\u25C6", "\u25CF", "\u2727"]), i * 100);
2059
+ triggerShake2(12, 2);
2060
+ for (let i = 0; i < 5; i++) setTimeout(() => spawnParticles3(Math.random() * GAME_WIDTH, Math.random() * GAME_HEIGHT / 2, 15, brickColors[Math.floor(Math.random() * brickColors.length)], ["\u2605", "\u2726", "\u25C6", "\u25CF", "\u2727"]), i * 100);
2061
2061
  }
2062
2062
  }
2063
2063
  function render() {
@@ -4065,7 +4065,7 @@ function runCrackGame(terminal) {
4065
4065
  lng: (Math.random() * 360 - 180).toFixed(6)
4066
4066
  };
4067
4067
  }
4068
- function spawnParticles2(x, y, count, color, chars = ["\u2588", "\u2593", "\u2592", "\u2591", "\u25CF", "\u25C6", "\u2726"]) {
4068
+ function spawnParticles3(x, y, count, color, chars = ["\u2588", "\u2593", "\u2592", "\u2591", "\u25CF", "\u25C6", "\u2726"]) {
4069
4069
  for (let i = 0; i < count; i++) {
4070
4070
  particles.push({
4071
4071
  x,
@@ -4078,7 +4078,7 @@ function runCrackGame(terminal) {
4078
4078
  });
4079
4079
  }
4080
4080
  }
4081
- function addScorePopup(x, y, text, color) {
4081
+ function addScorePopup2(x, y, text, color) {
4082
4082
  scorePopups.push({ x, y, text, frames: 30, color });
4083
4083
  }
4084
4084
  const controller = {
@@ -4168,17 +4168,17 @@ function runCrackGame(terminal) {
4168
4168
  layerBreachFlash = 20;
4169
4169
  screenShake = 8;
4170
4170
  shakeIntensity = 3;
4171
- spawnParticles2(effectX, effectY, 25, "\x1B[1;32m", ["\u2588", "\u2593", "\u2726", "\u2605", "\u25C6", "\u25CF"]);
4172
- spawnParticles2(effectX - 5, effectY, 15, "\x1B[1;92m", ["\u2591", "\u2592", "\u2593"]);
4173
- spawnParticles2(effectX + 5, effectY, 15, "\x1B[1;92m", ["\u2591", "\u2592", "\u2593"]);
4171
+ spawnParticles3(effectX, effectY, 25, "\x1B[1;32m", ["\u2588", "\u2593", "\u2726", "\u2605", "\u25C6", "\u25CF"]);
4172
+ spawnParticles3(effectX - 5, effectY, 15, "\x1B[1;92m", ["\u2591", "\u2592", "\u2593"]);
4173
+ spawnParticles3(effectX + 5, effectY, 15, "\x1B[1;92m", ["\u2591", "\u2592", "\u2593"]);
4174
4174
  if (currentLayer >= totalLayers) {
4175
4175
  won = true;
4176
4176
  gameOver = true;
4177
- addScorePopup(effectX, effectY - 2, "\u25C6 SYSTEM COMPROMISED \u25C6", "\x1B[1;32m");
4177
+ addScorePopup2(effectX, effectY - 2, "\u25C6 SYSTEM COMPROMISED \u25C6", "\x1B[1;32m");
4178
4178
  for (let i = 0; i < 5; i++) {
4179
4179
  setTimeout(() => {
4180
4180
  if (running) {
4181
- spawnParticles2(
4181
+ spawnParticles3(
4182
4182
  Math.floor(cols / 4) + Math.random() * cols / 2,
4183
4183
  5 + Math.random() * 10,
4184
4184
  10,
@@ -4189,7 +4189,7 @@ function runCrackGame(terminal) {
4189
4189
  }, i * 100);
4190
4190
  }
4191
4191
  } else {
4192
- addScorePopup(effectX, effectY - 2, `LAYER ${currentLayer} BREACHED!`, "\x1B[1;32m");
4192
+ addScorePopup2(effectX, effectY - 2, `LAYER ${currentLayer} BREACHED!`, "\x1B[1;32m");
4193
4193
  currentLayer++;
4194
4194
  setTimeout(() => {
4195
4195
  if (running && !gameOver) initLayer();
@@ -4204,21 +4204,21 @@ function runCrackGame(terminal) {
4204
4204
  gameOver = true;
4205
4205
  gameOverFrame = 0;
4206
4206
  generateFakeCoords();
4207
- spawnParticles2(effectX, effectY, 20, "\x1B[1;31m", ["\u2588", "\u2593", "\u2592", "!", "@", "#"]);
4208
- addScorePopup(effectX, effectY - 2, "\u25C6 TRACED \u25C6", "\x1B[1;31m");
4207
+ spawnParticles3(effectX, effectY, 20, "\x1B[1;31m", ["\u2588", "\u2593", "\u2592", "!", "@", "#"]);
4208
+ addScorePopup2(effectX, effectY - 2, "\u25C6 TRACED \u25C6", "\x1B[1;31m");
4209
4209
  } else if (hasPartial) {
4210
4210
  addLog("partial");
4211
4211
  correctFlash = 4 + correctCount * 2;
4212
4212
  screenShake = Math.min(correctCount + 1, 4);
4213
4213
  shakeIntensity = 1;
4214
4214
  if (correctCount > 0) {
4215
- spawnParticles2(effectX, effectY, 3 + correctCount * 2, "\x1B[1;32m", ["\u2588", "\u25CF", "\u25C6"]);
4216
- addScorePopup(effectX, effectY - 1, `${correctCount} EXACT!`, "\x1B[1;32m");
4215
+ spawnParticles3(effectX, effectY, 3 + correctCount * 2, "\x1B[1;32m", ["\u2588", "\u25CF", "\u25C6"]);
4216
+ addScorePopup2(effectX, effectY - 1, `${correctCount} EXACT!`, "\x1B[1;32m");
4217
4217
  }
4218
4218
  if (presentCount > 0) {
4219
- spawnParticles2(effectX + 3, effectY, 2 + presentCount, "\x1B[1;33m", ["\u2591", "\u2592", "\u25CF"]);
4219
+ spawnParticles3(effectX + 3, effectY, 2 + presentCount, "\x1B[1;33m", ["\u2591", "\u2592", "\u25CF"]);
4220
4220
  if (correctCount === 0) {
4221
- addScorePopup(effectX, effectY - 1, `${presentCount} CLOSE`, "\x1B[1;33m");
4221
+ addScorePopup2(effectX, effectY - 1, `${presentCount} CLOSE`, "\x1B[1;33m");
4222
4222
  }
4223
4223
  }
4224
4224
  } else {
@@ -4226,8 +4226,8 @@ function runCrackGame(terminal) {
4226
4226
  wrongFlash = 6;
4227
4227
  screenShake = 3;
4228
4228
  shakeIntensity = 2;
4229
- spawnParticles2(effectX, effectY, 5, "\x1B[31m", ["\u2591", "\u2592", "\xD7", "\xB7"]);
4230
- addScorePopup(effectX, effectY - 1, "DENIED", "\x1B[2;31m");
4229
+ spawnParticles3(effectX, effectY, 5, "\x1B[31m", ["\u2591", "\u2592", "\xD7", "\xB7"]);
4230
+ addScorePopup2(effectX, effectY - 1, "DENIED", "\x1B[2;31m");
4231
4231
  }
4232
4232
  currentGuess = "";
4233
4233
  }
@@ -4501,7 +4501,7 @@ function runCrackGame(terminal) {
4501
4501
  borderFlash = 3;
4502
4502
  wrongFlash = 3;
4503
4503
  if (timeLeft % 2 === 0) {
4504
- spawnParticles2(Math.random() * cols, 2, 3, "\x1B[1;31m", ["!", "\u2593", "\u2591"]);
4504
+ spawnParticles3(Math.random() * cols, 2, 3, "\x1B[1;31m", ["!", "\u2593", "\u2591"]);
4505
4505
  }
4506
4506
  }
4507
4507
  if (timeLeft <= 0) {
@@ -4515,8 +4515,8 @@ function runCrackGame(terminal) {
4515
4515
  borderFlash = 25;
4516
4516
  const centerX = Math.floor(cols / 2);
4517
4517
  const centerY = Math.floor(rows / 2);
4518
- spawnParticles2(centerX, centerY, 30, "\x1B[1;31m", ["\u2588", "\u2593", "\u2592", "!", "@", "#", "\xD7"]);
4519
- addScorePopup(centerX, centerY - 3, "\u25C6\u25C6 TRACE COMPLETE \u25C6\u25C6", "\x1B[1;31m");
4518
+ spawnParticles3(centerX, centerY, 30, "\x1B[1;31m", ["\u2588", "\u2593", "\u2592", "!", "@", "#", "\xD7"]);
4519
+ addScorePopup2(centerX, centerY - 3, "\u25C6\u25C6 TRACE COMPLETE \u25C6\u25C6", "\x1B[1;31m");
4520
4520
  }
4521
4521
  }
4522
4522
  if (gameOver) {
@@ -4663,7 +4663,7 @@ function runCrackGame(terminal) {
4663
4663
  currentGuess += key.toUpperCase();
4664
4664
  const inputX = 4 + currentGuess.length * 2;
4665
4665
  const inputY = 12 + guesses.length;
4666
- spawnParticles2(inputX, inputY, 1, themeColor, ["\xB7", "\u25CF"]);
4666
+ spawnParticles3(inputX, inputY, 1, themeColor, ["\xB7", "\u25CF"]);
4667
4667
  if (currentGuess.length === 5) {
4668
4668
  screenShake = 2;
4669
4669
  shakeIntensity = 1;
@@ -4751,7 +4751,7 @@ function runFroggerGame(terminal) {
4751
4751
  "\u2588\u2580\u2580 \u2588\u2580\u2588 \u2588\u2580\u2588 \u2588\u2580\u2580 \u2588\u2580\u2580 \u2588\u2580\u2580 \u2588\u2580\u2588",
4752
4752
  "\u2588\u2580 \u2588\u2580\u2584 \u2588\u2584\u2588 \u2588\u2584\u2588 \u2588\u2584\u2588 \u2588\u2588\u2584 \u2588\u2580\u2584"
4753
4753
  ];
4754
- function spawnParticles2(x, y, count, color, chars) {
4754
+ function spawnParticles3(x, y, count, color, chars) {
4755
4755
  for (let i = 0; i < count; i++) {
4756
4756
  const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
4757
4757
  const speed = 0.1 + Math.random() * 0.15;
@@ -4768,13 +4768,13 @@ function runFroggerGame(terminal) {
4768
4768
  }
4769
4769
  }
4770
4770
  function spawnSplash2(x, y) {
4771
- spawnParticles2(x, y, 8, "\x1B[96m", ["~", "\u223C", "\u2248", "\u25CB"]);
4771
+ spawnParticles3(x, y, 8, "\x1B[96m", ["~", "\u223C", "\u2248", "\u25CB"]);
4772
4772
  }
4773
4773
  function spawnCrash(x, y) {
4774
- spawnParticles2(x, y, 10, "\x1B[91m", ["*", "x", "\xD7", "#"]);
4774
+ spawnParticles3(x, y, 10, "\x1B[91m", ["*", "x", "\xD7", "#"]);
4775
4775
  }
4776
4776
  function spawnSuccess(x, y) {
4777
- spawnParticles2(x, y, 12, "\x1B[92m", ["*", "+", "\u2666", "\u25C7"]);
4777
+ spawnParticles3(x, y, 12, "\x1B[92m", ["*", "+", "\u2666", "\u25C7"]);
4778
4778
  }
4779
4779
  function calculateLilyPads() {
4780
4780
  lilyPadX = [];
@@ -5580,7 +5580,7 @@ function runHangmanGame(terminal) {
5580
5580
  winAnimation = 0;
5581
5581
  loseAnimation = 0;
5582
5582
  }
5583
- function spawnParticles2(x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
5583
+ function spawnParticles3(x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
5584
5584
  for (let i = 0; i < count; i++) {
5585
5585
  const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
5586
5586
  const speed = 0.3 + Math.random() * 0.5;
@@ -5595,7 +5595,7 @@ function runHangmanGame(terminal) {
5595
5595
  });
5596
5596
  }
5597
5597
  }
5598
- function addScorePopup(x, y, text, color = "\x1B[1;33m") {
5598
+ function addScorePopup2(x, y, text, color = "\x1B[1;33m") {
5599
5599
  scorePopups.push({ x, y, text, frames: 22, color });
5600
5600
  }
5601
5601
  function getDisplayWord() {
@@ -5622,12 +5622,12 @@ function runHangmanGame(terminal) {
5622
5622
  screenShake = 2 + Math.floor(effectIntensity / 2);
5623
5623
  const centerX = Math.floor(terminal.cols / 2);
5624
5624
  const wordY = gameTop + 9;
5625
- spawnParticles2(centerX, wordY, 4 + effectIntensity, "\x1B[1;92m", ["\u2726", "\u2605", "\u25C6", "\u25CF"]);
5625
+ spawnParticles3(centerX, wordY, 4 + effectIntensity, "\x1B[1;92m", ["\u2726", "\u2605", "\u25C6", "\u25CF"]);
5626
5626
  const popupText = letterCount > 1 ? `+${points}!` : `+${points}`;
5627
5627
  const popupColor = correctStreak >= 3 ? "\x1B[1;93m" : "\x1B[1;92m";
5628
- addScorePopup(centerX - 2, wordY - 2, popupText, popupColor);
5628
+ addScorePopup2(centerX - 2, wordY - 2, popupText, popupColor);
5629
5629
  if (correctStreak >= 3) {
5630
- addScorePopup(centerX - 4, wordY - 4, `${correctStreak}x STREAK!`, "\x1B[1;96m");
5630
+ addScorePopup2(centerX - 4, wordY - 4, `${correctStreak}x STREAK!`, "\x1B[1;96m");
5631
5631
  }
5632
5632
  if (checkWin()) {
5633
5633
  won = true;
@@ -5638,9 +5638,9 @@ function runHangmanGame(terminal) {
5638
5638
  score += bonus;
5639
5639
  winAnimation = 30;
5640
5640
  screenShake = 8;
5641
- spawnParticles2(centerX, wordY, 15, "\x1B[1;93m", ["\u2605", "\u2726", "\u2666", "\u25C6", "\u25CF"]);
5641
+ spawnParticles3(centerX, wordY, 15, "\x1B[1;93m", ["\u2605", "\u2726", "\u2666", "\u25C6", "\u25CF"]);
5642
5642
  if (bonus > 0) {
5643
- addScorePopup(centerX - 3, wordY + 2, `+${bonus} BONUS!`, "\x1B[1;93m");
5643
+ addScorePopup2(centerX - 3, wordY + 2, `+${bonus} BONUS!`, "\x1B[1;93m");
5644
5644
  }
5645
5645
  }
5646
5646
  } else {
@@ -5650,14 +5650,14 @@ function runHangmanGame(terminal) {
5650
5650
  screenShake = 4 + wrongGuesses;
5651
5651
  const hangmanX = gameLeft + 6;
5652
5652
  const hangmanY = gameTop + 4;
5653
- spawnParticles2(hangmanX, hangmanY, 5, "\x1B[1;91m", ["\u2717", "\xD7", "\xB7", "\u25CB"]);
5653
+ spawnParticles3(hangmanX, hangmanY, 5, "\x1B[1;91m", ["\u2717", "\xD7", "\xB7", "\u25CB"]);
5654
5654
  if (wrongGuesses >= MAX_WRONG) {
5655
5655
  gameOver = true;
5656
5656
  streak = 0;
5657
5657
  loseAnimation = 40;
5658
5658
  screenShake = 20;
5659
- spawnParticles2(hangmanX, hangmanY, 12, "\x1B[1;91m", ["\u2717", "\u2620", "\xD7", "\u2592", "\u2591"]);
5660
- addScorePopup(hangmanX - 3, hangmanY - 2, "FAILED!", "\x1B[1;91m");
5659
+ spawnParticles3(hangmanX, hangmanY, 12, "\x1B[1;91m", ["\u2717", "\u2620", "\xD7", "\u2592", "\u2591"]);
5660
+ addScorePopup2(hangmanX - 3, hangmanY - 2, "FAILED!", "\x1B[1;91m");
5661
5661
  }
5662
5662
  }
5663
5663
  }
@@ -6013,7 +6013,7 @@ function runMinesweeperGame(terminal) {
6013
6013
  "\u2588\u2584 \u2584\u2588 \u2588 \u2588\u2584 \u2588 \u2588\u2580\u2580 \u2588\u2580\u2580 \u2588 \u2588 \u2588 \u2588\u2580\u2580 \u2588\u2580\u2580 \u2588\u2580\u2588 \u2588\u2580\u2580 \u2588\u2580\u2588",
6014
6014
  "\u2588 \u2580 \u2588 \u2588 \u2588 \u2580\u2588 \u2588\u2588\u2584 \u2584\u2584\u2588 \u2580\u2584\u2580\u2584\u2580 \u2588\u2588\u2584 \u2588\u2588\u2584 \u2588\u2580\u2580 \u2588\u2588\u2584 \u2588\u2580\u2584"
6015
6015
  ];
6016
- function spawnParticles2(x, y, count, color, chars = ["*", "+", ".", "o"]) {
6016
+ function spawnParticles3(x, y, count, color, chars = ["*", "+", ".", "o"]) {
6017
6017
  for (let i = 0; i < count; i++) {
6018
6018
  const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
6019
6019
  const speed = 0.2 + Math.random() * 0.4;
@@ -6045,10 +6045,10 @@ function runMinesweeperGame(terminal) {
6045
6045
  });
6046
6046
  }
6047
6047
  }
6048
- function addScorePopup(x, y, text, color = "\x1B[1;33m") {
6048
+ function addScorePopup2(x, y, text, color = "\x1B[1;33m") {
6049
6049
  scorePopups.push({ x, y, text, frames: 20, color });
6050
6050
  }
6051
- function triggerShake(frames, intensity) {
6051
+ function triggerShake2(frames, intensity) {
6052
6052
  shakeFrames = frames;
6053
6053
  shakeIntensity = intensity;
6054
6054
  }
@@ -6135,14 +6135,14 @@ function runMinesweeperGame(terminal) {
6135
6135
  if (cell.isMine) {
6136
6136
  gameOver = true;
6137
6137
  won = false;
6138
- triggerShake(25, 4);
6138
+ triggerShake2(25, 4);
6139
6139
  spawnExplosion(x * 2 + 1, y);
6140
- addScorePopup(x * 2, y - 1, "MALWARE!", "\x1B[1;91m");
6140
+ addScorePopup2(x * 2, y - 1, "MALWARE!", "\x1B[1;91m");
6141
6141
  revealAllMines();
6142
6142
  return;
6143
6143
  }
6144
6144
  if (!isChain) {
6145
- spawnParticles2(x * 2 + 1, y, 4, themeColor, [".", "*", "+"]);
6145
+ spawnParticles3(x * 2 + 1, y, 4, themeColor, [".", "*", "+"]);
6146
6146
  }
6147
6147
  if (cell.adjacentMines === 0) {
6148
6148
  for (let dy = -1; dy <= 1; dy++) {
@@ -6165,7 +6165,7 @@ function runMinesweeperGame(terminal) {
6165
6165
  cell.isFlagged = !cell.isFlagged;
6166
6166
  if (cell.isFlagged) {
6167
6167
  flagsPlaced++;
6168
- spawnParticles2(x * 2 + 1, y, 3, "\x1B[1;93m", ["!", "^", "*"]);
6168
+ spawnParticles3(x * 2 + 1, y, 3, "\x1B[1;93m", ["!", "^", "*"]);
6169
6169
  } else {
6170
6170
  flagsPlaced--;
6171
6171
  }
@@ -6184,13 +6184,13 @@ function runMinesweeperGame(terminal) {
6184
6184
  if (cellsRevealed >= totalNonMines) {
6185
6185
  gameOver = true;
6186
6186
  won = true;
6187
- triggerShake(10, 2);
6187
+ triggerShake2(10, 2);
6188
6188
  for (let i = 0; i < 5; i++) {
6189
6189
  const x = Math.floor(Math.random() * difficulty.width);
6190
6190
  const y = Math.floor(Math.random() * difficulty.height);
6191
- spawnParticles2(x * 2 + 1, y, 6, "\x1B[1;92m", ["*", "+", "#"]);
6191
+ spawnParticles3(x * 2 + 1, y, 6, "\x1B[1;92m", ["*", "+", "#"]);
6192
6192
  }
6193
- addScorePopup(difficulty.width, difficulty.height / 2, "GRID SECURE!", "\x1B[1;92m");
6193
+ addScorePopup2(difficulty.width, difficulty.height / 2, "GRID SECURE!", "\x1B[1;92m");
6194
6194
  }
6195
6195
  }
6196
6196
  function update() {
@@ -6660,7 +6660,7 @@ function runPongGame(terminal) {
6660
6660
  rallyCount = 0;
6661
6661
  wallHitFlash = 0;
6662
6662
  }
6663
- function spawnParticles2(x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
6663
+ function spawnParticles3(x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
6664
6664
  for (let i = 0; i < count; i++) {
6665
6665
  const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
6666
6666
  const speed = 0.2 + Math.random() * 0.4;
@@ -6675,7 +6675,7 @@ function runPongGame(terminal) {
6675
6675
  });
6676
6676
  }
6677
6677
  }
6678
- function addScorePopup(x, y, text, color = "\x1B[1;33m") {
6678
+ function addScorePopup2(x, y, text, color = "\x1B[1;33m") {
6679
6679
  scorePopups.push({ x, y, text, frames: 20, color });
6680
6680
  }
6681
6681
  function createGoalExplosion(side) {
@@ -6928,7 +6928,7 @@ function runPongGame(terminal) {
6928
6928
  ballVY = -ballVY;
6929
6929
  ballY = Math.max(0, Math.min(GAME_HEIGHT - 1, ballY));
6930
6930
  wallHitFlash = 6;
6931
- spawnParticles2(ballX, ballY <= 0 ? 1 : GAME_HEIGHT - 2, 4, "\x1B[1;93m", ["\xB7", "\u2022", "\u25CB"]);
6931
+ spawnParticles3(ballX, ballY <= 0 ? 1 : GAME_HEIGHT - 2, 4, "\x1B[1;93m", ["\xB7", "\u2022", "\u25CB"]);
6932
6932
  }
6933
6933
  if (ballX <= PADDLE_OFFSET + 1 && ballX >= PADDLE_OFFSET) {
6934
6934
  if (ballY >= playerY && ballY <= playerY + PADDLE_HEIGHT) {
@@ -6943,9 +6943,9 @@ function runPongGame(terminal) {
6943
6943
  const effectIntensity = Math.min(rallyCount, 10);
6944
6944
  paddleHitFlash = 8;
6945
6945
  if (rallyCount >= 5) screenShake = Math.floor(effectIntensity / 4);
6946
- spawnParticles2(PADDLE_OFFSET + 2, ballY, 4 + Math.floor(effectIntensity / 2), themeColor, ["\u2726", "\u2605", "\u25C6", "\u25CF"]);
6946
+ spawnParticles3(PADDLE_OFFSET + 2, ballY, 4 + Math.floor(effectIntensity / 2), themeColor, ["\u2726", "\u2605", "\u25C6", "\u25CF"]);
6947
6947
  if (rallyCount >= 3 && rallyCount % 3 === 0) {
6948
- addScorePopup(PADDLE_OFFSET + 4, ballY - 1, `${rallyCount}!`, "\x1B[1;96m");
6948
+ addScorePopup2(PADDLE_OFFSET + 4, ballY - 1, `${rallyCount}!`, "\x1B[1;96m");
6949
6949
  }
6950
6950
  }
6951
6951
  }
@@ -6962,9 +6962,9 @@ function runPongGame(terminal) {
6962
6962
  const effectIntensity = Math.min(rallyCount, 10);
6963
6963
  paddleHitFlash = 8;
6964
6964
  if (rallyCount >= 5) screenShake = Math.floor(effectIntensity / 4);
6965
- spawnParticles2(GAME_WIDTH - PADDLE_OFFSET - 2, ballY, 4 + Math.floor(effectIntensity / 2), "\x1B[1;91m", ["\u2726", "\u2605", "\u25C6", "\u25CF"]);
6965
+ spawnParticles3(GAME_WIDTH - PADDLE_OFFSET - 2, ballY, 4 + Math.floor(effectIntensity / 2), "\x1B[1;91m", ["\u2726", "\u2605", "\u25C6", "\u25CF"]);
6966
6966
  if (rallyCount >= 3 && rallyCount % 3 === 0) {
6967
- addScorePopup(GAME_WIDTH - PADDLE_OFFSET - 6, ballY - 1, `${rallyCount}!`, "\x1B[1;91m");
6967
+ addScorePopup2(GAME_WIDTH - PADDLE_OFFSET - 6, ballY - 1, `${rallyCount}!`, "\x1B[1;91m");
6968
6968
  }
6969
6969
  }
6970
6970
  }
@@ -6976,13 +6976,13 @@ function runPongGame(terminal) {
6976
6976
  screenShake = 8;
6977
6977
  goalFlashSide = "left";
6978
6978
  createGoalExplosion("left");
6979
- addScorePopup(GAME_WIDTH / 2 - 3, GAME_HEIGHT / 2 - 2, "CPU +1", "\x1B[1;91m");
6980
- spawnParticles2(2, ballY, 10, "\x1B[1;91m", ["\u2717", "\xD7", "\u2592", "\u2591"]);
6979
+ addScorePopup2(GAME_WIDTH / 2 - 3, GAME_HEIGHT / 2 - 2, "CPU +1", "\x1B[1;91m");
6980
+ spawnParticles3(2, ballY, 10, "\x1B[1;91m", ["\u2717", "\xD7", "\u2592", "\u2591"]);
6981
6981
  if (aiScore >= WIN_SCORE) {
6982
6982
  gameOver = true;
6983
6983
  scoreFreeze = 0;
6984
6984
  screenShake = 15;
6985
- spawnParticles2(GAME_WIDTH / 2, GAME_HEIGHT / 2, 20, "\x1B[1;91m", ["\u2717", "\u2620", "\xD7", "\u2593"]);
6985
+ spawnParticles3(GAME_WIDTH / 2, GAME_HEIGHT / 2, 20, "\x1B[1;91m", ["\u2717", "\u2620", "\xD7", "\u2593"]);
6986
6986
  } else {
6987
6987
  resetBall(true);
6988
6988
  }
@@ -6995,13 +6995,13 @@ function runPongGame(terminal) {
6995
6995
  goalFlashSide = "right";
6996
6996
  createGoalExplosion("right");
6997
6997
  const rallyBonus = rallyCount >= 5 ? ` (${rallyCount} rally!)` : "";
6998
- addScorePopup(GAME_WIDTH / 2 - 2, GAME_HEIGHT / 2 - 2, `+1${rallyBonus}`, "\x1B[1;92m");
6999
- spawnParticles2(GAME_WIDTH - 3, ballY, 10, "\x1B[1;92m", ["\u2726", "\u2605", "\u25C6", "\u25CF"]);
6998
+ addScorePopup2(GAME_WIDTH / 2 - 2, GAME_HEIGHT / 2 - 2, `+1${rallyBonus}`, "\x1B[1;92m");
6999
+ spawnParticles3(GAME_WIDTH - 3, ballY, 10, "\x1B[1;92m", ["\u2726", "\u2605", "\u25C6", "\u25CF"]);
7000
7000
  if (playerScore >= WIN_SCORE) {
7001
7001
  gameOver = true;
7002
7002
  scoreFreeze = 0;
7003
7003
  screenShake = 15;
7004
- spawnParticles2(GAME_WIDTH / 2, GAME_HEIGHT / 2, 20, "\x1B[1;93m", ["\u2605", "\u2726", "\u2666", "\u25C6"]);
7004
+ spawnParticles3(GAME_WIDTH / 2, GAME_HEIGHT / 2, 20, "\x1B[1;93m", ["\u2605", "\u2726", "\u2666", "\u25C6"]);
7005
7005
  } else {
7006
7006
  resetBall(false);
7007
7007
  }
@@ -7234,7 +7234,7 @@ function runRunnerGame(terminal) {
7234
7234
  const factor = Math.pow(t, 0.6);
7235
7235
  return Math.floor(ROAD_WIDTH_TOP + (ROAD_WIDTH_BOTTOM - ROAD_WIDTH_TOP) * factor);
7236
7236
  }
7237
- function spawnParticles2(x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
7237
+ function spawnParticles3(x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
7238
7238
  for (let i = 0; i < count; i++) {
7239
7239
  const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
7240
7240
  const speed2 = 0.3 + Math.random() * 0.5;
@@ -7249,7 +7249,7 @@ function runRunnerGame(terminal) {
7249
7249
  });
7250
7250
  }
7251
7251
  }
7252
- function addScorePopup(x, y, text, color = "\x1B[1;33m") {
7252
+ function addScorePopup2(x, y, text, color = "\x1B[1;33m") {
7253
7253
  scorePopups.push({ x, y, text, frames: 20, color });
7254
7254
  }
7255
7255
  function initGame() {
@@ -7372,8 +7372,8 @@ function runRunnerGame(terminal) {
7372
7372
  const roadLeft = centerX - Math.floor(roadWidth / 2);
7373
7373
  const coinX = roadLeft + Math.floor((coin.lane + 0.5) / LANES * roadWidth);
7374
7374
  const coinY = gameTop + TRACK_HEIGHT - Math.floor(coin.y);
7375
- spawnParticles2(coinX - gameLeft, coinY - gameTop, 6, "\x1B[1;93m", ["\u25C6", "\u2605", "\u25CF", "\u2666"]);
7376
- addScorePopup(coinX, coinY, `+${points}`, "\x1B[1;93m");
7375
+ spawnParticles3(coinX - gameLeft, coinY - gameTop, 6, "\x1B[1;93m", ["\u25C6", "\u2605", "\u25CF", "\u2666"]);
7376
+ addScorePopup2(coinX, coinY, `+${points}`, "\x1B[1;93m");
7377
7377
  } else {
7378
7378
  newCoins.push(coin);
7379
7379
  }
@@ -7763,7 +7763,7 @@ function runRunnerGame(terminal) {
7763
7763
  const roadWidth = getRoadWidth(TRACK_HEIGHT - 1);
7764
7764
  const roadLeft = centerX - Math.floor(roadWidth / 2);
7765
7765
  const playerCenter = roadLeft + Math.floor((playerLane + 0.5) / LANES * roadWidth);
7766
- spawnParticles2(playerCenter - gameLeft, TRACK_HEIGHT - 2, 4, "\x1B[96m", ["\u2726", "\u2605", "\u25C7"]);
7766
+ spawnParticles3(playerCenter - gameLeft, TRACK_HEIGHT - 2, 4, "\x1B[96m", ["\u2726", "\u2605", "\u25C7"]);
7767
7767
  }
7768
7768
  collectCoins();
7769
7769
  if (checkCollision()) {
@@ -7776,7 +7776,7 @@ function runRunnerGame(terminal) {
7776
7776
  const roadWidth = getRoadWidth(TRACK_HEIGHT - 1);
7777
7777
  const roadLeft = centerX - Math.floor(roadWidth / 2);
7778
7778
  const playerCenter = roadLeft + Math.floor((playerLane + 0.5) / LANES * roadWidth);
7779
- spawnParticles2(playerCenter - gameLeft, TRACK_HEIGHT - 1, 15, "\x1B[1;91m", ["\u2717", "\u2620", "\xD7", "\u2593", "\u2591"]);
7779
+ spawnParticles3(playerCenter - gameLeft, TRACK_HEIGHT - 1, 15, "\x1B[1;91m", ["\u2717", "\u2620", "\xD7", "\u2593", "\u2591"]);
7780
7780
  return;
7781
7781
  }
7782
7782
  distance += 0.18 * speed;
@@ -8010,7 +8010,7 @@ function runSimonGame(terminal) {
8010
8010
  "\u2588 \u2588 \u2588\u2584\u2588 \u2588\u2580\u2588 \u2588\u2580\u2580 \u2588\u2580\u2588 \u2588\u2580\u2580 \u2588 \u2588\u2580\u2580\u2588 \u2580\u2588\u2580\u2588 \u2588\u2580\u2588 \u2588\u2580\u2588",
8011
8011
  "\u2588\u2580\u2588 \u2588 \u2588\u2580\u2580 \u2588\u2588\u2584 \u2588\u2580\u2584 \u2584\u2584\u2588 \u2588 \u2588\u2588\u2584 \u2588 \u2588 \u2588 \u2588\u2580\u2584 \u2588 \u2588"
8012
8012
  ];
8013
- function spawnParticles2(x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
8013
+ function spawnParticles3(x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
8014
8014
  for (let i = 0; i < count; i++) {
8015
8015
  const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
8016
8016
  const speed = 0.3 + Math.random() * 0.5;
@@ -8045,12 +8045,12 @@ function runSimonGame(terminal) {
8045
8045
  x = centerX - offset * 2;
8046
8046
  break;
8047
8047
  }
8048
- spawnParticles2(x, y, 8, QUADRANT_COLORS[quadrant], ["\u2726", "\u2605", "\u25C6", "\u25CF"]);
8048
+ spawnParticles3(x, y, 8, QUADRANT_COLORS[quadrant], ["\u2726", "\u2605", "\u25C6", "\u25CF"]);
8049
8049
  }
8050
- function addScorePopup(x, y, text, color = "\x1B[1;33m") {
8050
+ function addScorePopup2(x, y, text, color = "\x1B[1;33m") {
8051
8051
  scorePopups.push({ x, y, text, frames: 20, color });
8052
8052
  }
8053
- function triggerShake(frames, intensity) {
8053
+ function triggerShake2(frames, intensity) {
8054
8054
  shakeFrames = frames;
8055
8055
  shakeIntensity = intensity;
8056
8056
  }
@@ -8107,12 +8107,12 @@ function runSimonGame(terminal) {
8107
8107
  score += currentRound * 10;
8108
8108
  const centerX = GAME_WIDTH / 2;
8109
8109
  const centerY = GAME_HEIGHT / 2;
8110
- addScorePopup(centerX - 2, centerY - 2, `+${currentRound * 10}`, "\x1B[1;92m");
8111
- spawnParticles2(centerX, centerY, 20, "\x1B[1;92m", ["\u2726", "\u2605", "\u2606", "\u25C8"]);
8110
+ addScorePopup2(centerX - 2, centerY - 2, `+${currentRound * 10}`, "\x1B[1;92m");
8111
+ spawnParticles3(centerX, centerY, 20, "\x1B[1;92m", ["\u2726", "\u2605", "\u2606", "\u25C8"]);
8112
8112
  statusMessage = "PATTERN ACCEPTED";
8113
8113
  statusColor = "\x1B[1;92m";
8114
8114
  statusBlink = true;
8115
- triggerShake(6, 1);
8115
+ triggerShake2(6, 1);
8116
8116
  }
8117
8117
  } else {
8118
8118
  phase = "failure";
@@ -8124,10 +8124,10 @@ function runSimonGame(terminal) {
8124
8124
  statusMessage = "ACCESS DENIED";
8125
8125
  statusColor = "\x1B[1;91m";
8126
8126
  statusBlink = true;
8127
- triggerShake(15, 3);
8127
+ triggerShake2(15, 3);
8128
8128
  const centerX = GAME_WIDTH / 2;
8129
8129
  const centerY = GAME_HEIGHT / 2;
8130
- spawnParticles2(centerX, centerY, 15, "\x1B[1;91m", ["\u2717", "\u2716", "\xD7", "\u2573"]);
8130
+ spawnParticles3(centerX, centerY, 15, "\x1B[1;91m", ["\u2717", "\u2716", "\xD7", "\u2573"]);
8131
8131
  }
8132
8132
  }
8133
8133
  function update() {
@@ -8605,7 +8605,7 @@ function runSnakeGame(terminal) {
8605
8605
  attempts++;
8606
8606
  } while (snake.some((s) => s.x === food.x && s.y === food.y) && attempts < 100);
8607
8607
  }
8608
- function spawnParticles2(x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
8608
+ function spawnParticles3(x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
8609
8609
  for (let i = 0; i < count; i++) {
8610
8610
  const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
8611
8611
  const speed = 0.3 + Math.random() * 0.4;
@@ -8621,7 +8621,7 @@ function runSnakeGame(terminal) {
8621
8621
  });
8622
8622
  }
8623
8623
  }
8624
- function updateParticles2() {
8624
+ function updateParticles3() {
8625
8625
  for (let i = particles.length - 1; i >= 0; i--) {
8626
8626
  const p = particles[i];
8627
8627
  p.x += p.vx;
@@ -8646,7 +8646,7 @@ function runSnakeGame(terminal) {
8646
8646
  scorePopup.y -= 0.3;
8647
8647
  if (scorePopup.frames <= 0) scorePopup = null;
8648
8648
  }
8649
- updateParticles2();
8649
+ updateParticles3();
8650
8650
  let renderGameLeft = gameLeft;
8651
8651
  let renderGameTop = gameTop;
8652
8652
  if (shakeFrames > 0) {
@@ -8797,7 +8797,7 @@ function runSnakeGame(terminal) {
8797
8797
  shakeFrames = 20;
8798
8798
  shakeIntensity = 3;
8799
8799
  deathFlashFrames = 30;
8800
- spawnParticles2(snake[0].x, snake[0].y, 12, "\x1B[1;31m", ["\u2717", "\u2620", "\xD7", "\u2592"]);
8800
+ spawnParticles3(snake[0].x, snake[0].y, 12, "\x1B[1;31m", ["\u2717", "\u2620", "\xD7", "\u2592"]);
8801
8801
  comboCount = 0;
8802
8802
  return;
8803
8803
  }
@@ -8807,7 +8807,7 @@ function runSnakeGame(terminal) {
8807
8807
  shakeFrames = 20;
8808
8808
  shakeIntensity = 3;
8809
8809
  deathFlashFrames = 30;
8810
- spawnParticles2(snake[0].x, snake[0].y, 12, "\x1B[1;31m", ["\u2717", "\u2620", "\xD7", "\u2592"]);
8810
+ spawnParticles3(snake[0].x, snake[0].y, 12, "\x1B[1;31m", ["\u2717", "\u2620", "\xD7", "\u2592"]);
8811
8811
  comboCount = 0;
8812
8812
  return;
8813
8813
  }
@@ -8835,7 +8835,7 @@ function runSnakeGame(terminal) {
8835
8835
  frames: 20
8836
8836
  };
8837
8837
  const particleCount = 4 + Math.min(comboCount * 2, 10);
8838
- spawnParticles2(food.x, food.y, particleCount, "\x1B[1;33m", ["\u2726", "\u2605", "\u25C6", "\u2666"]);
8838
+ spawnParticles3(food.x, food.y, particleCount, "\x1B[1;33m", ["\u2726", "\u2605", "\u25C6", "\u2666"]);
8839
8839
  spawnFood();
8840
8840
  } else {
8841
8841
  snake.pop();
@@ -9060,7 +9060,7 @@ function runSpaceInvadersGame(terminal) {
9060
9060
  ["|=|", "|#|"]
9061
9061
  // Type 2 - top rows
9062
9062
  ];
9063
- function spawnParticles2(x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
9063
+ function spawnParticles3(x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
9064
9064
  for (let i = 0; i < count; i++) {
9065
9065
  const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
9066
9066
  const speed = 0.2 + Math.random() * 0.4;
@@ -9075,7 +9075,7 @@ function runSpaceInvadersGame(terminal) {
9075
9075
  });
9076
9076
  }
9077
9077
  }
9078
- function addScorePopup(x, y, text, color = "\x1B[1;33m") {
9078
+ function addScorePopup2(x, y, text, color = "\x1B[1;33m") {
9079
9079
  scorePopups.push({ x, y, text, frames: 18, color });
9080
9080
  }
9081
9081
  function initGame() {
@@ -9400,10 +9400,10 @@ function runSpaceInvadersGame(terminal) {
9400
9400
  shakeFrames = 3 + Math.min(killStreakCount, 5);
9401
9401
  shakeIntensity = 1 + Math.floor(killStreakCount / 3);
9402
9402
  const invaderColors = ["\x1B[1;92m", "\x1B[1;93m", "\x1B[1;95m"];
9403
- spawnParticles2(invader.x + 1, invader.y, 6 + Math.min(killStreakCount, 6), invaderColors[invader.type], ["\u2726", "\u2605", "\u25C6", "\xD7"]);
9403
+ spawnParticles3(invader.x + 1, invader.y, 6 + Math.min(killStreakCount, 6), invaderColors[invader.type], ["\u2726", "\u2605", "\u25C6", "\xD7"]);
9404
9404
  const popupText = killStreakCount >= 3 ? `+${totalScore}!` : `+${totalScore}`;
9405
9405
  const popupColor = killStreakCount >= 3 ? "\x1B[1;91m" : "\x1B[1;93m";
9406
- addScorePopup(invader.x + 1, invader.y - 1, popupText, popupColor);
9406
+ addScorePopup2(invader.x + 1, invader.y - 1, popupText, popupColor);
9407
9407
  }
9408
9408
  }
9409
9409
  }
@@ -9431,13 +9431,13 @@ function runSpaceInvadersGame(terminal) {
9431
9431
  shakeIntensity = 3;
9432
9432
  hitFlashFrames = 15;
9433
9433
  killStreakCount = 0;
9434
- spawnParticles2(Math.floor(playerX), playerY, 10, "\x1B[1;91m", ["\u2717", "\u2620", "\xD7", "\u2592"]);
9434
+ spawnParticles3(Math.floor(playerX), playerY, 10, "\x1B[1;91m", ["\u2717", "\u2620", "\xD7", "\u2592"]);
9435
9435
  if (lives <= 0) {
9436
9436
  gameOver = true;
9437
9437
  gameOverFlashFrames = 30;
9438
9438
  shakeFrames = 20;
9439
9439
  shakeIntensity = 4;
9440
- spawnParticles2(Math.floor(playerX), playerY, 15, "\x1B[1;91m", ["\u2717", "\u2620", "\xD7", "\u2593", "\u2591"]);
9440
+ spawnParticles3(Math.floor(playerX), playerY, 15, "\x1B[1;91m", ["\u2717", "\u2620", "\xD7", "\u2593", "\u2591"]);
9441
9441
  if (score > highScore) highScore = score;
9442
9442
  }
9443
9443
  }
@@ -10416,7 +10416,7 @@ function runTowerGame(terminal) {
10416
10416
  "\u2580\u2588\u2580 \u2588\u2580\u2588 \u2588 \u2588 \u2588 \u2588\u2580\u2580 \u2588\u2580\u2588",
10417
10417
  " \u2588 \u2588\u2584\u2588 \u2580\u2584\u2580\u2584\u2580 \u2588\u2588\u2584 \u2588\u2580\u2584"
10418
10418
  ];
10419
- function spawnParticles2(x, y, count, color) {
10419
+ function spawnParticles3(x, y, count, color) {
10420
10420
  const chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"];
10421
10421
  for (let i = 0; i < count; i++) {
10422
10422
  const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
@@ -10443,10 +10443,10 @@ function runTowerGame(terminal) {
10443
10443
  vy: 0.1
10444
10444
  });
10445
10445
  }
10446
- function addScorePopup(x, y, text, color = "\x1B[1;33m") {
10446
+ function addScorePopup2(x, y, text, color = "\x1B[1;33m") {
10447
10447
  scorePopups.push({ x, y, text, frames: 24, color });
10448
10448
  }
10449
- function triggerShake(frames, intensity) {
10449
+ function triggerShake2(frames, intensity) {
10450
10450
  shakeFrames = frames;
10451
10451
  shakeIntensity = intensity;
10452
10452
  }
@@ -10506,8 +10506,8 @@ function runTowerGame(terminal) {
10506
10506
  gameOver = true;
10507
10507
  if (score > highScore) highScore = score;
10508
10508
  if (perfectCombo > maxCombo) maxCombo = perfectCombo;
10509
- spawnParticles2(dropX + dropWidth / 2, landY, 15, "\x1B[91m");
10510
- triggerShake(10, 3);
10509
+ spawnParticles3(dropX + dropWidth / 2, landY, 15, "\x1B[91m");
10510
+ triggerShake2(10, 3);
10511
10511
  return;
10512
10512
  }
10513
10513
  const isPerfect = Math.abs(dropLeft - topLeft) < PERFECT_THRESHOLD && Math.abs(dropRight - topRight) < PERFECT_THRESHOLD;
@@ -10517,34 +10517,34 @@ function runTowerGame(terminal) {
10517
10517
  const comboBonus = Math.min(perfectCombo * 5, 50);
10518
10518
  points += 10 + comboBonus;
10519
10519
  flashFrames = 6;
10520
- spawnParticles2(dropX + dropWidth / 2, landY, 12, "\x1B[93m");
10520
+ spawnParticles3(dropX + dropWidth / 2, landY, 12, "\x1B[93m");
10521
10521
  const popupText = perfectCombo > 1 ? `PERFECT! x${perfectCombo}` : "PERFECT!";
10522
- addScorePopup(
10522
+ addScorePopup2(
10523
10523
  Math.floor(GAME_WIDTH / 2) - Math.floor(popupText.length / 2),
10524
10524
  Math.floor(GAME_HEIGHT / 2),
10525
10525
  popupText,
10526
10526
  perfectCombo > 3 ? "\x1B[1;91m" : "\x1B[1;93m"
10527
10527
  );
10528
- triggerShake(4, 1);
10528
+ triggerShake2(4, 1);
10529
10529
  } else {
10530
10530
  if (perfectCombo > maxCombo) maxCombo = perfectCombo;
10531
10531
  perfectCombo = 0;
10532
10532
  if (dropLeft < topLeft) {
10533
10533
  const overhangWidth = topLeft - dropLeft;
10534
10534
  spawnFallingPiece(dropLeft, landY, overhangWidth, dropColor);
10535
- spawnParticles2(dropLeft + overhangWidth / 2, landY, 5, dropColor);
10535
+ spawnParticles3(dropLeft + overhangWidth / 2, landY, 5, dropColor);
10536
10536
  }
10537
10537
  if (dropRight > topRight) {
10538
10538
  const overhangWidth = dropRight - topRight;
10539
10539
  spawnFallingPiece(topRight, landY, overhangWidth, dropColor);
10540
- spawnParticles2(topRight + overhangWidth / 2, landY, 5, dropColor);
10540
+ spawnParticles3(topRight + overhangWidth / 2, landY, 5, dropColor);
10541
10541
  }
10542
- triggerShake(3, 1);
10542
+ triggerShake2(3, 1);
10543
10543
  }
10544
10544
  score += points;
10545
10545
  height++;
10546
10546
  if (points > 10) {
10547
- addScorePopup(overlapLeft + overlapWidth / 2, landY - 1, `+${points}`, "\x1B[92m");
10547
+ addScorePopup2(overlapLeft + overlapWidth / 2, landY - 1, `+${points}`, "\x1B[92m");
10548
10548
  }
10549
10549
  tower.push({
10550
10550
  x: overlapLeft,
@@ -10910,7 +10910,7 @@ function runTronGame(terminal) {
10910
10910
  "\u2588 \u2588 \u2588\u2584\u2588 \u2588\u2580\u2588 \u2588\u2580\u2580 \u2588\u2580\u2588 \u2580\u2588\u2580 \u2588\u2580\u2588 \u2588\u2580\u2588 \u2588\u2584 \u2588",
10911
10911
  "\u2588\u2580\u2588 \u2588 \u2588\u2580\u2580 \u2588\u2588\u2584 \u2588\u2580\u2584 \u2588 \u2588\u2580\u2584 \u2588\u2584\u2588 \u2588 \u2580\u2588"
10912
10912
  ];
10913
- function spawnParticles2(x, y, count, color, chars = ["\u2591", "\u2592", "\u2593", "\u2588", "\u25C6"]) {
10913
+ function spawnParticles3(x, y, count, color, chars = ["\u2591", "\u2592", "\u2593", "\u2588", "\u25C6"]) {
10914
10914
  for (let i = 0; i < count; i++) {
10915
10915
  const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
10916
10916
  const speed = 0.3 + Math.random() * 0.5;
@@ -10926,10 +10926,10 @@ function runTronGame(terminal) {
10926
10926
  }
10927
10927
  }
10928
10928
  function spawnExplosion(x, y, color) {
10929
- spawnParticles2(x, y, 20, color, ["\u2717", "\xD7", "\u2591", "\u2592", "\u2593", "\u2588"]);
10930
- triggerShake(12, 3);
10929
+ spawnParticles3(x, y, 20, color, ["\u2717", "\xD7", "\u2591", "\u2592", "\u2593", "\u2588"]);
10930
+ triggerShake2(12, 3);
10931
10931
  }
10932
- function triggerShake(frames, intensity) {
10932
+ function triggerShake2(frames, intensity) {
10933
10933
  shakeFrames = frames;
10934
10934
  shakeIntensity = intensity;
10935
10935
  }
@@ -11144,7 +11144,7 @@ function runTronGame(terminal) {
11144
11144
  arenaMinY += SHRINK_AMOUNT;
11145
11145
  arenaMaxY -= SHRINK_AMOUNT;
11146
11146
  }
11147
- triggerShake(4, 1);
11147
+ triggerShake2(4, 1);
11148
11148
  }
11149
11149
  }
11150
11150
  }
@@ -11779,7 +11779,7 @@ function runTypingTest(terminal) {
11779
11779
  borderFlash = 0;
11780
11780
  errorFlash = 0;
11781
11781
  }
11782
- function spawnParticles2(x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
11782
+ function spawnParticles3(x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
11783
11783
  for (let i = 0; i < count; i++) {
11784
11784
  const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
11785
11785
  const speed = 0.2 + Math.random() * 0.3;
@@ -11794,7 +11794,7 @@ function runTypingTest(terminal) {
11794
11794
  });
11795
11795
  }
11796
11796
  }
11797
- function addScorePopup(x, y, text, color = "\x1B[1;33m") {
11797
+ function addScorePopup2(x, y, text, color = "\x1B[1;33m") {
11798
11798
  scorePopups.push({ x, y, text, frames: 18, color });
11799
11799
  }
11800
11800
  function calculateStats() {
@@ -11833,16 +11833,16 @@ function runTypingTest(terminal) {
11833
11833
  correctStreak++;
11834
11834
  if (correctStreak >= 5 && correctStreak % 5 === 0) {
11835
11835
  borderFlash = 6;
11836
- spawnParticles2(cursorX, textY, 4 + Math.floor(correctStreak / 5), "\x1B[1;92m", ["\u2726", "\u2605", "\u25C6"]);
11837
- addScorePopup(cursorX, textY - 1, `${correctStreak}!`, "\x1B[1;96m");
11836
+ spawnParticles3(cursorX, textY, 4 + Math.floor(correctStreak / 5), "\x1B[1;92m", ["\u2726", "\u2605", "\u25C6"]);
11837
+ addScorePopup2(cursorX, textY - 1, `${correctStreak}!`, "\x1B[1;96m");
11838
11838
  } else if (correctStreak >= 10) {
11839
11839
  if (Math.random() < 0.3) {
11840
- spawnParticles2(cursorX, textY, 2, "\x1B[1;92m", ["\xB7", "\u2022", "\u25CB"]);
11840
+ spawnParticles3(cursorX, textY, 2, "\x1B[1;92m", ["\xB7", "\u2022", "\u25CB"]);
11841
11841
  }
11842
11842
  }
11843
11843
  if (char === " " || typedText.length === currentText.length) {
11844
11844
  wordsCompleted++;
11845
- spawnParticles2(cursorX - 2, textY, 3, "\x1B[1;96m", ["\u2726", "\xB7", "\u25CB"]);
11845
+ spawnParticles3(cursorX - 2, textY, 3, "\x1B[1;96m", ["\u2726", "\xB7", "\u25CB"]);
11846
11846
  }
11847
11847
  if (typedText.length >= currentText.length - 20) {
11848
11848
  if (mode === "words") {
@@ -11858,7 +11858,7 @@ function runTypingTest(terminal) {
11858
11858
  correctStreak = 0;
11859
11859
  errorFlash = 6;
11860
11860
  screenShake = 3;
11861
- spawnParticles2(cursorX, textY, 3, "\x1B[1;91m", ["\u2717", "\xD7", "\xB7"]);
11861
+ spawnParticles3(cursorX, textY, 3, "\x1B[1;91m", ["\u2717", "\xD7", "\xB7"]);
11862
11862
  }
11863
11863
  }
11864
11864
  function handleBackspace() {
@@ -12602,7 +12602,7 @@ function runWordleGame(terminal) {
12602
12602
  "\u2588 \u2588 \u2588\u2584\u2588 \u2588\u2580\u2588 \u2588\u2580\u2580 \u2588\u2580\u2588 \u2588 \u2588 \u2588 \u2588\u2580\u2588 \u2588\u2580\u2588 \u2588\u2580\u2584 \u2588 \u2588\u2580\u2580",
12603
12603
  "\u2588\u2580\u2588 \u2588 \u2588\u2580\u2580 \u2588\u2588\u2584 \u2588\u2580\u2584 \u2580\u2584\u2580\u2584\u2580 \u2588\u2584\u2588 \u2588\u2580\u2584 \u2588\u2584\u2580 \u2588\u2584\u2584 \u2588\u2588\u2584"
12604
12604
  ];
12605
- function spawnParticles2(x, y, count, color, chars = ["*", "+", "o", "."]) {
12605
+ function spawnParticles3(x, y, count, color, chars = ["*", "+", "o", "."]) {
12606
12606
  for (let i = 0; i < count; i++) {
12607
12607
  const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
12608
12608
  const speed = 0.3 + Math.random() * 0.5;
@@ -12617,7 +12617,7 @@ function runWordleGame(terminal) {
12617
12617
  });
12618
12618
  }
12619
12619
  }
12620
- function spawnFirework2(x, y) {
12620
+ function spawnFirework3(x, y) {
12621
12621
  const colors = ["\x1B[1;92m", "\x1B[1;93m", "\x1B[1;96m", "\x1B[1;95m"];
12622
12622
  const color = colors[Math.floor(Math.random() * colors.length)];
12623
12623
  const chars = ["*", "+", "o", ".", "`", "'"];
@@ -12635,10 +12635,10 @@ function runWordleGame(terminal) {
12635
12635
  });
12636
12636
  }
12637
12637
  }
12638
- function addScorePopup(x, y, text, color = "\x1B[1;33m") {
12638
+ function addScorePopup2(x, y, text, color = "\x1B[1;33m") {
12639
12639
  scorePopups.push({ x, y, text, frames: 25, color });
12640
12640
  }
12641
- function triggerShake(frames, intensity) {
12641
+ function triggerShake2(frames, intensity) {
12642
12642
  shakeFrames = frames;
12643
12643
  shakeIntensity = intensity;
12644
12644
  }
@@ -12696,8 +12696,8 @@ function runWordleGame(terminal) {
12696
12696
  }
12697
12697
  function submitGuess() {
12698
12698
  if (currentGuess.length !== WORD_LENGTH) {
12699
- triggerShake(4, 2);
12700
- addScorePopup(Math.floor(cols / 2), 8, "NOT ENOUGH LETTERS", "\x1B[1;91m");
12699
+ triggerShake2(4, 2);
12700
+ addScorePopup2(Math.floor(cols / 2), 8, "NOT ENOUGH LETTERS", "\x1B[1;91m");
12701
12701
  return;
12702
12702
  }
12703
12703
  const result = checkGuess(currentGuess);
@@ -12722,15 +12722,15 @@ function runWordleGame(terminal) {
12722
12722
  }
12723
12723
  stats.guessDistribution[guesses.length - 1]++;
12724
12724
  borderFlash = 20;
12725
- triggerShake(10, 3);
12725
+ triggerShake2(10, 3);
12726
12726
  const messages = ["CIPHER BREACHED!", "CODE CRACKED!", "DECRYPTED!", "BRILLIANT!"];
12727
- addScorePopup(centerX, guessY - 2, messages[Math.floor(Math.random() * messages.length)], "\x1B[1;92m");
12727
+ addScorePopup2(centerX, guessY - 2, messages[Math.floor(Math.random() * messages.length)], "\x1B[1;92m");
12728
12728
  setTimeout(() => {
12729
12729
  if (running) {
12730
12730
  for (let i = 0; i < 5; i++) {
12731
12731
  setTimeout(() => {
12732
12732
  if (running && won) {
12733
- spawnFirework2(
12733
+ spawnFirework3(
12734
12734
  10 + Math.random() * (cols - 20),
12735
12735
  5 + Math.random() * 10
12736
12736
  );
@@ -12743,15 +12743,15 @@ function runWordleGame(terminal) {
12743
12743
  gameOver = true;
12744
12744
  stats.gamesPlayed++;
12745
12745
  stats.currentStreak = 0;
12746
- triggerShake(8, 4);
12746
+ triggerShake2(8, 4);
12747
12747
  borderFlash = 15;
12748
- addScorePopup(centerX, guessY - 2, "DECRYPTION FAILED", "\x1B[1;91m");
12749
- spawnParticles2(centerX, guessY, 10, "\x1B[1;91m", ["X", "x", ".", "*"]);
12748
+ addScorePopup2(centerX, guessY - 2, "DECRYPTION FAILED", "\x1B[1;91m");
12749
+ spawnParticles3(centerX, guessY, 10, "\x1B[1;91m", ["X", "x", ".", "*"]);
12750
12750
  } else {
12751
12751
  if (correctCount > 0 || presentCount > 0) {
12752
12752
  const hint = correctCount > 0 ? `${correctCount} EXACT` : `${presentCount} CLOSE`;
12753
- addScorePopup(centerX, guessY - 1, hint, correctCount > 0 ? "\x1B[1;92m" : "\x1B[1;93m");
12754
- spawnParticles2(centerX, guessY, 3 + correctCount * 2, correctCount > 0 ? "\x1B[1;92m" : "\x1B[1;93m");
12753
+ addScorePopup2(centerX, guessY - 1, hint, correctCount > 0 ? "\x1B[1;92m" : "\x1B[1;93m");
12754
+ spawnParticles3(centerX, guessY, 3 + correctCount * 2, correctCount > 0 ? "\x1B[1;92m" : "\x1B[1;93m");
12755
12755
  }
12756
12756
  }
12757
12757
  currentGuess = "";
@@ -13118,7 +13118,7 @@ function runWordleGame(terminal) {
13118
13118
  submitGuess();
13119
13119
  } else if (key.length === 1 && /[a-zA-Z]/.test(key) && currentGuess.length < WORD_LENGTH) {
13120
13120
  currentGuess += key.toUpperCase();
13121
- spawnParticles2(
13121
+ spawnParticles3(
13122
13122
  Math.floor(cols / 2) - 8 + currentGuess.length * 4,
13123
13123
  4 + guesses.length * 2,
13124
13124
  2,
@@ -13667,11 +13667,14 @@ function launchGame(terminal, game) {
13667
13667
  }
13668
13668
  function printHelp() {
13669
13669
  console.log(`
13670
- @hypersocial/cli-games \u2014 18 terminal games
13670
+ @hypersocial/cli-games \u2014 Terminal games
13671
13671
 
13672
13672
  Usage:
13673
13673
  cli-games Interactive game menu
13674
13674
  cli-games <game> Launch a game directly
13675
+ cli-games vibe Developer hub (create, vibe code, play, remove, PR)
13676
+ cli-games vibe <name> Vibe code a game (creates it if new)
13677
+ cli-games remove <name> Remove a game
13675
13678
  cli-games --theme <theme> Set color theme
13676
13679
  cli-games --list List all games
13677
13680
  cli-games --help Show this help
@@ -13731,5 +13734,12 @@ function main() {
13731
13734
  }
13732
13735
  openMenu(terminal);
13733
13736
  }
13734
- main();
13737
+ var cliArgs = process.argv.slice(2);
13738
+ if (cliArgs[0] === "vibe" || cliArgs[0] === "create") {
13739
+ import("./create-NVLKKJX6.js").then((m) => m.vibeCommand(cliArgs.slice(1)));
13740
+ } else if (cliArgs[0] === "remove") {
13741
+ import("./create-NVLKKJX6.js").then((m) => m.removeCommand(cliArgs.slice(1)));
13742
+ } else {
13743
+ main();
13744
+ }
13735
13745
  //# sourceMappingURL=cli.js.map