무인도에 보물 찾기


13

소개

당신은 무인도에 약간의 종들이 갇혀 있으며 보물을 찾고 있습니다. 검색 시간이 길수록 더 많은 보물을 찾습니다. 검색하는 사람이 적을수록 더 많은 사람을 찾습니다.

공급이 제한되어 있기 때문에 지도자는 그룹의 1/4까지 몇 사람이 매일 밤 죽도록 남겨두기로 결정했습니다. 그는 어느 날에 얼마나 많은 사람들이 죽을지를 정확하게 말하지 않기로 결정했습니다.

당신은 5 명으로 구성된 소그룹을 통제하고 있으며, 그들은 5 명을 소중히 여길 것입니다.

객관적인

이 경쟁의 목적은 가능한 많은 보물을 모으는 것입니다. 당신의 종들이 캠프로 돌아 가려고하지 않을 때마다, 그들은 특정한 수의 보물을 발견 할 것입니다. 종들은 다른 시간에 캠프로 돌아올 수 있습니다.

노동자가 보물을 찾기 위해 떠날 때마다, 노동자는 1+R보물 조각을 찾습니다 . 여기서 R캠프에 이미 돌아온 노동자의 수 (모든 봇 중)가 있습니다. 데드 봇은이 계산에 영향을 미치지 않습니다.

하루의 시작시에, 난수 ( n발) 2에이 max(3, floor(num_live_players/4))선택 될 것이다. (1 일 10 플레이어의 경우,이은 2max(3,50/4)=121 일에 20 명의 선수들도이 될 것입니다. 2max(3,100/4)=25이 숫자는 그 날을 위해 죽을 남아있을 것입니다 선수의 수를 나타냅니다.), 및 프로그램에 제공되지 않습니다 .

하인이 마지막 n으로 돌아온 사람들 중 하나라면 , 그 / 그녀는 죽었고, 찾은 보물을 당신의 소유물로 옮길 수 없습니다. 또한, 종은 모험의 나머지 부분을 위해 보물 사냥에 참여할 수 없습니다.

최종 점수는 모험 (컨트롤러 실행) 당 획득 한 평균 보물의 양입니다.

열린 슬롯보다 같은 턴에 더 많은 사람들이 캠프에 돌아 오려고 시도하면 난수는 누가 들어가고 누가 죽는 지 결정합니다.

일출부터 일몰까지이 섬의 하루는 30 턴 동안 지속됩니다. 밤에는 위험한 동물이 많기 때문에 일몰으로 돌아 오지 않으면 캠프에 들어갈 수 없습니다.

입출력

시뮬레이션 전체에서 프로그램을 실행해야합니다.

시뮬레이션 시작시 봇의 인덱스가있는 INDEX I위치 I가 입력 됩니다 (이 인덱스는 1부터 계산).

하루의 시작에서, START_DAY D/N프로그램에 입력됩니다 D(부터 하루 번호입니다 1), 그리고 N동일 max(3, floor(num_live_players/4))특정 일에 죽을 수 있습니다 사람들의 최대 수입니다.

각 턴이 시작될 START_TURN T때 프로그램에 입력됩니다. 여기서 T턴 번호는 (에서 시작 1)입니다.

당신의 프로그램이 이것을 받으면, 각각의 쉼표로 구분 된 당신의 하인들의 움직임 목록으로 응답해야합니다.

유효한 움직임은 다음과 같습니다.

  • R: 캠프로 돌아갑니다.
  • S: 보물을 찾으십시오.
  • N: 서번트가 이미 죽었거나 야영 중입니다.

유효하지 않은 움직임을 입력하는 S것은 봇이 살아 있고 캠프가 아닌 것처럼 해석됩니다 N.

매 턴이 끝날 때마다 문자열이 프로그램에 전달됩니다.

