diff --git a/README.md b/README.md index 64b404d..3494dfa 100644 --- a/README.md +++ b/README.md @@ -113,3 +113,4 @@ planner.set_goal( - 순수 플레이이므로 **걷기, 채굴, 제작에 실제 시간이 소요**됩니다 - AI가 "move 먼저 → 작업" 패턴을 학습하도록 프롬프트가 설계되어 있습니다 - `agent_log.jsonl`에 모든 행동과 타임스탬프가 기록됩니다 +- `mine_resource`에서 실패한 채굴 타일 제외(`exclude`)는 Lua와 Python 양쪽에서 정수 타일 좌표(`tx, ty`) 키로 통일해, 제외한 좌표가 반복 선택되지 않도록 합니다. diff --git a/__pycache__/action_executor.cpython-311.pyc b/__pycache__/action_executor.cpython-311.pyc new file mode 100644 index 0000000..dc3d2d1 Binary files /dev/null and b/__pycache__/action_executor.cpython-311.pyc differ diff --git a/__pycache__/ai_planner.cpython-311.pyc b/__pycache__/ai_planner.cpython-311.pyc new file mode 100644 index 0000000..e33b87f Binary files /dev/null and b/__pycache__/ai_planner.cpython-311.pyc differ diff --git a/__pycache__/context_compressor.cpython-311.pyc b/__pycache__/context_compressor.cpython-311.pyc new file mode 100644 index 0000000..cd7cd46 Binary files /dev/null and b/__pycache__/context_compressor.cpython-311.pyc differ diff --git a/__pycache__/factorio_rcon.cpython-311.pyc b/__pycache__/factorio_rcon.cpython-311.pyc new file mode 100644 index 0000000..b686f6f Binary files /dev/null and b/__pycache__/factorio_rcon.cpython-311.pyc differ diff --git a/__pycache__/main.cpython-311.pyc b/__pycache__/main.cpython-311.pyc new file mode 100644 index 0000000..12ef78f Binary files /dev/null and b/__pycache__/main.cpython-311.pyc differ diff --git a/__pycache__/state_reader.cpython-311.pyc b/__pycache__/state_reader.cpython-311.pyc new file mode 100644 index 0000000..ff188ba Binary files /dev/null and b/__pycache__/state_reader.cpython-311.pyc differ diff --git a/action_executor.py b/action_executor.py index b723636..2525b80 100644 --- a/action_executor.py +++ b/action_executor.py @@ -134,14 +134,14 @@ rcon.print("WALK:" .. string.format("%.1f", dist)) before_count = self._get_item_count(ore) target_count = before_count + count total_mined = 0 - failed_positions = set() # 실패한 좌표 기억 + failed_positions: set[tuple[int, int]] = set() # Lua exclude 키와 동일한 정수 타일 좌표만 저장 for round_num in range(15): # 최대 15번 시도 # 1. Lua에서 가장 가까운 광석 찾기 (실패한 좌표 제외) # 제외 좌표를 Lua 테이블로 전달 exclude_lua = "local exclude = {}\n" for i, (fx, fy) in enumerate(failed_positions): - exclude_lua += f'exclude["{fx:.0f},{fy:.0f}"] = true\n' + exclude_lua += f'exclude["{fx},{fy}"] = true\n' find_result = self.rcon.lua(P + f""" {exclude_lua} @@ -156,9 +156,12 @@ table.sort(res, function(a, b) end) -- 제외 목록에 없는 가장 가까운 광석 찾기 for _, e in ipairs(res) do - local key = string.format("%.0f,%.0f", e.position.x, e.position.y) + -- Lua 키를 "정수 타일"로 통일 (반올림/절삭 방식 차이로 exclude가 빗나가는 문제 방지) + local tx = math.floor(e.position.x + 0.5) + local ty = math.floor(e.position.y + 0.5) + local key = string.format("%d,%d", tx, ty) if not exclude[key] then - rcon.print(string.format("%.1f,%.1f", e.position.x, e.position.y)) + rcon.print(key) return end end @@ -176,14 +179,14 @@ rcon.print("ALL_EXCLUDED") return False, f"{ore} 근처 타일 {len(failed_positions)}개 모두 접근 불가 — 다른 위치로 이동 필요" try: - parts = find_result.split(",") - ox, oy = float(parts[0]), float(parts[1]) + parts = find_result.strip().split(",") + ox, oy = int(parts[0]), int(parts[1]) except: return False, f"좌표 파싱 실패: {find_result}" # 2. 광석 위치로 걸어가기 - print(f" [채굴] 광석({ox:.0f},{oy:.0f})으로 이동... (시도 {round_num+1}, 제외: {len(failed_positions)}개)") - ok, msg = self.move(int(ox), int(oy)) + print(f" [채굴] 광석({ox},{oy})으로 이동... (시도 {round_num+1}, 제외: {len(failed_positions)}개)") + ok, msg = self.move(ox, oy) if not ok: print(f" [채굴] 이동 실패: {msg}") failed_positions.add((ox, oy)) diff --git a/docs/plan.md b/docs/plan.md new file mode 100644 index 0000000..ca5d063 --- /dev/null +++ b/docs/plan.md @@ -0,0 +1,24 @@ +## 채굴 실패 시 제외 좌표 반복 버그 수정 계획 + +### 문제 재현/관찰 +- `mine_resource`에서 실패한 타일을 `failed_positions`에 추가한 뒤 Lua에 `exclude` 테이블로 전달하지만, + 다음 시도에서도 동일 좌표(예: `388,2`)로 다시 이동하는 로그가 발생합니다. + +### 원인 후보 +- Lua에서 제외 판정에 쓰는 좌표 키가 `string.format("%.0f,%.0f", ...)` 기반인 반면, + Python에서 `exclude["{fx:.0f},{fy:.0f}"]`를 만들 때 반올림/절삭 방식이 Lua와 1:1로 일치하지 않는 케이스가 있을 수 있습니다. +- 이 경우 `exclude[key]`가 항상 false가 되어, Lua가 “가장 가까운 광석”을 계속 같은 엔티티로 반환할 수 있습니다. + +### 변경 목표 +1. `failed_positions`를 “Lua 키 생성과 동일한 정수 타일 좌표(tx, ty)”로만 저장합니다. +2. Lua에서 후보 광석 엔티티를 검사할 때도 정수 타일 좌표를 계산해 키/반환/마이닝 좌표에 일관되게 사용합니다. +3. 그 결과, 제외한 좌표는 다음 루프에서 절대로 다시 선택되지 않도록 보장합니다. + +### 구현 범위 +- `action_executor.py` + - `mine_resource` 내부에서 좌표 처리 로직을 정수 타일 기반으로 통일 + - Lua 반환값을 `tx,ty` 정수 문자열로 변경하고 Python 파싱을 이에 맞춤 + +### README 업데이트 계획 +- 채굴 제외(exclude) 로직이 “정수 타일 키 기반으로 통일”되도록 README의 기술/동작 설명(또는 체크리스트)을 업데이트합니다. +