| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- {
- "version": "3.16",
- "name": "CaveZoneScout",
- "description": "Writes a cave-search program into an isolated child space, runs it, and captures the trace/report.",
- "steps": [
- {
- "id": "Tool_010_WriteMap",
- "tool": "WriteFile",
- "input": {
- "file_path": "=\"cave.json\"",
- "content": "=mapJson"
- },
- "next": "Tool_020_WriteSolver"
- },
- {
- "id": "Tool_020_WriteSolver",
- "tool": "WriteFile",
- "input": {
- "file_path": "=\"explore-cave.mjs\"",
- "content": "import fs from 'fs';\n\nconst cavePath = process.argv[2] || 'cave.json';\nconst cave = JSON.parse(fs.readFileSync(cavePath, 'utf8'));\nconst trace = [];\nconst seen = new Map();\nlet best = null;\n\nfunction scoreState(node, energy, crystals, path) {\n return (node === cave.goal ? 500 : 0) + (crystals * 11) + energy - path.length;\n}\n\nfunction remember(signature, score) {\n const prev = seen.get(signature) ?? -Infinity;\n if (prev >= score) return false;\n seen.set(signature, score);\n return true;\n}\n\nfunction explore(node, energy, crystals, path, visitedRooms) {\n const room = cave.rooms[node] || {};\n const nextVisitedRooms = new Set(visitedRooms);\n const gained = nextVisitedRooms.has(node) ? 0 : (room.crystals || 0);\n nextVisitedRooms.add(node);\n const nextCrystals = crystals + gained;\n const nextPath = [...path, node];\n const signature = [node, energy, nextCrystals, [...nextVisitedRooms].sort().join(',')].join('|');\n const score = scoreState(node, energy, nextCrystals, nextPath);\n if (!remember(signature, score)) return;\n\n trace.push(`visit=${node}; energy=${energy}; crystals=${nextCrystals}; path=${nextPath.join('>')}`);\n if (!best || score > best.score) {\n best = { node, energy, crystals: nextCrystals, path: nextPath, score };\n }\n if (node === cave.goal) return;\n\n const edges = (cave.tunnels[node] || []).slice().sort((a, b) => {\n const aReward = (cave.rooms[a.to]?.crystals || 0) - a.cost;\n const bReward = (cave.rooms[b.to]?.crystals || 0) - b.cost;\n return bReward - aReward;\n });\n\n for (const edge of edges) {\n if (energy < edge.cost) {\n trace.push(`skip=${node}->${edge.to}; reason=energy; need=${edge.cost}; have=${energy}`);\n continue;\n }\n const recharge = cave.rooms[edge.to]?.recharge || 0;\n explore(edge.to, energy - edge.cost + recharge, nextCrystals, nextPath, nextVisitedRooms);\n }\n}\n\nexplore(cave.start, cave.energy, 0, [], new Set());\n\nconst reportLines = [\n `zone=${cave.zone}`,\n `goal=${cave.goal}`,\n `bestNode=${best?.node || 'unknown'}`,\n `score=${best?.score ?? 0}`,\n `energyLeft=${best?.energy ?? 0}`,\n `crystals=${best?.crystals ?? 0}`,\n `route=${best?.path?.join('>') || ''}`\n];\n\nfs.writeFileSync('report.txt', reportLines.join('\\n'));\nfs.writeFileSync('trace.txt', trace.join('\\n'));\nconsole.log(`best=${best?.node || 'unknown'}; score=${best?.score ?? 0}; route=${best?.path?.join('>') || ''}; crystals=${best?.crystals ?? 0}`);\n"
- },
- "next": "Tool_030_RunSolver"
- },
- {
- "id": "Tool_030_RunSolver",
- "tool": "Bash",
- "input": {
- "command": "=\"node explore-cave.mjs cave.json\""
- },
- "out": {
- "$solverStdout": "=_result"
- },
- "next": "Tool_040_ReadReport"
- },
- {
- "id": "Tool_040_ReadReport",
- "tool": "ReadFile",
- "input": {
- "file_path": "=\"report.txt\""
- },
- "out": {
- "$reportText": "=_result"
- },
- "next": "Tool_050_ReadTrace"
- },
- {
- "id": "Tool_050_ReadTrace",
- "tool": "ReadFile",
- "input": {
- "file_path": "=\"trace.txt\"",
- "limit": 80
- },
- "out": {
- "$traceText": "=_result"
- },
- "next": "Set_060_Summary"
- },
- {
- "id": "Set_060_Summary",
- "target": "$zoneSummary",
- "value": "=zoneName + \" => \" + $solverStdout",
- "next": "Write_070_Summary"
- },
- {
- "id": "Write_070_Summary",
- "target": "=\"Artifacts/zone-summary.txt\"",
- "value": "=$zoneSummary",
- "mode": "overwrite",
- "next": "Stop_End"
- },
- {
- "id": "Stop_End"
- }
- ]
- }
|