END_TURN [Turn #] [Bot 1 Moves] [Bot 2 Moves] ...

각 봇의 하인 동작은 쉼표로 구분됩니다.

이러한 움직임은 다음 중 하나입니다.

  • R: 그 차례에 캠프로 돌아 왔습니다.
  • r: 그 차례에 캠프로 돌아 오지 못했습니다.
  • S: 여전히 보물을 찾고 있습니다.
  • D: 이전 차례에 사망했습니다.
  • N: 캠프에 이미 돌아 왔습니다.

봇과 하인은 전체 시뮬레이션에서 동일한 순서로 유지됩니다.

예를 들면 다음과 같습니다.

INDEX 2
....
END_TURN 8 N,N,N,N,N r,r,r,r,D D,D,D,N,R S,D,D,N,D

여기, 당신은 두 번째 봇 ( r,r,r,r,r)이며, 여전히 살아있는 (그리고 네 개 모두에게 불행하게도 실패한) 네 종을 모두 반환하려고했습니다. 봇 1의 종들은 모두 캠프에 돌아 왔습니다. 봇 3에는 죽은 종 3 명이 있는데 한 명은 다시 캠프에 돌아 왔으며 다섯 번째 종은 성공적으로 돌아 왔습니다. 봇 4에는 한 종의 종이 있었고 (하루가 마지막 차례이므로 죽을 것임) 한 종의 야영지와 세 명의 종이 있습니다.

이 각 문자열 다음에 하루의 끝을 알리는 문자열이 출력되지 않는 한 (아래 참조) 프로그램은 하인의 다음 동작을 쉼표로 구분하여 출력합니다. 모든 종들은 ( N캠프에 D이미 있고 이미 죽은 경우) 계정을 고려해야합니다 . 잘못된 행동은 S하인이 아직 야영 / 사망하지 않은 것처럼 취급됩니다 . 예:

N,N,S,S,R

이는 다음을 의미합니다.

Servant # | Action
     1    | Do nothing.
     2    | Do nothing.
     3    | Stay put (keep looking for treasure).
     4    | Stay put (keep looking for treasure).
     5    | Try to return to camp.

하루가 끝날 때, 다음 줄은 마지막 턴의 END줄 다음에 전달 되어 살아있는 모든 사람에게 알려줍니다.

END_DAY [Day #] [Bot 1 Status] [Bot 2 Status] 

여기서 상태는 쉼표로 구분 된 A(alive) 또는 D(dead) 목록입니다 . 다음날은 바로 시작됩니다.

라이브 하인이 6 명 미만이면 시뮬레이션이 종료됩니다. 프로그램은 시뮬레이션이 끝날 때 다음과 같은 입력을받습니다 :

EXIT

규칙 / 세부 사항

  • 당신의 행동이있는 턴에만 S보물을 찾을 것입니다.
  • 실행 된 시뮬레이션 수 : 1000 회
  • 프로그램이 움직임을 결정하는 데 1 초 이상 걸리지 않아야합니다.
  • 프로그램이 일찍 종료되지 않아야합니다. 정확히 한 번 시작됩니다.
  • 각 출력 후에 출력 버퍼 (해당되는 경우)가 플러시되는지 확인하십시오.
  • 봇의 폴더 ( ./players/BotName/) 에 파일이 기록 될 수 있습니다 . 봇 이름은 영숫자가 아닌 모든 문자가 제거되고 CamelCase로 작성된 봇의 이름입니다. 실행은 순차적으로 수행되므로 컨트롤러 실행간에 데이터를 저장할 수 있습니다.
  • 프로그램을받은 후 종료해야합니다 EXIT.
  • 컴파일 또는 오류가 발생하지 않거나 유효하지 않은 텍스트 (쉼표로 구분 된 5 자의 형식이 아닌)를 출력하는 프로그램은 경쟁에서 제외 될 수 있습니다. 개행은 각 출력을 따라야합니다.
  • 컨트롤러는 GitHub 에서 찾을 수 있습니다 .

봇 이름, 언어 + 버전, 코드 및 명령 (해당되는 경우)을 작성하고 봇을 실행하십시오.

프로그램에서 출력되는 텍스트 앞에는 접두사가 붙습니다 >. 프로그램은이 문자를 출력하지 않아야합니다.

INDEX 2
START_DAY 1/3
START_TURN 1
>S,S,S,S,S
END_TURN 1 S,R,S,S,S S,S,S,S,S
START_TURN 2
>S,S,S,S,S
END_TURN 2 S,N,S,R,S S,S,S,S,S
START_TURN 3
>R,R,S,S,S
END_TURN 3 R,N,R,N,R R,R,S,S,S
START_TURN 4
>N,N,S,S,S
END_TURN 4 N,N,N,N,N N,N,S,S,S
START_TURN 5
>N,N,R,R,R
END_TURN 5 N,N,N,N,N N,N,r,r,R
END_DAY 1 A,A,A,A,A A,A,D,D,A
START_DAY 2/3
START_TURN 1
>S,S,N,S,N
END_TURN 1 R,R,R,R,R S,S,D,D,N
END_DAY 2 A,A,A,A,A D,D,D,D,D
EXIT

위 예제의 점수는 다음과 같습니다.

Bot#    Day 1   Day 2   Total
1       10      0       10
  S1    1+2     0       3
  S2    0       0       0
  S3    1+2     0       3
  S4    1       0       1
  S5    1+2     0       3

2       20      0       20
  S1    1+2     0       3
  S2    1+2     0       3
  S3    0       0       0
  S4    0       0       0
  S5    1+2+3+8 0       14

따라서 승자는 봇 2입니다. 승자는 절대 끝까지 살아남을 필요는 없습니다. (플레이어가 봇을 다시 보낼 때까지 캠프가 가득 차지 않았기 때문에 플레이어는 1 일에 30 세가 될 때까지 남아있을 수 있습니다.)

점수

Bot               Score
Bob               2939.422
Statisticians     2905.833
Morning Birds     1652.325
Evolved           1578.285
Slow Returners    1224.318
Wandering Fools   1065.908
Randomizers       735.313
Drunkards         0     
Plague            0

로그는 GitHub에서 사용 가능 합니다 . 각 평가판 당 결과는 이 Google 스프레드 시트에서 확인할 수 있습니다 .


하인이 돌아 오지 않으면, 그는 오늘 죽는 사람들의 수에 포함됩니까?
EagleV_Attnam

@EagleV_Attnam 하루 종일 돌아온 종들이 많거나 30 턴이 지나면 돌아 가지 않은 모든 사람이 조기에 결정된 사망 수에 관계없이 죽을 것입니다.
es1024

맞아, 그건 바보 같았 어, 미안
EagleV_Attnam

하인이 캠프로 돌아 오면 지금까지 찾은 보물을 배달 한 다음 같은 날 다시 찾아 갈 수 있습니까?
Logic Knight

1
@MikeSweeney 아니요. 하인이 돌아 오면 그대로 있습니다.
es1024

답변:


5

밥-C ++

#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <algorithm>

using namespace std;

int compare(int i, int j)
  {
  if (i < j)
    return (-1);
  if (i == j)
    return (0);
  if (i > j)
    return (1);
  }

int main()
  {
  int index;
  int day;
  int turn;
  int slash_index;
  int to_die;
  int num_alive;
  int mine_alive;
  int turn_to_return;
  bool returned;
  string line;
  vector<int> last_returns;
  vector<int> today_returns;

  getline(cin, line);

  if (line.compare(0, 6, "INDEX ") != 0)
    {
    cerr << "INVALID INDEX LINE \"" << line << "\"" << endl;

    return (-1);
    }

  index = atoi(line.substr(6).c_str()) - 1;

  while (1) // Day loop
    {
    getline(cin, line);
    if (line.compare(0, 4, "EXIT") == 0)
      {
      return (0);
      }
    else if (line.compare(0, 9, "START_DAY") != 0 || (slash_index = line.find('/')) == string::npos)
      {
      cerr << "INVALID START_DAY \"" << line << "\"" << endl;
      return (-1);
      }

    day = atoi(line.substr(10, slash_index - 10).c_str());
    to_die = atoi(line.substr(slash_index + 1, line.length() - slash_index - 1).c_str());

    if (day != 1)
      {
      if (to_die > num_alive)
        {
        turn_to_return = 30;
        }
      else
        {
        turn_to_return = last_returns[last_returns.size() - to_die] - 1;
        }
      }

    returned = false;

    for (turn = 1; turn <= 30; ++turn)
      {
      getline(cin, line);

      if (line.compare(0, 4, "EXIT") == 0)
        {
        return (0);
        }
      if (line.compare(0, 7, "END_DAY") == 0)
        {
        goto end_day;
        }
      if (line.compare(0, 10, "START_TURN") != 0)
        {
        cerr << "INVALID START_TURN \"" << line << "\"" << endl;
        }

      if (day == 1)
        {
        switch (compare(turn, 30))
          {
            case -1:
              cout << "S,S,S,S,S" << endl;
              break;

            case 0:
              cout << "R,R,R,R,R" << endl;
              break;

            case 1:
              cout << "N,N,N,N,N" << endl;
              break;
          }
        }
      else
        {
        if (returned)
          {
          cout << "N,N,N,N,N" << endl;
          }
        /*
        else if (num_alive - today_returns.size() < to_die)
          {
          cout << "R,R,R,R,R" << endl;
          returned = true;
          }
        */
        else if (turn >= turn_to_return)
          {
          cout << "R,R,R,R,R" << endl;
          returned = true;
          }
        else
          {
          cout << "S,S,S,S,S" << endl;
          }
        }

      getline(cin, line);

      if (line.compare(0, 4, "EXIT") == 0)
        {
        return (0);
        }
      if (line.compare(0, 8, "END_TURN") != 0)
        {
        cerr << "INVALID END_TURN \"" << line << "\"" << endl;
        }

      stringstream ss(line);
      string item;
      int i = 0;
      while (getline(ss, item, ' '))
        {
        i++;
        if (i > 2 && i - 3 != index)
          {
          int num_to_add = count(item.begin(), item.end(), 'R'); // Add turn to today_returns for each servant that returned
          for (int j = 0; j < num_to_add; j++)
            {
            today_returns.push_back(turn);
            }
          }
        }

      }

    getline(cin, line);

  end_day:

    if (line.compare(0, 4, "EXIT") == 0)
      {
      return (0);
      }
    else if (line.compare(0, 7, "END_DAY") != 0)
      {
      cerr << "INVALID END_DAY \"" << line << "\"" << endl;
      return (-1);
      }

    stringstream ss(line);
    string item;
    int i = 0;
    num_alive = 0;
    while (getline(ss, item, ' '))
      {
      i++;
      if (i > 2 && i - 3 != index)
        {
        num_alive += count(item.begin(), item.end(), 'A');
        }
      else if (i - 3 == index)
        {
        mine_alive = count(item.begin(), item.end(), 'A');
        }
      }

    last_returns = today_returns;
    today_returns.clear();

    }

  return (0);
  }

컴파일하기:

g++ -o Bob.exe Bob.cpp

실행하려면 :

./players/Bob/Bob.exe

6

통계 학자, Python 3

통계학자는 항상 협력합니다. 첫 턴에, 상대방의 3 분의 2가 그렇게했을 때 그들은 캠프로 돌아온다. 이후 차례에 그들은 이전 차례에서 수집 한 데이터에 의존하여 다른 종들의 습관을 예측하고 마지막 안전한 순간에 캠프로 돌아갑니다.

프로그램

# Team of treasure-hunting statisticians
# Run with:
# python3 statisticians.py

num_others = None
running = True
while running:
    msg = input().split()
    msg_type = msg.pop(0)
    if msg_type == "INDEX":
        my_index = int(msg[0])-1
    elif msg_type == "START_DAY":
        day, max_deaths = tuple(map(int, msg[0].split('/')))
    elif msg_type == "START_TURN":
        turn = int(msg[0])
        if day == 1:
            if turn == 1:
                print("S,S,S,S,S")
            elif turn == 30 or num_active <= max_deaths * 4/5:
                print("R,R,R,R,R") # On first day, return when 4/5 of  maximum number of dying servants remain
            else:
                print("S,S,S,S,S")
        elif turn >= 29 or len(expected_servants[turn+1]) <= max(2, max_deaths * 3/4) or len(expected_servants[turn]) <= max(2, max_deaths * 1/4):
            print("R,R,R,R,R") # If many servants are expected to return next turn or someone is sure to die, return to camp
        else:
            print("S,S,S,S,S") # Otherwise, keep going
    elif msg_type == "END_TURN":
        turn = int(msg.pop(0))
        others_moves = [tuple(s.split(',')) for s in msg[:my_index] + msg[my_index+1:]]
        if num_others is None: # End of first turn, initialize variables that depend on number of servants
            num_others = len(others_moves)
            others_history = [{} for i in range(num_others)]
        if day == 1:
            num_active = sum([move.count('S') for move in others_moves])
        for i, moves in enumerate(others_moves): # Log the return habits of other bots
            if turn == 1:
                others_history[i][day] = [0]*5
            for j, move in enumerate(moves):
                if move == "R": # Only safely returned servants are taken into account
                    others_history[i][day][j] = turn
                    if day > 1:
                        for future_turn in range(turn, 30):
                            expected_servants[future_turn].discard((i,j))
    elif msg_type == "END_DAY":
        day = int(msg.pop(0))
        my_statuses = tuple(msg[my_index].split(','))
        others_statuses = [tuple(s.split(',')) for s in msg[:my_index] + msg[my_index+1:]]
        expected_servants = [set() for i in range(30)] # Compute the sets of expected servants for each turn
        for i in range(num_others):
            for j in range(5):
                if others_statuses[i][j] == 'A':
                    turn_sum = 0
                    for day_num in others_history[i]:
                        turn_sum += others_history[i][day_num][j]
                    for turn in range(turn_sum//day):
                        expected_servants[turn].add((i,j))
    elif msg_type == "EXIT":
        running = False

보시다시피, @Mike Sweeney의 프로그램 구조를 부끄럽게 훔쳤습니다.

명령

python3 statisticians.py

편집 : 집으로 돌아 오는 수표에 버그가 수정되었습니다. 그들은 지금 어느 정도 더 잘 수행해야합니다.

편집 2 : 통계학자는 이제 전보다 똑똑합니다. 현재의 어느 종이 캠프로 돌아 왔는지 추적하고 그에 따라 예측을 조정합니다. 또한 그들은 더 많은 위험을 감수하고 죽어가는 종의 최대 수의 3/4가 남아있을 때 캠프로 돌아갑니다. 이것은 그들을 맨 위로 밀어 넣습니다 (단지 밥은 매우 위험 해졌습니다).


5

주정 뱅이, Perl 5

술이 너무 많아서 다시는 캠프로 돌아갈 수 없습니다.

이 항목은 주로 예이지만 참여합니다.

프로그램

#!/usr/bin/perl
use 5.10.1;
$| = 1; # disable buffering
@actions = qw(S S S S S);

$_ = <>; ~/^INDEX (\d+)/;
$index = $1;

while(<>){
    if(index($_, 'START_TURN') == 0){
        say join(',', @actions);
    }elsif(index($_, 'END_DAY') == 0){ 
        # update actions based on who is alive
        # index 1-indexed; first bot at position 2.
        # this is not actually necessary for Drunkards, as all of Drunkards'
        #  servants will die on day 1 in any case.
        # This check is here simply as an example.
        my @status = split(',',(split(' '))[$index + 1]);
        my $i;
        for($i = 0; $i < 5; ++$i){
            # action is S if alive, N if dead. Servants will never be in camp.
            $actions[$i] = $status[$i] eq 'A' ? 'S' : 'N';
        }
    }elsif(index($_, 'EXIT') == 0){
        exit 0;
    }
}

명령

perl ./players/Drunkards/Drunkards.pl

코드 $status[$i] eq 'A' ? 'S' : 'D';$status[$i] eq 'A' ? 'S' : 'N';사양을 충족 해야합니까 ?
Logic Knight

@MikeSweeney 잘 잡아라. 이 도전이 여전히 샌드 박스에있는 동안 사양을 변경했을 때 문제를 해결하는 것을 잊었습니다.
es1024

4

아침 새

이른 새가 벌레를 잡는다! !!

package players.MorningBirds;

import java.io.*;
import java.util.*;

/*
 * Java 7
 * 
 * Compile with "javac ./players/MorningBirds/MorningBirds.java"
 * Run with "java players.MorningBirds.MorningBirds"
 * 
 * Servants find treasure from morning until noon.
 * At noon they go to bed to prepare for next day.
 * 
 * According to Benjamin Franklin, "Early to bed, early to rise, keeps a 
 *      man healthy, WEALTHY, and wise."
 * 
 * 
 */
public class MorningBirds {

    protected final static String STARTDAY = "START_DAY";

    protected final static String STARTTURN = "START_TURN";

    protected final static String ENDTURN = "END_TURN";

    protected final static String ENDDAY = "END_DAY";

    protected final static String MOVERETURN = "R";

    protected final static String MOVESEARCH = "S";

    protected final static String MOVENOTHING = "N";

    protected final static String RETURNED = "R";

    protected final static String FAILEDRETURN = "r";

    protected final static String SEARCHING = "S";

    protected final static String DEAD = "D";

    protected final static String SLEEPING = "N";

    protected final static String EXIT = "EXIT";

    protected final static String ALIVE = "A";

    protected enum Status{SEARCHING, DEAD, RETURNED}

    protected enum Move{RETURN, SEARCH, NOTHING}

    protected int index;

    protected int day;

    protected int turnNum;

    protected int howManyTeams;

    protected int howManyWillDieTodayAtMost;

    protected int howManyHaveDiedToday;

    protected int howManyEnemyPlayers;

    protected int howManyAliveEnemyPlayers;

    protected int howManyEnemyTeams;

    protected int howManyDeadEnemyPlayers;

    protected int howManyReturnedEnemyPlayers;

    protected int howManySearchingEnemyPlayers;

    protected int howManyTotalPlayers;

    protected int howManyTotalAlivePlayers;

    protected int howManyTotalDeadPlayers;

    protected int howManyTotalReturnedPlayers;

    protected int howManyTotalSearchingPlayers;

    protected int howManyOwnAlivePlayers;

    protected int howManyOwnDeadPlayers;

    protected int howManyOwnReturnedPlayers;

    protected int howManyOwnSearchingPlayers;

    protected Status[] statuses = new Status[5];

    protected Status[][] allStatuses = null;

    protected List<Status[][]> allDayStatuses = null;

    protected List<List<Status[][]>> allTimeStatuses = new ArrayList<>();

    protected BufferedReader in = new BufferedReader(
            new InputStreamReader(System.in));

    public static void main (String args[]) throws Exception{
        new MorningBirds().start();
    }

    public void start() throws Exception{

        index = Integer.parseInt(in.readLine().split("\\s")[1]);
        Arrays.fill(statuses, Status.SEARCHING);

        while(true){
            String[] input = in.readLine().split("\\s");
            if (input[0].equals(ENDTURN) || input[0].equals(ENDDAY)){
                updateStatus(input);
            } else if (input[0].equals(EXIT)){
                return;
            } else if (input[0].equals(STARTDAY)){
                updateDay(input);
            } else if (input[0].equals(STARTTURN)){
                updateTurn(input);
                doTurn(input);
            }

        }

    }

    protected void updateStatus(String[] input){
        if (allStatuses == null && input[0].equals(ENDTURN)){
            allStatuses = new Status[input.length - 2][5];
            for (Status[] enemyStatus : allStatuses){
                Arrays.fill(enemyStatus, Status.SEARCHING);
            }
            howManyTeams = input.length - 2;
            howManyEnemyTeams = input.length - 3;
            howManyTotalPlayers = howManyTeams * 5;
            howManyTotalAlivePlayers = howManyTotalPlayers;
            howManyTotalSearchingPlayers = howManyTotalAlivePlayers;
            howManyAliveEnemyPlayers = howManyTotalPlayers - 5;
            howManyEnemyPlayers = howManyEnemyTeams * 5;
            howManyOwnAlivePlayers = 5;
            howManyOwnSearchingPlayers = 5;
            howManySearchingEnemyPlayers = howManyAliveEnemyPlayers;
        }
        for ( int j = 0; j < howManyTeams; j++){
            String[] stats = input[j + 2].split(",");
            for(int i = 0; i < 5; i++){
                switch (stats[i]){
                    case "R":
                    case "N":
                        if (allStatuses[j][i] != Status.RETURNED){
                            howManyTotalReturnedPlayers++;
                            howManyTotalSearchingPlayers--;
                            if (j == index - 1) {
                                howManyOwnReturnedPlayers++;
                                howManyOwnSearchingPlayers--;
                            } else {
                                howManyReturnedEnemyPlayers++;
                                howManySearchingEnemyPlayers--;
                            }
                        }
                        allStatuses[j][i] = Status.RETURNED;
                        break;
                    case "A":
                    case "S":
                        if (allStatuses[j][i] != Status.SEARCHING){
                            howManyTotalReturnedPlayers--;
                            howManyTotalSearchingPlayers++;
                            if (j == index - 1) {
                                howManyOwnReturnedPlayers--;
                                howManyOwnSearchingPlayers++;
                            } else {
                                howManyReturnedEnemyPlayers--;
                                howManySearchingEnemyPlayers++;
                            }
                        }
                        allStatuses[j][i] = Status.SEARCHING;
                        break;
                    case "r":
                    case "D":
                        if (allStatuses[j][i] != Status.DEAD){
                            howManyTotalAlivePlayers--;
                            howManyTotalDeadPlayers++;
                            howManyHaveDiedToday++;
                            howManyTotalSearchingPlayers--;
                            if (j == index - 1){
                                howManyOwnAlivePlayers--;
                                howManyOwnDeadPlayers++;
                                howManyOwnSearchingPlayers--;
                            } else {
                                howManyAliveEnemyPlayers--;
                                howManyDeadEnemyPlayers++;
                                howManySearchingEnemyPlayers--;
                            }
                        }
                        allStatuses[j][i] = Status.DEAD;
                        break;
                    default:
                        break;
                }
            }
        }
        statuses = allStatuses[index - 1];
        if (input[0].equals(ENDTURN)){
            allDayStatuses.add(allStatuses.clone());
        }
        if (input[0].equals(ENDDAY)){
            Status[][] statusesToAdd = new Status[howManyTeams][5];
            for (int i = 0; i < statusesToAdd.length; i++){
                for (int j = 0; j < statusesToAdd[i].length; j++){
                    if (allStatuses[i][j] == Status.SEARCHING){
                        statusesToAdd[i][j] = Status.RETURNED;
                    } else {
                        statusesToAdd[i][j] = Status.DEAD;
                    }
                }
            }
            while (turnNum <= 30){
                allDayStatuses.add(statusesToAdd.clone());
                turnNum++;
            }
            allTimeStatuses.add(allDayStatuses);
        }
    }

    protected void updateDay(String[] input) throws Exception{
        day = Integer.parseInt(input[1].split("/")[0]);
        howManyWillDieTodayAtMost = Integer.parseInt(input[1].split("/")[1]);
        howManyHaveDiedToday = 0;
        allDayStatuses = new ArrayList<>();
        if (day == 1){
            Arrays.fill(statuses, Status.SEARCHING);
            howManyOwnAlivePlayers = 5;
            howManyOwnSearchingPlayers = 5;
        }
    }

    protected void updateTurn(String[] input){
        turnNum = Integer.parseInt(input[1]);
    }

    protected void doTurn(String[] input){
        Move[] moves = new Move[5];
        for (int i = 0; i < 5; i++){
            if (statuses[i] == Status.DEAD ||
                        statuses[i] == Status.RETURNED) {
                moves[i] = Move.NOTHING;
                continue;
            } else {
                moves[i] = doMove(i);
            }
        }
        String[] outputs = new String[5];
        for (int i = 0; i < 5; i++){
            switch (moves[i]){
                case SEARCH:
                    outputs[i] = MOVESEARCH;
                    break;
                case RETURN:
                    outputs[i] = MOVERETURN;
                    break;
                case NOTHING:
                    outputs[i] = MOVENOTHING;
            }
        }
        String totalOutput = "";
        for(String output : outputs){
            if (totalOutput != ""){
                totalOutput += ",";
            }
            totalOutput += output;
        }
         System.out.println(totalOutput);
    }

    //Implement this method differently for different 
    //strategies. 
    public Move doMove(int playerNumber){
        if (turnNum >= 15){
            return Move.RETURN;
        }
        return Move.SEARCH;
    }

    /**
     * Returns the status of one of your players. 
     * Your players have numbers 1 to 5 inclusive.
     * Throws exception if number is outside range.
     * 
     */
    protected Status getStatus(int player){
        if (player > 5 || player < 1){
            throw new IllegalArgumentException(
                    "getStatus(" + player +") failed.");
        }
        return statuses[player - 1];
    }

    /**
     * Returns the status of a player in a team.
     * Team numbers start with 1 inclusive.
     * Players have numbers 1 to 5 inclusive.
     * Throws exception if argument player is outside range.
     * Throws exception if argument team is less than 1 or is greater
     * than the number of teams.
     * Returns Status.SEARCHING if day == 1 and turnNum == 1 and argument 
     * team >= 1.
     */
    protected Status getStatus(int team, int player){
        if (team < 1 || player < 1 || player > 1 || 
                (team > howManyTeams && day == 1 && turnNum == 1)){
            throw new IllegalArgumentException(
                    "getStatus(" + team + ", " + player + ") failed.");
        }
        if (day == 1 && turnNum == 1 && team >= 1){
            return Status.SEARCHING;
        }
        return allStatuses[team - 1][player - 1];
    }

    /**
     * Returns the status of a player in a team at the end of argument
     * turn.
     * Team numbers start with 1 inclusive.
     * Players have numbers 1 to 5 inclusive.
     * Turns have numbers 0 to 30 inclusive.
     * Status at turn 0 is equal to status at start of turn 1.
     * Throws exception if argument turn hasn't happened yet.
     * Throws exception if argument player is outside range.
     * Throws exception if argument team is less than 1 or is greater
     * than the number of teams.
     */
    protected Status getStatus(int turn, int team, int player){
        if (turn == 0){
            if (day == 1){
                return Status.SEARCHING;
            } else {
                return getStatus(day - 1, 30, team, player);
            }
        }
        if (turnNum <= turn || turn < 0|| player > 5 || player < 1 ||
                team < 1 || team > howManyTeams){
            throw new IllegalArgumentException("getStatus(" + turn + 
                    ", " + team + ", " + player + ") failed.");
        }
        return allDayStatuses.get(turn - 1)[team - 1][player - 1];
    }

    /**
     * Returns the status of a player in a team at the end of argument
     * turn on the day of argument day.
     * Team numbers start with 1 inclusive.
     * Players have numbers 1 to 5 inclusive.
     * Turns have numbers 0 to 30 inclusive.
     * Days have numbers 1 inclusive and up.
     * Status at turn 0 is equal to status at start of turn 1.
     * Throws exception if argument day hasn't ended yet or is less 
     * than one.
     * Throws exception if argument turn is out of range.
     * Throws exception if argument player is outside range.
     * Throws exception if argument team is less than 1 or is greater
     * than the number of teams.
     */
    protected Status getStatus(int day, int turn, int team, int player){
        if (turn == 0){
            if (day == 1){
                return Status.SEARCHING;
            } else {
                return getStatus(day - 1, 30, team, player);
            }
        }
        if (this.day <= day || day < 1 || turn > 30 || turn < 0 || 
                player > 5 || player < 1 ||
                team < 1 || team > howManyTeams){
            throw new IllegalArgumentException("getStatus(" + day + ", "
                    + turn + ", " + team + ", " + player + ") failed.");
        }
        return allTimeStatuses.get(day - 1).get(turn - 1)[team - 1][player - 1];
    }

}

편집 : 누구나 쉽게 서브 클래스 화 할 수 있도록했습니다. doMove(int playerNumber)자신의 봇에 맞게 재정의 하십시오. 몇 가지 유용한 필드와 방법을 추가했습니다. 나는 그것을 광범위하게 테스트했습니다. 이전 시뮬레이션의 상태를 저장 하지 않습니다 . 문제가 있으면 알려주십시오.

다음과 같이 컴파일하십시오. javac ./players/MorningBirds/MorningBirds.java

로 실행 : java players.MorningBirds.MorningBirds


메소드와 변수를 보호하고 나중에 도전을 위해 하위 클래스를 만들면 괜찮습니까?
TheNumberOne

필요한 경우 여러 소스 파일을 사용하거나 항목이 함께 작동하지 않는 한 다른 항목의 코드를 재사용하십시오.
es1024

@ es1024 실험에서 나는 1 번부터 하루 종일 아무것도하지 않으면 봇이 죽는 것을 발견했다.
TheNumberOne

R특정 날짜에 ( )를 반환하지 않는 봇 은 항상 그 날 죽습니다.
es1024

플레이어 SlowReturners 및 Randomizer를 추가하면 컨트롤러가 응답하지 않습니다. 참고 : 죄송합니다. 여기에 의견을 게시하고 있습니다. 다른 곳에 게시하는 데 필요한 평판이 없습니다.
TheNumberOne

3

랜덤 라이저-Ruby

통계 기반 봇을 망치기 위해 무작위 추출기는 예측할 수 없습니다. 그들 모두는 다른 사람들을 좌초 시키려고 한 번에 무작위로 돌아옵니다.

(다른 플레이어의 영향을받지 않습니다.)

def min(a,b);(a<b)?a:b;end
x=""
r=0
while x != "EXIT"
  x=gets.chomp
  if x =~ /^START_DAY/
    r = min(rand(30),rand(30))
  end
  if x =~ /^START_TURN (\d*)/
    puts ($1.to_i>r)?'R,R,R,R,R':'S,S,S,S,S'
  end
end

2

방황 바보, 파이썬 2

이것은 미리 설정된 "돌아 가기"시간에 도달 할 때까지 하인을 보내는 간단한 Python 봇이며, 캠프에 들어가서 다음 날까지 머물려고합니다.

또한 다른 사람들이 사용하기를 원하는보다 복잡한 봇을위한 기본 프레임 워크입니다. 그러나 판사 엔진에서는 테스트를 거치지 않았으므로 오류가 발생했는지 알려주십시오.

프로그램

import sys
from random import randint, choice
team = range(5)

while True:
    inp = sys.stdin.readline().split()
    cmd = inp.pop(0)
    if cmd == 'INDEX':
        teamnum = int(inp[0]) - 1   # using zero based indexing
    elif cmd == 'START_DAY':
        daynum, deadnum = [int(v) for v in inp[0].split('/')]
        # Set up strategy for the day:
        goback = [randint(5,25) for i in team]
    elif cmd == 'START_TURN':
        turn = int(inp[0])
        # Output actions [R]eturn, [S]earch, [N]othing here:
        actions = ['S' if turn < goback[i] else 'R' for i in team]
        sys.stdout.write( (','.join(actions)) + '\n' )
        sys.stdout.flush()
    elif cmd == 'END_TURN':
        endturn = int(inp.pop(0))
        status = [v.split(',') for v in inp]  # R,r,S,D,N
        # [R]eturned, [r]ejected, [S]earching, [D]ead, [N]othing
        mystatus = status[teamnum]
    elif cmd == 'END_DAY':
        endturn = int(inp.pop(0))
        alive = [v.split(',') for v in inp]  # [A]live or [D]ead
        myalive = alive[teamnum]
    elif cmd == 'EXIT':
        sys.exit(0)

명령

python WanderingFools.py

편집 : 규칙 설명 후 작업 결정 코드가 변경되었습니다.


2

진화

이 봇을 만들기 위해 JGAP를 통한 유전자 프로그래밍을 사용했습니다. 그것은 다른 모든 것을 능가하는 간단한 대답을 제시했습니다 (거의).

package players.Evolved;

import players.MorningBirds.*;
import java.util.*;

public class Evolved extends MorningBirds{

    List<Integer> scrambled = new ArrayList<>();

    public static void main(String[] args) throws Exception{
        new Evolved().start();
    }

    public Evolved() throws Exception{
        super();
    }

    @Override
    public MorningBirds.Move doMove(int playerNum){
        if (!(howManyTotalSearchingPlayers < (turnNum - getScrambled(index)))){
            return Move.SEARCH;
        } else {
            return Move.RETURN;
        }
    }

    @Override
    protected void updateStatus(String[] input){
        super.updateStatus(input);
        if (input[0].equals(ENDTURN) && (Integer.parseInt(input[1]) == 1)){
            for (int i = 1; i <= howManyTeams; i++){
                scrambled.add(i);
            }
            Collections.shuffle(scrambled);
        }
    } 

    public int getScrambled(int in){
        if (in > scrambled.size() || in < 1 ){
            return in;
        }
        return scrambled.get(in - 1);
    }
}

다음과 같이 컴파일하십시오. javac players/Evolved/Evolved.java

로 실행 : java players.Evolved.Evolved

편집 : Grrr ... 밥이 나를 엉망!

편집 : 예! 밥, 불쾌한 재앙으로 죽었다 !!!


1

SlowReturners-루비

5 턴마다 한 종을 되돌립니다.

x=""
while x != "EXIT"
  x=gets.chomp
  if x =~ /^START_TURN (\d*)/
    puts (1..5).map{|i|(i<=$1.to_i/5)?"R":"S"}.join(",")
  end
end

1

역병

전염병은 질병입니다. 합리적이지 않습니다. 예측 가능합니다. 질병은 보물을 모을 수없고 보물을 돌볼 수도 없습니다. 역병은 다른 플레이어를 아프게 만듭니다. 현명한 사람들은 집에 머물면서 보물을 잊습니다. 어리석은 사람들은 항상 어리 석고 많은 보물을 얻지 못할 것입니다. 진화는 전염병에 면역입니다. 그는 또한 현명하다. 그는 가서 보물을 모으고 죽지 않습니다.

package players.Plague;

import players.MorningBirds.MorningBirds;

public class Plague extends MorningBirds{

    public static void main(String[] args) throws Exception{
        new Plague().start();
    }

    public Plague() throws Exception{
        super();
    }

    @Override
    public MorningBirds.Move doMove(int playerNum){
        if (day > howManyTotalDeadPlayers){
            return Move.SEARCH;
        } else {
            return Move.RETURN;
        }
    }
}

다음과 같이 컴파일하십시오. javac players/Plague/Plague.java

로 실행 : java players.Plague.Plague

밥과 통계학자는 이제 역병에 저항합니다.


흠 ...이 봇을 실행하면 항상 첫날에 죽어 ...

나는 이것을 만들기 위해 유전자 알고리즘을 사용했다. 둘째 날에 죽어야한다. 통계 기반 봇을 엉망으로 만들어 Evolved와 비교했을 때 성능이 크게 떨어졌습니다.
TheNumberOne
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.