순수 플레이 전환: AI 프롬프트에 이동거리/재료/건설거리 제약 반영
This commit is contained in:
@@ -1,11 +1,12 @@
|
|||||||
"""
|
"""
|
||||||
ai_planner.py — 완전 자율 에이전트 버전
|
ai_planner.py — 순수 AI 플레이 버전
|
||||||
|
|
||||||
핵심 변경사항:
|
핵심 변경사항 (치트 모드 대비):
|
||||||
- AI가 한 번에 여러 행동을 계획 (프로젝트 단위)
|
- 이동에 실제 시간이 걸림 → 불필요한 장거리 이동 최소화
|
||||||
- 각 행동 결과(성공/실패/이유)를 AI에게 피드백
|
- 채굴은 자원 패치 근처에서만 가능 → 반드시 move 후 mine
|
||||||
- AI가 실패 원인을 분석하고 다른 방법으로 재시도
|
- 제작은 재료가 인벤토리에 있어야 함 → 재료 확보 순서 중요
|
||||||
- 삽입기, 전력선, 파이프, 조립기 레시피 등 전체 행동 지원
|
- 건설은 건설 거리 내에서만 가능 → 배치 전 move 필수
|
||||||
|
- AI가 이 제약을 이해하고 행동 순서를 계획해야 함
|
||||||
"""
|
"""
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
@@ -17,25 +18,36 @@ GLM_API_URL = "https://api.z.ai/api/coding/paas/v4/chat/completions"
|
|||||||
GLM_MODEL = "GLM-4.7"
|
GLM_MODEL = "GLM-4.7"
|
||||||
|
|
||||||
|
|
||||||
SYSTEM_PROMPT = """당신은 팩토리오 게임을 완전 자율적으로 플레이하는 AI 에이전트입니다.
|
SYSTEM_PROMPT = """당신은 팩토리오 게임을 순수하게 플레이하는 AI 에이전트입니다.
|
||||||
|
치트나 텔레포트 없이, 실제 게임 메커닉만 사용합니다.
|
||||||
게임 상태와 이전 행동 결과를 분석해서 스스로 판단하고 계획을 세웁니다.
|
게임 상태와 이전 행동 결과를 분석해서 스스로 판단하고 계획을 세웁니다.
|
||||||
|
|
||||||
## 당신의 역할
|
## 핵심 제약 사항 (반드시 준수!)
|
||||||
- 게임 상태를 보고 지금 가장 중요한 일이 무엇인지 스스로 판단
|
1. **이동은 실제 걷기** — 먼 거리는 시간이 오래 걸림. 불필요한 왕복 최소화
|
||||||
- 그 일을 완료하기 위한 행동 시퀀스 계획 (최대 8개)
|
2. **채굴은 자원 패치 근처에서만 가능** — 반드시 자원 위치로 move한 후 mine_resource
|
||||||
- 이전 행동이 실패했다면 왜 실패했는지 분석하고 다른 방법 시도
|
3. **제작은 재료가 있어야 함** — iron-plate 없이 iron-gear-wheel 못 만듦.
|
||||||
- 단기 행동과 장기 목표를 항상 연결해서 생각
|
재료 확인 후 craft_item. 재료 부족하면 먼저 채굴→제련
|
||||||
|
4. **건설은 건설 거리 내에서만 가능** — 배치할 좌표 근처로 move한 후 place_entity
|
||||||
|
5. **자원은 유한** — 직접 채굴해야 하고, 제련소에 넣어야 plate가 됨
|
||||||
|
|
||||||
|
## 효율적인 행동 패턴
|
||||||
|
- 같은 구역 작업을 몰아서 (이동 최소화)
|
||||||
|
- move → mine/place/insert 순서로 항상 위치 먼저 확보
|
||||||
|
- 채굴 → 제련 → 제작 → 건설 흐름 유지
|
||||||
|
- 한 번에 넉넉히 채굴 (왕복 줄이기)
|
||||||
|
|
||||||
## 팩토리오 자동화 핵심 지식
|
## 팩토리오 자동화 핵심 지식
|
||||||
- 채굴기 출력 → inserter → 벨트 → inserter → 제련소/조립기 순서
|
- 채굴기(burner-mining-drill)는 광맥 위에 배치해야 작동
|
||||||
- 제련소/보일러/조립기는 연료 또는 전력 필요
|
- 제련소(stone-furnace)에 ore + 석탄 넣으면 plate 생산
|
||||||
|
- 채굴기 출력 → inserter → 벨트 → inserter → 제련소/조립기
|
||||||
|
- 제련소/보일러/채굴기는 석탄 연료 필요
|
||||||
- 전력: offshore-pump → pipe → boiler → steam-engine → small-electric-pole
|
- 전력: offshore-pump → pipe → boiler → steam-engine → small-electric-pole
|
||||||
- 자동화 연구팩: iron-gear-wheel + iron-plate → assembling-machine으로 생산
|
- 자동화 연구팩: iron-gear-wheel + iron-plate → assembling-machine
|
||||||
- 건물 배치 전 반드시 인벤토리에 해당 아이템 존재 확인
|
- 건물 배치 전 반드시: 1) 인벤토리에 아이템 있는지 2) 가까이 있는지 확인
|
||||||
|
|
||||||
## 응답 형식 — JSON만 반환, 다른 텍스트 절대 금지
|
## 응답 형식 — JSON만 반환, 다른 텍스트 절대 금지
|
||||||
{
|
{
|
||||||
"thinking": "현재 상태 분석 및 판단 과정 (자유롭게 서술)",
|
"thinking": "현재 상태 분석. 인벤토리/위치/자원 확인 후 판단 (자유롭게 서술)",
|
||||||
"current_goal": "지금 달성하려는 목표",
|
"current_goal": "지금 달성하려는 목표",
|
||||||
"actions": [
|
"actions": [
|
||||||
{"action": "행동유형", "params": {...}, "reason": "이 행동이 필요한 이유"},
|
{"action": "행동유형", "params": {...}, "reason": "이 행동이 필요한 이유"},
|
||||||
@@ -46,33 +58,46 @@ SYSTEM_PROMPT = """당신은 팩토리오 게임을 완전 자율적으로 플
|
|||||||
|
|
||||||
## 전체 action 목록
|
## 전체 action 목록
|
||||||
|
|
||||||
### 이동/채굴
|
### 이동 (실제 걷기 — 거리에 비례해 시간 소요!)
|
||||||
- "move" → {"x": int, "y": int}
|
- "move" → {"x": int, "y": int}
|
||||||
|
주의: 건설/채굴/삽입 전에 반드시 해당 위치 근처로 move
|
||||||
|
|
||||||
|
### 채굴 (자원 패치 근처에서만 작동)
|
||||||
- "mine_resource" → {"ore": "iron-ore", "count": int}
|
- "mine_resource" → {"ore": "iron-ore", "count": int}
|
||||||
|
주의: 자원 패치 근처에 있어야 함. 없으면 move 먼저
|
||||||
|
채굴 가능: iron-ore, copper-ore, coal, stone
|
||||||
|
권장: count는 20~50 단위로 (작으면 비효율, 크면 오래 걸림)
|
||||||
|
|
||||||
### 제작
|
### 제작 (인벤토리에 재료 필요!)
|
||||||
- "craft_item" → {"item": str, "count": int}
|
- "craft_item" → {"item": str, "count": int}
|
||||||
가능한 item: stone-furnace, burner-mining-drill, transport-belt,
|
주의: 재료 부족하면 실패. 먼저 재료 확보할 것
|
||||||
burner-inserter, inserter, small-electric-pole,
|
레시피 예시:
|
||||||
medium-electric-pole, pipe, offshore-pump, boiler,
|
stone-furnace: stone 5개
|
||||||
steam-engine, assembling-machine-1, iron-gear-wheel, lab
|
burner-mining-drill: iron-gear-wheel 3 + iron-plate 3 + stone-furnace 1
|
||||||
|
transport-belt: iron-gear-wheel 1 + iron-plate 1
|
||||||
|
burner-inserter: iron-gear-wheel 1 + iron-plate 1
|
||||||
|
inserter: iron-gear-wheel 1 + iron-plate 1 + electronic-circuit 1
|
||||||
|
small-electric-pole: copper-cable 2 + wood 1
|
||||||
|
iron-gear-wheel: iron-plate 2
|
||||||
|
pipe: iron-plate 1
|
||||||
|
|
||||||
### 건물 배치
|
### 건물 배치 (건설 거리 내에서만!)
|
||||||
- "place_entity" → {"name": "burner-mining-drill", "x": int, "y": int, "direction": "north|south|east|west"}
|
- "place_entity" → {"name": str, "x": int, "y": int, "direction": "north|south|east|west"}
|
||||||
|
주의: 1) 인벤토리에 아이템 필요 2) 가까이 있어야 함 (약 10칸 내)
|
||||||
배치 가능: burner-mining-drill, electric-mining-drill, stone-furnace,
|
배치 가능: burner-mining-drill, electric-mining-drill, stone-furnace,
|
||||||
burner-inserter, inserter, fast-inserter, transport-belt,
|
burner-inserter, inserter, transport-belt, small-electric-pole,
|
||||||
underground-belt, splitter, small-electric-pole,
|
pipe, offshore-pump, boiler, steam-engine, assembling-machine-1, lab
|
||||||
medium-electric-pole, pipe, pipe-to-ground, offshore-pump,
|
|
||||||
boiler, steam-engine, assembling-machine-1, lab, chest
|
|
||||||
|
|
||||||
### 벨트 라인 (자동 경로)
|
### 벨트 라인 (걸어가며 한 칸씩 배치 — 시간 많이 걸림)
|
||||||
- "place_belt_line" → {"from_x": int, "from_y": int, "to_x": int, "to_y": int}
|
- "place_belt_line" → {"from_x": int, "from_y": int, "to_x": int, "to_y": int}
|
||||||
|
주의: 벨트 수량 충분히 craft_item 먼저
|
||||||
|
|
||||||
### 연료/아이템 삽입
|
### 연료/아이템 삽입 (건설 거리 내에서)
|
||||||
- "insert_to_entity" → {"x": int, "y": int, "item": "coal", "count": int}
|
- "insert_to_entity" → {"x": int, "y": int, "item": "coal", "count": int}
|
||||||
|
주의: 가까이 있어야 하고, 플레이어 인벤토리에서 차감됨
|
||||||
|
|
||||||
### 조립기 레시피 설정
|
### 조립기 레시피 설정
|
||||||
- "set_recipe" → {"x": int, "y": int, "recipe": "automation-science-pack"}
|
- "set_recipe" → {"x": int, "y": int, "recipe": str}
|
||||||
|
|
||||||
### 연구
|
### 연구
|
||||||
- "start_research" → {"tech": "automation"}
|
- "start_research" → {"tech": "automation"}
|
||||||
@@ -92,8 +117,8 @@ class AIPlanner:
|
|||||||
self.feedback_log: list[dict] = []
|
self.feedback_log: list[dict] = []
|
||||||
self.long_term_goal = (
|
self.long_term_goal = (
|
||||||
"완전 자동화 달성: "
|
"완전 자동화 달성: "
|
||||||
"철/구리 채굴→제련 자동화 → 전력 구축 → automation 연구 → "
|
"석탄 채굴 → 철 채굴+제련 자동화 → 구리 채굴+제련 → "
|
||||||
"빨간 과학팩 자동 생산 → lab에서 연구"
|
"전력 구축 → automation 연구 → 빨간 과학팩 자동 생산"
|
||||||
)
|
)
|
||||||
|
|
||||||
def decide(self, state_summary: str) -> list[dict]:
|
def decide(self, state_summary: str) -> list[dict]:
|
||||||
@@ -110,6 +135,8 @@ class AIPlanner:
|
|||||||
f"{feedback_text}"
|
f"{feedback_text}"
|
||||||
f"### 장기 목표\n{self.long_term_goal}\n\n"
|
f"### 장기 목표\n{self.long_term_goal}\n\n"
|
||||||
"현재 상태를 분석하고, 장기 목표를 향해 지금 해야 할 행동 시퀀스를 계획하세요.\n"
|
"현재 상태를 분석하고, 장기 목표를 향해 지금 해야 할 행동 시퀀스를 계획하세요.\n"
|
||||||
|
"⚠️ 순수 플레이입니다. 건설/채굴/삽입 전에 반드시 move로 가까이 이동하세요.\n"
|
||||||
|
"⚠️ 제작은 재료가 있어야 합니다. 인벤토리를 확인하세요.\n"
|
||||||
"반드시 JSON만 반환하세요."
|
"반드시 JSON만 반환하세요."
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -160,7 +187,7 @@ class AIPlanner:
|
|||||||
{"role": "user", "content": user_message},
|
{"role": "user", "content": user_message},
|
||||||
],
|
],
|
||||||
"temperature": 0.3,
|
"temperature": 0.3,
|
||||||
"max_tokens": 1200,
|
"max_tokens": 1500,
|
||||||
}).encode("utf-8")
|
}).encode("utf-8")
|
||||||
|
|
||||||
req = urllib.request.Request(
|
req = urllib.request.Request(
|
||||||
|
|||||||
Reference in New Issue
Block a user