mirror of
https://github.com/kolbytn/mindcraft.git
synced 2025-04-29 19:44:53 +02:00
178 lines
6.1 KiB
JavaScript
178 lines
6.1 KiB
JavaScript
import fs from 'fs';
|
|
import path from 'path';
|
|
import {proceduralGeneration} from "../../src/agent/tasks/construction_tasks.js";
|
|
|
|
//note 'main' (script to run generation of tasks) is at bottom of page
|
|
|
|
/**
|
|
* Helper function to initalize agent inventories
|
|
* @param blueprint
|
|
* @param agents
|
|
* @param evenlySplit - When true, splits materials evenly across inventories
|
|
* @returns {{}}
|
|
*/
|
|
function createInitialInventory(blueprint, agents, evenlySplit = true) {
|
|
const inventories = {};
|
|
const materialCounts = {};
|
|
let currentAgent = 0;
|
|
|
|
// Initialize inventories
|
|
for (let i = 0; i < agents; i++) {
|
|
inventories[i] = {'diamond_pickaxe': 1};
|
|
}
|
|
|
|
// Count materials in blueprint and replace ladder variants with "ladder"
|
|
for (const level of blueprint.levels) {
|
|
for (let rowIndex = 0; rowIndex < level.placement.length; rowIndex++) {
|
|
for (let blockIndex = 0; blockIndex < level.placement[rowIndex].length; blockIndex++) {
|
|
let block = level.placement[rowIndex][blockIndex];
|
|
|
|
if (block !== 'air') {
|
|
// Check if material contains 'door' or 'ladder' and convert appropriately
|
|
let materialKey = block;
|
|
if (block.includes('dark_oak_door')) {
|
|
materialKey = 'dark_oak_door';
|
|
} else if (block.includes('oak_door')) {
|
|
materialKey = 'oak_door';
|
|
} else if (block.includes('ladder')) {
|
|
materialKey = 'ladder';
|
|
level.placement[rowIndex][blockIndex] = 'ladder'; // Replace in blueprint
|
|
}
|
|
|
|
materialCounts[materialKey] = (materialCounts[materialKey] || 0) + 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (evenlySplit) {
|
|
// Distribute materials evenly among agents
|
|
for (const [material, count] of Object.entries(materialCounts)) {
|
|
const baseAmount = Math.floor(count / agents);
|
|
const remainder = count % agents;
|
|
|
|
// Give each agent the base amount
|
|
for (let i = 0; i < agents; i++) {
|
|
inventories[i][material] = baseAmount;
|
|
}
|
|
|
|
// Distribute remainder one by one to agents
|
|
for (let i = 0; i < remainder; i++) {
|
|
inventories[i][material]++;
|
|
}
|
|
}
|
|
} else {
|
|
// Original distribution - one material type to one agent
|
|
for (const [material, count] of Object.entries(materialCounts)) {
|
|
inventories[currentAgent][material] = count;
|
|
currentAgent = (currentAgent + 1) % agents;
|
|
}
|
|
}
|
|
|
|
for (let i = 0; i < agents; i++) {
|
|
inventories[i]['dirt'] = 128;
|
|
}
|
|
|
|
return inventories;
|
|
}
|
|
|
|
/**
|
|
* Helper function to allocate space for the blueprint based on the number of rooms
|
|
* @param rooms
|
|
* @returns {number}
|
|
*/
|
|
function calculateSpaceNeeded(rooms) {
|
|
const baseSize = 10;
|
|
const scaleFactor = Math.floor(rooms / 4) * 5;
|
|
return baseSize + scaleFactor;
|
|
}
|
|
|
|
/**
|
|
* MAIN GENERATION FUNCTION
|
|
*
|
|
* Varies agents, materials, room count, windows and carpets to create different complexities of construction tasks.
|
|
* @param variants is the number of variants within each complexity level you want.
|
|
* @returns The tasks as nested JSON {{}}
|
|
*/
|
|
function generateConstructionTasks(variants, agents) {
|
|
const materialLevels = 5;
|
|
const roomCounts = [4, 6, 8];
|
|
const windowStyles = [0, 1, 2];
|
|
const carpetStyles = [0, 1, 2];
|
|
const timeout = 600; // 10 min base
|
|
|
|
const tasks = {};
|
|
|
|
for (let m = 0; m < materialLevels; m++) {
|
|
for (let r = 0; r < roomCounts.length; r++) {
|
|
for (let w = 0; w < windowStyles.length; w++) {
|
|
for (let c = 0; c < carpetStyles.length; c++) {
|
|
for (let variant = 0; variant < variants; variant++) {
|
|
|
|
const rooms = roomCounts[r];
|
|
const spaceSize = calculateSpaceNeeded(rooms);
|
|
|
|
const blueprint = proceduralGeneration(
|
|
spaceSize,
|
|
spaceSize,
|
|
spaceSize,
|
|
rooms,
|
|
5,
|
|
5,
|
|
4,
|
|
5,
|
|
"air",
|
|
carpetStyles[c],
|
|
windowStyles[w],
|
|
m + 1
|
|
);
|
|
|
|
const taskName = `materials_${m}_rooms_${r}_window_${w}_carpet_${c}_variant_${variant}`;
|
|
|
|
tasks[taskName] = {
|
|
type: "construction",
|
|
goal: "Make a house with the blueprint",
|
|
conversation: "Let's share materials and make a house with the blueprint",
|
|
agent_count: agents,
|
|
initial_inventory: createInitialInventory(blueprint, agents),
|
|
timeout: timeout + (300 * r), // 5 minute per additional level of complexity
|
|
blueprint: blueprint,
|
|
|
|
};
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return tasks;
|
|
}
|
|
|
|
|
|
// const fs = require('fs');
|
|
// const path = require('path');
|
|
|
|
// Function to create directories and generate tasks
|
|
function setupTaskFiles(baseDirs, agentCounts, variants) {
|
|
baseDirs.forEach(base => {
|
|
if (!fs.existsSync(base)) {
|
|
fs.mkdirSync(base, { recursive: true });
|
|
}
|
|
|
|
agentCounts.forEach(count => {
|
|
const tasks = generateConstructionTasks(variants, count);
|
|
const filePath = path.join(base, `${count}agents.json`);
|
|
|
|
fs.writeFileSync(filePath, JSON.stringify(tasks, null, 2));
|
|
console.log(`Generated tasks saved to ${filePath}`);
|
|
});
|
|
});
|
|
}
|
|
|
|
const baseDirs = ['./train', './test'];
|
|
const agentCounts = [2, 3, 4, 5];
|
|
const variants = 5;
|
|
|
|
setupTaskFiles(baseDirs, agentCounts, variants);
|
|
|