Problem
크기의 보드에서 같은 색 타일을 제거하여 가능한 한 높은 점수를 얻는 게임을 진행합니다.
보드는 크기의 칸이 행 열로 배열된 형태입니다. 행 번호는 위에서 아래로 행부터 행, 열 번호는 왼쪽에서 오른쪽으로 열부터 열까지이며, 행 열의 칸을 로 표기합니다.
각 칸은 빈칸이거나 세 가지 색 중 하나의 타일을 가집니다. 새 행의 각 칸 색은 세 가지 색 중 하나를 서로 독립적으로 같은 확률로 선택하여 생성합니다. 게임을 시작할 때 보드의 맨 아래에 이렇게 생성한 타일 개로 이루어진 행 하나가 추가됩니다.
한 턴에는 비어 있지 않은 칸 하나를 선택합니다. 선택한 타일과 상하좌우로 연결된 같은 색 타일을 모두 제거합니다. 대각선으로 맞닿은 타일은 연결되지 않습니다. 연결된 타일이 하나뿐인 경우에도 선택할 수 있습니다.
한 번에 개의 타일을 제거했다면 점을 얻습니다. 제거한 뒤에는 각 열의 남은 타일이 빈칸 없이 아래로 떨어집니다. 이후 새로운 타일 개로 이루어진 행이 보드 아래에 추가되고, 기존 보드는 한 행 위로 이동합니다.
새 행을 추가할 때 보드의 맨 위에 남아 있던 타일이 보드 밖으로 밀려나면 게임이 종료됩니다. 종료를 일으킨 마지막 행동에서 제거한 타일의 점수도 최종 점수에 포함됩니다.
각 실행은 다음 조건 중 하나가 먼저 만족되면 종료됩니다.
- 새 행 추가로 타일이 보드 위쪽을 벗어난 경우
- 정상적인 행동을 번 수행한 경우
- 준비 응답과 모든 행동 응답의 누적 시간 를 모두 사용한 경우
- 출력 형식에 맞지 않는 문자열, 범위를 벗어난 좌표, 빈칸 좌표를 출력한 경우
- 프로그램 실행 중 오류가 발생한 경우
잘못된 행동, 시간 초과, 실행 오류가 발생해도 그 전에 얻은 점수는 유지됩니다. 잘못된 행동은 보드와 점수에 반영되지 않습니다.
행 생성에 사용하는 실제 난수 초기값은 공개되지 않습니다. 하나의 평가 정책 버전에는 서로 다른 비공개 초기값 30개로 이루어진 평가 집합이 하나만 고정되며, 모든 제출은 이 집합으로 평가됩니다. 내부 평가 기록의 seedId 부터 까지는 이 30개 초기값을 나타내는 불투명한 식별자이며, 같은 평가 정책 버전에서는 모든 제출에서 각 seedId가 동일한 실제 초기값에 대응합니다. 활성 평가 정책 버전 동안 제출 상세에는 전체 평가 상태, 완료 횟수, 점수 합과 평균만 표시하며, seedId별 상태·점수·종료 사유·매치 식별자와 리플레이는 실제 초기값을 역추정할 수 있으므로 제공하지 않습니다. 해당 버전이 종료된 뒤에만 seedId별 결과와 제출자 본인의 seedId=1 정제 리플레이를 공개 가능한 정보로 전환할 수 있습니다. 이 리플레이는 다른 사용자에게 공개하지 않으며, seedId=2부터 까지의 리플레이도 제공하지 않습니다.
30회 실행의 점수 합(scoreSum)이 높은 제출이 더 높은 순위를 얻습니다. scoreSum이 같다면 제출 시각이 빠른 제출이 앞서고, 제출 시각도 같다면 제출 ID가 작은 제출이 앞섭니다. 사용자별로 이 순서가 가장 높은 제출 하나만 리더보드에 표시됩니다.
보드의 상태를 정확히 관리하고, 앞으로 추가될 행으로 인해 게임이 종료되기 전에 큰 연결 요소를 만들어 높은 점수를 얻는 Agent를 작성해주세요!
Input
Hanpang Agent 프로토콜
보드는 행 열입니다. Agent 프로토콜의 행은 위에서 아래로 1부터 15, 열은 왼쪽에서 오른쪽으로 1부터 8까지 사용합니다. SDK 내부에서 빈칸은 0, 타일 색은 1, 2, 3입니다.
C++20과 Python3 Starter는 한 파일 상단에 공식 SDK를 포함합니다. SDK는 새 행 삽입, 연결요소 제거, 중력, 프로토콜 처리를 담당합니다. 사용자 코드는 mutable board와 calculateMove() 또는 calculate_move()만 수정합니다. board 배열 인덱스는 각 언어 관례대로 0부터 시작하지만, 함수가 반환하는 Action의 row, col은 Agent 프로토콜과 같은 1-based 좌표입니다.
| 채점기→플레이어 입력 | 플레이어→채점기 출력 | 제한 | 설명 |
|---|---|---|---|
START |
READY |
남은 총 시간 | Agent 준비 handshake. 응답 시간도 같은 총 시간에서 차감됩니다. |
TURN remaining_ms new_row |
PANG row col |
remaining_ms |
새 행을 반영한 뒤 제거할 타일 선택 |
- Agent는
START를 읽기 전에READY를 자발적으로 출력하면 안 됩니다. READY와PANG row col뒤에는 줄바꿈을 출력하고 즉시 flush합니다.- 한 참가자는 START의 READY와 모든 TURN 응답을 합쳐 총 를 가집니다. 명령별 고정 시간 제한은 없습니다.
remaining_ms는 READY와 successful TURN response의 BrokerRESULT elapsed_ms를 누적 차감한 남은 총 시간입니다. OS CPU 시간이 아닙니다.- 응답의
elapsed_ms >= remaining_ms이면 PANG을 parse/apply하지 않고TIME_LIMIT으로 종료하며 이전 점수를 보존합니다. new_row는 길이 의 문자열이며 각 문자는1,2,3입니다. 첫 TURN은 초기 바닥 행입니다.- 다음 행은 행동 전에 공개되지 않습니다.
row,col은 각각 , 인 정수입니다. 단일 타일도 선택할 수 있습니다.- 출력 형식 오류, 범위 밖·빈칸 좌표, invalid UTF-8/control byte/oversized output은 해당 행동을 적용하지 않고 마지막 확정 점수를 보존합니다.
- Agent protocol에는 terminal
FINISH입력이 없습니다. Judger가 terminal LOG와 control FINISH를 만든 뒤 Broker가 participant process를 종료합니다.
SDK는 new_row를 반영한 뒤 사용자 전략을 호출합니다. 사용자가 선택한 행동을 출력하기 전에 SDK는 같은 색 상하좌우 연결요소를 로컬 보드에서 제거하고 각 열에 중력을 적용합니다. 다음 TURN의 새 행을 추가하면 로컬 보드가 채점기 보드와 다시 같은 상태가 됩니다.
Example
| 채점기→플레이어 입력 | 플레이어→채점기 출력 |
|---|---|
START |
READY |
TURN 5000 32131311 |
PANG 15 7 |
TURN 4999 11223312 |
PANG 15 7 |
remaining_ms 값은 설명을 위한 예시입니다. 실제 값은 READY 응답과 각 successful TURN 응답의 Broker elapsed를 같은 5,000ms bank에서 누적 차감한 결과에 따라 달라집니다. Agent가 받는 terminal FINISH 명령은 없습니다.