логика выделена в отдельный набор классов
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
/** Headless example: plays the game for many ticks with no browser/DOM involved at all — proves
|
||||
* GameStore/its entities (see src/game/entities) can run standalone, and demonstrates measuring
|
||||
* how often a player would need to act (pick a new target) per unit of simulated time.
|
||||
*
|
||||
* Run with: npx tsx scripts/simulate.ts [ticks] [tickSeconds]
|
||||
*/
|
||||
import { Rabbit } from '../src/game/entities/Rabbit';
|
||||
import { ResourceNode } from '../src/game/entities/ResourceNode';
|
||||
import { GameStore } from '../src/game/GameStore';
|
||||
|
||||
const totalTicks = Number(process.argv[2] ?? 1_000_000);
|
||||
const tickSeconds = Number(process.argv[3] ?? 0.1);
|
||||
const mapWidth = 1200;
|
||||
const mapHeight = 800;
|
||||
|
||||
const store = new GameStore();
|
||||
store.initialize(mapWidth, mapHeight);
|
||||
|
||||
// A minimal bot policy standing in for a player: keep whatever target is currently held as long
|
||||
// as it still exists; otherwise pick the nearest node or rabbit and hold it. Each such pick is
|
||||
// counted as one "user action" — a mouse click choosing a new thing to interact with.
|
||||
let actionCount = 0;
|
||||
|
||||
for (let i = 0; i < totalTicks; i++) {
|
||||
if (store.isDead)
|
||||
break;
|
||||
|
||||
const stillHoldingNode = store.heldNodeId !== null && store.nodes.some((node) => node.id === store.heldNodeId);
|
||||
const stillHoldingRabbit = store.heldRabbitId !== null && store.rabbits.some((rabbit) => rabbit.id === store.heldRabbitId);
|
||||
|
||||
if (!stillHoldingNode && !stillHoldingRabbit) {
|
||||
const nearestNode = ResourceNode.findNearestToPosition(store.nodes, store.character);
|
||||
const nearestRabbit = Rabbit.findNearestToPosition(store.rabbits, store.character);
|
||||
const nodeDistance = nearestNode ? Math.hypot(nearestNode.x - store.character.x, nearestNode.y - store.character.y) : Infinity;
|
||||
const rabbitDistance = nearestRabbit ? Math.hypot(nearestRabbit.x - store.character.x, nearestRabbit.y - store.character.y) : Infinity;
|
||||
|
||||
if (nearestNode && nodeDistance <= rabbitDistance) {
|
||||
store.holdNode(nearestNode.id);
|
||||
actionCount++;
|
||||
} else if (nearestRabbit) {
|
||||
store.holdRabbit(nearestRabbit.id);
|
||||
actionCount++;
|
||||
}
|
||||
}
|
||||
|
||||
store.tick(tickSeconds);
|
||||
}
|
||||
|
||||
const simulatedSeconds = totalTicks * tickSeconds;
|
||||
console.log(JSON.stringify({
|
||||
ticks: totalTicks,
|
||||
simulatedDay: Number((store.day + store.hour / 24).toFixed(2)),
|
||||
isDead: store.isDead,
|
||||
inventory: store.inventory,
|
||||
actionCount,
|
||||
actionsPerSimulatedMinute: Number((actionCount / (simulatedSeconds / 60)).toFixed(3)),
|
||||
}, null, 2));
|
||||
Reference in New Issue
Block a user