xabbo-scripts/B3R1 Solver.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

138 lines
6.1 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Xabbo.Core;
public struct Point : IEquatable<Point>
{
public int X { get; } public int Y { get; }
public Point(int x, int y) { X = x; Y = y; }
public bool Equals(Point other) => X == other.X && Y == other.Y;
public override bool Equals(object obj) => obj is Point other && Equals(other);
public override int GetHashCode() => HashCode.Combine(X, Y);
public override string ToString() => $"({X}, {Y})";
}
int pickupClickDelayMilliseconds = 25;
int placementDelayMilliseconds = 30;
var floorMap = new Dictionary<Point, List<IFloorItem>>();
var blockSourceIds = new Dictionary<string, long>();
var rowConstraints = new int[6, 4];
var colConstraints = new int[6, 4];
var hasCircleRow = new bool[6, 4];
var hasCircleCol = new bool[6, 4];
var grid = new int[6, 6];
string[] colors = { "Red", "Pink", "Blue", "Green" };
var blockNamesToColors = new Dictionary<string, int> {
{ "Großer Bauklotz 5", 0 }, { "Großer Bauklotz 4", 1 },
{ "Großer Bauklotz 11", 2 }, { "Großer Bauklotz 8", 3 }
};
Log("Sudoku Solver v11 Initialized.");
foreach (IFloorItem item in FloorItems) {
if (item == null) continue;
var p = new Point(item.Location.X, item.Location.Y);
if (!floorMap.ContainsKey(p)) floorMap[p] = new List<IFloorItem>();
floorMap[p].Add(item);
if (p.X == 19 && p.Y == 19 && blockNamesToColors.TryGetValue(item.GetName(), out int colorIndex)) {
blockSourceIds[colors[colorIndex].ToLower()] = item.Id;
}
}
if (blockSourceIds.Count < 4) { Log("ERROR: Could not find all four source blocks at (19,19)."); return; }
Func<Point, bool> hasCircleMarker = p =>
floorMap.TryGetValue(p, out var items) && items.Any(i => i.GetName() == "Nummernbauklotz") && items.Any(i => i.GetName().StartsWith("Großer Bauklotz"));
for (int i = 0; i < 6; i++) {
int y = 23 + i; int x = 23 + i;
int[][] rC = { new[] { 16, y }, new[] { 18, y }, new[] { 20, y }, new[] { 22, y } };
int[][] cC = { new[] { x, 16 }, new[] { x, 18 }, new[] { x, 20 }, new[] { x, 22 } };
for (int color = 0; color < 4; color++) {
var rP = new Point(rC[color][0], rC[color][1]);
if (floorMap.TryGetValue(rP, out var rI)) {
var t = rI.FirstOrDefault(it => it.GetName() == "Nummernbauklotz");
if (t != null) { rowConstraints[i, color] = t.State; hasCircleRow[i, color] = hasCircleMarker(rP); }
}
var cP = new Point(cC[color][0], cC[color][1]);
if (floorMap.TryGetValue(cP, out var cI)) {
var t = cI.FirstOrDefault(it => it.GetName() == "Nummernbauklotz");
if (t != null) { colConstraints[i, color] = t.State; hasCircleCol[i, color] = hasCircleMarker(cP); }
}
}
}
var initialPlacements = new HashSet<Point>();
for (int y = 0; y < 6; y++) for (int x = 0; x < 6; x++) {
grid[y, x] = -1;
var gP = new Point(23 + x, 23 + y);
if (floorMap.TryGetValue(gP, out var items)) {
var b = items.FirstOrDefault(i => i.GetName().StartsWith("Großer Bauklotz"));
if (b != null && blockNamesToColors.TryGetValue(b.GetName(), out int cV)) {
grid[y, x] = cV; initialPlacements.Add(new Point(x,y));
}
}
}
Func<int, int, bool> IsValid = (r, c) => {
var rowCounts = new int[4]; bool rowIsFull = true;
for (int i = 0; i < 6; i++) { if (grid[r, i] == -1) rowIsFull = false; else rowCounts[grid[r, i]]++; }
if (rowIsFull) {
for (int color = 0; color < 4; color++) {
if (rowCounts[color] != rowConstraints[r, color]) return false;
var indices = Enumerable.Range(0, 6).Where(i => grid[r,i] == color).ToList();
if(indices.Count > 1 && (hasCircleRow[r, color] != (indices.Last() - indices.First() + 1 == indices.Count))) return false;
}
} else { for (int color = 0; color < 4; color++) { if (rowCounts[color] > rowConstraints[r, color]) return false; } }
var colCounts = new int[4]; bool colIsFull = true;
for (int i = 0; i < 6; i++) { if (grid[i, c] == -1) colIsFull = false; else colCounts[grid[i, c]]++; }
if (colIsFull) {
for (int color = 0; color < 4; color++) {
if (colCounts[color] != colConstraints[c, color]) return false;
var indices = Enumerable.Range(0, 6).Where(i => grid[i,c] == color).ToList();
if(indices.Count > 1 && (hasCircleCol[c, color] != (indices.Last() - indices.First() + 1 == indices.Count))) return false;
}
} else { for (int color = 0; color < 4; color++) { if (colCounts[color] > colConstraints[c, color]) return false; } }
return true;
};
Func<bool> solve = null;
solve = () => {
int nextR = -1, nextC = -1;
for (int r = 0; r < 6; r++) for (int c = 0; c < 6; c++) if (grid[r, c] == -1) { nextR = r; nextC = c; goto found; }
found:;
if (nextR == -1) return true;
for (int color = 0; color < 4; color++) { grid[nextR, nextC] = color; if (IsValid(nextR, nextC) && solve()) return true; }
grid[nextR, nextC] = -1;
return false;
};
Log("\nSolving...");
if (solve()) {
Log("Solution found. Placing blocks...");
var placementsByColor = Enumerable.Range(0,4).ToDictionary(i => colors[i].ToLower(), i => new List<Point>());
for (int y = 0; y < 6; y++) for (int x = 0; x < 6; x++) {
if (!initialPlacements.Contains(new Point(x,y))) placementsByColor[colors[grid[y, x]].ToLower()].Add(new Point(x, y));
}
int totalPlacements = placementsByColor.Sum(kvp => kvp.Value.Count);
if (totalPlacements == 0) { Log("Puzzle is already solved."); }
else {
foreach(var kvp in placementsByColor.Where(kvp => kvp.Value.Any())) {
Log($"--- Placing {kvp.Value.Count} {kvp.Key.ToUpper()} blocks ---");
Send(Out["ClickFurni"], blockSourceIds[kvp.Key], 0); Delay(pickupClickDelayMilliseconds);
Send(Out["ClickFurni"], blockSourceIds[kvp.Key], 0); Delay(pickupClickDelayMilliseconds);
foreach(Point p in kvp.Value) {
Send(Out["MoveAvatar"], 23 + p.X, 23 + p.Y);
Delay(placementDelayMilliseconds);
}
}
Log($"\nPlaced {totalPlacements} blocks.");
}
} else {
Log("\nERROR: No solution found.");
}
Log("Execution complete.");