귀하의 프로그램은 지하에서 귀중한 광물을 검색하는 마이닝 로봇을 제어합니다. 로봇은 컨트롤러에게 이동 및 발굴하려는 위치를 알려주고 컨트롤러는 로봇 상태에 대한 피드백을 제공합니다.
처음에는 로봇에 일부 광산 샤프트가있는 광산의 이미지 맵과 광산의 미네랄 값과 경도를 지정하는 데이터 파일이 제공됩니다. 그런 다음 로봇은 샤프트를 통해 이동하여 귀중한 미네랄을 찾습니다. 로봇은 지구를 파고 다닐 수 있지만 하드 록으로 인해 속도가 느려집니다.
24 시간 교대 후 가장 귀중한화물로 돌아 오는 로봇이 승자가됩니다. 복잡한 과제로 보일 수 있지만 기본 마이닝 로봇을 만드는 것은 간단합니다 (아래 샘플 마이닝 로봇 답변 참조).
조작
컨트롤러는 광산 이미지, 광물 데이터 및 장비 파일 이름으로 프로그램을 시작합니다. 로봇은 광산 이미지와 광물 데이터를 사용하여 귀중한 광석을 찾고 단단한 암석을 피할 수 있습니다. 로봇은 장비 목록에서 장비를 구매할 수도 있습니다.
예 : python driller.py mineimage.png minerals.txt equipmentlist.txt
2 초의 초기화 기간 후에 컨트롤러는 stdin 및 stdout을 통해 로봇 프로그램과 통신합니다. 로봇은 상태 메시지를받은 후 0.1 초 이내에 조치를 취해야합니다.
매번 컨트롤러는 로봇에게 상태 라인을 보냅니다 :
timeleft cargo battery cutter x y direction
예 : 1087 4505 34.65 88.04 261 355 right
정수 timeleft
는 쉬프트가 끝나기 전 남은 게임 시간입니다. 이것은
cargo
당신이 채굴 한 광물의 정수 값으로 지금까지 장비 비용을 지불 한 것보다 적습니다. battery
수준은 배터리 잔량의 정수 비율입니다. cutter
정수 레벨이 기준치에 대한 비율로 커터의 전류 선명도이다. x
및 y
값은 (0, 0)에서 좌측 상단에서 참조 로봇의 위치와 양의 정수이다. 방향은 로봇이 향하고있는 현재 방향입니다 (왼쪽, 오른쪽, 위, 아래).
로봇이 '엔드 시프트'또는 '실패한'입력을 받으면 곧 프로그램이 종료됩니다. 로봇이 디버깅 / 성능 데이터를 먼저 파일에 쓰도록 할 수 있습니다.
컨트롤러가 받아 들일 수있는 4 가지 명령이 있습니다. direction
left|right|up|down
로봇이 그 방향을 가리키고 15 초의 게임 시간이 필요합니다. move <integer>
는 미네랄 절단의 경도와 절단기의 선명도에 따라 시간이 걸리는 많은 단위를 앞으로 움직이거나 파도록 로봇에 지시합니다 (아래 참조). buy <equipment>
로봇이 표면에있는 경우에만 (y 값 <= 시작 y 값) 지정된 장비를 설치하고화물 값에서 비용을 공제합니다. 장비 설치에는 300 게임 시간이 걸립니다. 특수 명령 snapshot
은 현재 광산 이미지를 디스크에 기록하며 게임 시간이 없습니다. 스냅 샷을 사용하여 로봇을 디버깅하거나 애니메이션을 만들 수 있습니다.
로봇은 배터리 100 개와 절단기 선명도 100 개로 시작합니다. 이동 및 회전시 소량의 배터리 전원을 사용하십시오. 파기는 훨씬 더 많이 사용하며 미네랄의 경도와 절단기의 현재 선명도의 함수입니다. 로봇이 광물을 파헤 치면서, 시간과 광물의 경도에 따라 절단기의 선명도가 떨어집니다. 로봇에 충분한화물 가치가있는 경우 새 배터리 나 절단기를 구입하기 위해 표면으로 돌아올 수 있습니다. 고품질 장비의 초기 효과는 100 % 이상입니다. 배터리에는 이름에 "배터리"라는 문자열이 있고 (놀라운) 커터에는 이름에 "커터"가 있습니다.
다음 관계는 이동 및 절단을 정의합니다.
timecutting = sum(hardness of pixels cut) * 100 / cutter
cutterwear = 0.01 for each second cutting
cutters will not wear below 0.1 sharpness
timemoving = 1 + timecutting
batterydrain = 0.0178 for each second moving
changing direction takes 15 seconds and drains 0.2 from the battery
installing new equipment takes 300 seconds
광물을 자르지 않고 1 대의 유닛을 옮기는 데 1 초가 걸리며 배터리의 0.0178을 사용합니다. 따라서 로봇은 광물을 자르거나 돌리지 않는 경우 표준 100 회 충전으로 93 분 동안 5600 대의 유닛을 구동 할 수 있습니다.
새로운 기능 : 로봇의 너비는 11 픽셀이므로 각 픽셀 이동시 최대 11 픽셀을 자릅니다. 잘라낼 픽셀이 11 픽셀 미만이면 로봇이 이동하는 데 시간이 덜 걸리고 커터 마모가 줄어 듭니다. 광물 데이터 파일에 픽셀 색상을 지정하지 않으면 경도가 0이고 값이 0 인 여유 공간이됩니다.
시간이 다 떨어지거나 로봇 배터리가 소진되거나 로봇의 일부가 이미지 경계를 초과하거나 불법 명령이 전송되거나 로봇 통신 시간이 초과되면 실행이 종료됩니다.
당신의 점수는 로봇화물의 최종 가치입니다. 컨트롤러가 점수와 최종지도 이미지를 출력합니다. 프로그램의 stderr 출력은 robot.log 파일에 기록됩니다. 로봇이 죽으면 치명적인 오류가 로그에있을 수 있습니다.
광산 데이터
equipment.txt :
Equipment_Name Cost Initial_Value
std_cutter 200 100
carbide_cutter 600 160
diamond_cutter 2000 250
forcehammer_cutter 7200 460
std_battery 200 100
advanced_battery 500 180
megapower_battery 1600 320
nuclear_battery 5200 570
mineraldata.txt :
Mineral_Name Color Value Hardness
sandstone (157,91,46) 0 3
conglomerate (180,104,102) 0 12
igneous (108,1,17) 0 42
hard_rock (219,219,219) 0 15
tough_rock (146,146,146) 0 50
super_rock (73,73,73) 0 140
gem_ore1 (0,255,0) 10 8
gem_ore2 (0,0,255) 30 14
gem_ore3 (255,0,255) 100 6
gem_ore4 (255,0,0) 500 21
광산 이미지 :
광산 이미지에는 알파 채널이있을 수 있지만 사용되지는 않습니다.
컨트롤러
컨트롤러는 Python 2.7에서 작동해야하며 PIL 라이브러리가 필요합니다. Python Pillow는 PIL 이미지 모듈을 얻기위한 Windows 용 다운로드 파일이라는 정보를 받았습니다.
현재 디렉토리에서 로봇 프로그램, cfg.py, 이미지 및 데이터 파일로 컨트롤러를 시작하십시오. 제안 된 명령 행은 다음과 같습니다.
python controller.py [<interpreter>] {<switches>} <robotprogram>
예 : python controller.py java underminer.class
컨트롤러는 실행이 끝날 때 robot.log 파일과 finalmine.png 파일을 작성합니다.
#!/usr/bin/env python
# controller.py
# Control Program for the Robot Miner on PPCG.
# Tested on Python 2.7 on Ubuntu Linux. May need edits for other platforms.
# V1.0 First release.
# V1.1 Better error catching
import sys, subprocess, time
# Suggest installing Pillow here if you don't have PIL already
from PIL import Image, ImageDraw
from cfg import *
program = sys.argv[1:]
calltext = program + [MINEIMAGE, MINERALFILE, EQUIPMENTFILE]
errorlog = open(ERRORFILE, 'wb')
process = subprocess.Popen(calltext,
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=errorlog)
image = Image.open(MINEIMAGE)
draw = ImageDraw.Draw(image)
BLACK, ORANGE, WHITE = (0,0,0), (255,160,160), (255,255,255)
W,H = image.size
dirmap = dict(right=(1,0), left=(-1,0), up=(0,-1), down=(0,1))
# read in mineral file (Name, Color, Value, Hardness):
data = [v.split() for v in open(MINERALFILE)][1:]
mineralvalue = dict((eval(color), int(value)) for
name, color, value, hard in data)
hardness = dict((eval(color), int(hard)) for
name, color, value, hard in data)
# read in the equipment list:
data = [v.split() for v in open(EQUIPMENTFILE)][1:]
equipment = dict((name, (int(cost), float(init))) for
name, cost, init in data)
# Set up simulation variables:
status = 'OK'
rx, ry, direction = START_X, START_Y, START_DIR # center of robot
cargo, battery, cutter = 0, 100.0, 100.0
clock = ENDSHIFT
size = ROBOTSIZE / 2
msgfmt = '%u %u %u %u %u %u %s'
snapnum = 1
def mkcutlist(x, y, direc, size):
dx, dy = dirmap[direc]
cx, cy = x+dx*(size+1), y+dy*(size+1)
output = [(cx, cy)]
for s in range(1, size+1):
output += [ (cx+dy*s, cy+dx*s), (cx-dy*s, cy-dx*s)]
return output
def send(msg):
process.stdin.write((msg+'\n').encode('utf-8'))
process.stdin.flush()
def read():
return process.stdout.readline().decode('utf-8')
time.sleep(INITTIME)
while clock > 0:
try:
start = time.time()
send(msgfmt % (clock, cargo, battery, cutter, rx, ry, direction))
inline = read()
if time.time() - start > TIMELIMIT:
status = 'Move timeout'
break
except:
status = 'Robot comslink failed'
break
# Process command:
movecount = 0
try:
arg = inline.split()
cmd = arg.pop(0)
if cmd == 'buy':
if ry <= START_Y and arg and arg[0] in equipment:
cost, initperc = equipment[arg[0]]
if cost <= cargo:
cargo -= cost
if 'battery' in arg[0]:
battery = initperc
elif 'cutter' in arg[0]:
cutter = initperc
clock -= 300
elif cmd == 'direction':
if arg and arg[0] in dirmap:
direction = arg[0]
clock -= 15
battery -= 0.2
elif cmd == 'move':
if arg and arg[0].isdigit():
movecount = abs(int(arg[0]))
elif cmd == 'snapshot':
image.save('snap%04u.png' % snapnum)
snapnum += 1
except:
status = 'Robot command malfunction'
break
for move in range(movecount):
# check image boundaries
dx, dy = dirmap[direction]
rx2, ry2 = rx + dx, ry + dy
print rx2, ry2
if rx2-size < 0 or rx2+size >= W or ry2-size < 0 or ry2+size >= H:
status = 'Bounds exceeded'
break
# compute time to move/cut through 1 pixel
try:
cutlist = mkcutlist(rx2, ry2, direction, size)
colors = [image.getpixel(pos)[:3] for pos in cutlist]
except IndexError:
status = 'Mining outside of bounds'
break
work = sum(hardness.get(c, 0) for c in colors)
timetaken = work * 100 / cutter
cutter = max(0.1, cutter - timetaken / 100)
clock -= 1 + int(timetaken + 0.5)
battery -= (1 + timetaken) / 56
if battery <= 0:
status = 'Battery exhausted'
break
cargo += sum(mineralvalue.get(c, 0) for c in colors)
draw.rectangle([rx-size, ry-size, rx+size+1, ry+size+1], BLACK, BLACK)
rx, ry = rx2, ry2
draw.rectangle([rx-size, ry-size, rx+size+1, ry+size+1], ORANGE, WHITE)
if clock <= 0:
break
if status != 'OK':
break
del draw
image.save('finalmine.png')
if status in ('Battery exhausted', 'OK'):
print 'Score = %s' % cargo
send('endshift')
else:
print 'Error: %s at clock %s' % (status, clock)
send('failed')
time.sleep(0.3)
process.terminate()
연결된 구성 파일 (변경되지 않음) :
# This is cfg.py
# Scenario files:
MINEIMAGE = 'testmine.png'
MINERALFILE = 'mineraldata.txt'
EQUIPMENTFILE = 'equipment.txt'
# Mining Robot parameters:
START_X = 270
START_Y = 28
START_DIR = 'down'
ROBOTSIZE = 11 # should be an odd number
ENDSHIFT = 24 * 60 * 60 # seconds in an 24 hour shift
INITTIME = 2.0
TIMELIMIT = 0.1
ERRORFILE = 'robot.log'
답변 형식
답변에는 프로그래밍 언어, 로봇 이름 및 최종 점수 (예 : Python 3 , Tunnel Terror , 1352 )를 포함한 제목이 있어야합니다 . 답변 본문에는 코드와 최종 광산지도 이미지가 있어야합니다. 다른 이미지 나 애니메이션도 환영합니다. 승자가 가장 높은 점수를받은 로봇이됩니다.
다른 규칙
- 일반적인 허점은 금지되어 있습니다.
- 난수 생성기를 사용하는 경우 프로그램 실행을 재현 할 수 있도록 프로그램에서 시드를 하드 코딩해야합니다. 다른 사람이 프로그램을 실행하고 동일한 최종 광산 이미지와 점수를 얻을 수 있어야합니다.
- 귀하의 프로그램을 프로그래밍해야합니다 모든 내 이미지. 이러한 데이터 파일 또는 이 이미지 크기, 광물 레이아웃, 터널 레이아웃 등에 대해 프로그램을 코딩해서는 안됩니다 . 로봇이이 규칙을 어 기고 있다고 생각되면 광산 이미지 및 / 또는 데이터 파일을 변경할 권리가 있습니다.
편집
- 0.1 초 응답 규칙을 설명했습니다.
- 로봇 시작 명령 행 옵션 및 파일에서 확장되었습니다.
- 더 나은 오류 포착 기능을 가진 새로운 컨트롤러 버전을 추가했습니다.
- robot.log 메모를 추가했습니다.
- 기본 광물 경도 및 값을 설명했습니다.
- 배터리 대 커터 장비 설명.
- 로봇 크기 11을 명시 적으로 만들었습니다.
- 시간, 커터 마모 및 배터리에 대한 계산이 추가되었습니다.