Spaces:
Running
Running
File size: 2,904 Bytes
d8434c0 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | // /src/state/runStore.js
export const runStore = {
params: {
N: 100,
speed: 1.0,
seed: 1234
},
metrics: {
totalDistance: 0,
steps: 0,
timeElapsed: 0,
energy: 0
},
pointsCollected: 0,
points: [], // array of {x, y, collected: bool}
order: [], // order in which visitar (índices)
botPath: [], // punto por punto que sigue (incluye inicio)
startRun(params) {
this.params = { ...this.params, ...params };
this.resetMetrics();
this._initPoints();
this._computeOrder();
this.botPath = [this._startPosition()];
},
resetRun() {
this.metrics = {
totalDistance: 0,
steps: 0,
timeElapsed: 0,
energy: 0
};
this.pointsCollected = 0;
this.points.forEach(p => p.collected = false);
this.order = [];
this.botPath = [];
},
exportJSON() {
return JSON.stringify({
params: this.params,
metrics: this.metrics,
pointsCollected: this.pointsCollected,
order: this.order,
points: this.points
}, null, 2);
},
_initPoints() {
const { N, seed } = this.params;
this.points = [];
const rng = mulberry32(seed);
for (let i = 0; i < N; i++) {
this.points.push({
x: rng() * 1, // normalizar al espacio unitario [0,1]
y: rng() * 1,
collected: false
});
}
},
_startPosition() {
return { x: 0, y: 0 };
},
_computeOrder() {
// greedy nearest neighbor en espacio unitario
const pts = this.points;
const visited = new Set();
let cur = this._startPosition();
this.order = [];
for (let i = 0; i < pts.length; i++) {
let bestIdx = -1;
let bestD = Infinity;
pts.forEach((p, idx) => {
if (visited.has(idx)) return;
const dx = p.x - cur.x, dy = p.y - cur.y;
const d = dx*dx + dy*dy;
if (d < bestD) {
bestD = d;
bestIdx = idx;
}
});
if (bestIdx < 0) break;
visited.add(bestIdx);
this.order.push(bestIdx);
cur = { x: pts[bestIdx].x, y: pts[bestIdx].y };
}
},
recordStep(from, to) {
const dx = to.x - from.x, dy = to.y - from.y;
const dist = Math.hypot(dx, dy);
this.metrics.totalDistance += dist;
this.metrics.steps += 1;
// tiempo se puede acumular externo
this.botPath.push({ x: to.x, y: to.y });
},
markCollected(idx) {
this.points[idx].collected = true;
this.pointsCollected += 1;
},
finalize(timeElapsedSec, energyFactor = 1.0) {
this.metrics.timeElapsed = timeElapsedSec;
this.metrics.energy = this.metrics.totalDistance * energyFactor;
}
};
// PRNG auxiliar (por reproducibilidad)
function mulberry32(a) {
return function() {
var t = a += 0x6D2B79F5;
t = Math.imul(t ^ (t >>> 15), t | 1);
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
}
}
|