xabbo-scripts/Sirjonas-Snake.csx
Administrator b6c31a7feb Add 165 scripts from desktop collection + update README
Added scripts from C:\Users\ploet\Desktop\Habbo\Xabbo Scripte:
- 39 KI/Chatbot scripts (ChatGPT, Gemini, Grok, DeepSeek, Ollama)
- Game solvers (Domino, Dodgeball, Obsidian Maze, IceBall)
- Collision avoidance bots (5 versions)
- Plant/breeding automation (12 scripts)
- Trading tools, packet debuggers, room utilities
- Navigation & teleport helpers

Removed: 9 files (3 empty, 2 trivial, 4 cross-duplicates)
Updated README with full categorized index of all 230+ scripts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 09:47:56 +01:00

226 lines
6.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
const int GAME_MIN_X = 9;
const int GAME_MAX_X = 28;
const int GAME_MIN_Y = 11;
const int GAME_MAX_Y = 30;
const int BLOCKED_MIN_X = 17;
const int BLOCKED_MAX_X = 20;
const int BLOCKED_MIN_Y = 19;
const int BLOCKED_MAX_Y = 22;
const int KIND_SNAKE = 7100;
const int KIND_FOOD = 5068;
const int CTRL_UP = 2147418172;
const int CTRL_RIGHT = 2147418173;
const int CTRL_DOWN = 2147418174;
const int CTRL_LEFT = 2147418175;
List<(int x, int y)> body = new List<(int x, int y)>();
HashSet<(int x, int y)> prevSnake = new HashSet<(int x, int y)>();
(int x, int y) head = (-1, -1);
string dir = "DOWN";
string targetDir = "";
DateTime lastCmd = DateTime.MinValue;
int length = 0;
int GetKind(dynamic item) { try { return (int)item.Kind; } catch { return -1; } }
bool IsWall(int x, int y) => x < GAME_MIN_X || x > GAME_MAX_X || y < GAME_MIN_Y || y > GAME_MAX_Y;
bool IsBlocked(int x, int y) => x >= BLOCKED_MIN_X && x <= BLOCKED_MAX_X && y >= BLOCKED_MIN_Y && y <= BLOCKED_MAX_Y;
bool Bad(int x, int y)
{
if (IsWall(x, y)) return true;
if (IsBlocked(x, y)) return true;
for (int i = 0; i < body.Count - 1; i++)
if (body[i].x == x && body[i].y == y) return true;
return false;
}
bool BadFull(int x, int y)
{
if (IsWall(x, y)) return true;
if (IsBlocked(x, y)) return true;
foreach (var p in body)
if (p.x == x && p.y == y) return true;
return false;
}
(int, int) Next(int x, int y, string d)
{
if (d == "UP") return (x, y - 1);
if (d == "DOWN") return (x, y + 1);
if (d == "LEFT") return (x - 1, y);
if (d == "RIGHT") return (x + 1, y);
return (x, y);
}
string Opp(string d) => d == "UP" ? "DOWN" : d == "DOWN" ? "UP" : d == "LEFT" ? "RIGHT" : "LEFT";
int Fill(int sx, int sy)
{
if (BadFull(sx, sy)) return 0;
var v = new HashSet<(int, int)> { (sx, sy) };
var q = new Queue<(int, int)>();
q.Enqueue((sx, sy));
int c = 0;
while (q.Count > 0 && c < 200)
{
var (x, y) = q.Dequeue();
c++;
foreach (var (nx, ny) in new[] { (x, y-1), (x, y+1), (x-1, y), (x+1, y) })
if (!v.Contains((nx, ny)) && !BadFull(nx, ny)) { v.Add((nx, ny)); q.Enqueue((nx, ny)); }
}
return c;
}
void Cmd(string d)
{
if (d == "UP") Send(Out["ClickFurni"], CTRL_UP, 0);
else if (d == "DOWN") Send(Out["ClickFurni"], CTRL_DOWN, 0);
else if (d == "LEFT") Send(Out["ClickFurni"], CTRL_LEFT, 0);
else if (d == "RIGHT") Send(Out["ClickFurni"], CTRL_RIGHT, 0);
lastCmd = DateTime.Now;
}
string Best(int hx, int hy, int fx, int fy, string cur)
{
string opp = Opp(cur);
var results = new List<(string d, bool safe, int dist, int space)>();
foreach (var d in new[] { "UP", "DOWN", "LEFT", "RIGHT" })
{
if (d == opp) continue;
var (nx, ny) = Next(hx, hy, d);
bool hitBody = false;
for (int i = 0; i < body.Count - 1; i++)
if (body[i].x == nx && body[i].y == ny) { hitBody = true; break; }
if (IsWall(nx, ny) || IsBlocked(nx, ny) || hitBody) continue;
int space = Fill(nx, ny);
int dist = Math.Abs(fx - nx) + Math.Abs(fy - ny);
bool safe = space >= length + 3;
results.Add((d, safe, dist, space));
}
if (results.Count == 0) return cur;
var safeOpts = results.Where(r => r.safe).ToList();
if (safeOpts.Count > 0)
return safeOpts.OrderBy(r => r.dist).First().d;
return results.OrderByDescending(r => r.space).First().d;
}
Log("═══════════════════════════════════════════");
Log(" SNAKE BOT V7 - Self Body Tracking");
Log("═══════════════════════════════════════════");
while (Run)
{
Delay(10);
var snake = new HashSet<(int x, int y)>();
foreach (var item in FloorItems)
{
if (item == null) continue;
int x = item.Location.X;
int y = item.Location.Y;
if (IsWall(x, y)) continue;
int k = GetKind(item);
if (k == KIND_SNAKE) snake.Add((x, y));
}
if (snake.Count == 0)
{
body.Clear();
head = (-1, -1);
continue;
}
length = snake.Count;
var newP = snake.Except(prevSnake).ToList();
var removed = prevSnake.Except(snake).ToList();
bool moved = newP.Count == 1;
if (moved)
{
var nh = newP[0];
if (head.x != -1)
{
int dx = nh.x - head.x;
int dy = nh.y - head.y;
if (dy == -1) dir = "UP";
else if (dy == 1) dir = "DOWN";
else if (dx == -1) dir = "LEFT";
else if (dx == 1) dir = "RIGHT";
}
head = nh;
body.Insert(0, head);
while (body.Count > length) body.RemoveAt(body.Count - 1);
targetDir = "";
}
else if (prevSnake.Count == 0)
{
head = snake.OrderByDescending(p => p.y).First();
dir = "UP";
body = snake.OrderByDescending(p => p.y).ToList();
Log($"[INIT] Len:{length} Head:X{head.x},Y{head.y}");
}
prevSnake = new HashSet<(int x, int y)>(snake);
if (head.x == -1) continue;
int fx = -1, fy = -1;
foreach (var item in FloorItems)
{
if (item == null) continue;
if (GetKind(item) == KIND_FOOD)
{
fx = item.Location.X;
fy = item.Location.Y;
break;
}
}
if (fx == -1) continue;
if (moved || targetDir == "")
{
targetDir = Best(head.x, head.y, fx, fy, dir);
if (targetDir != dir)
Log($"[{length}] X{head.x},Y{head.y} {dir}->{targetDir} F:X{fx},Y{fy}");
}
var (nx, ny) = Next(head.x, head.y, dir);
bool danger = IsWall(nx, ny) || IsBlocked(nx, ny);
for (int i = 0; i < body.Count - 1 && !danger; i++)
if (body[i].x == nx && body[i].y == ny) danger = true;
if (danger)
{
targetDir = Best(head.x, head.y, fx, fy, dir);
Cmd(targetDir);
Delay(3);
Cmd(targetDir);
Delay(3);
Cmd(targetDir);
Log($"[!!!] X{head.x},Y{head.y} DANGER! ->{targetDir}");
}
else if ((DateTime.Now - lastCmd).TotalMilliseconds > 20)
{
Cmd(targetDir);
}
}