Issız bir adada hazine avı


13

Giriş

Bazı hizmetçilerle birlikte ıssız bir adada mahsur kaldınız ve hazine için avlanıyorsunuz. Ne kadar uzun arama yaparsa, o kadar çok hazine bulur. Ne kadar az kişi ararsa, o kadar çok kişi bulur.

Sınırlı tedarik nedeniyle, lider grubun dörtte birine kadar birkaç kişinin her gece ölüme terk edilmesine karar verdi. Kimseye önceden belli bir günde kaç kişinin öleceğini tam olarak söylememeye karar verdi.

Sizin için hazine bulmak için kamptan dışarı çıkacak 5 kişilik küçük bir grubun kontrolündesiniz.

Amaç

Bu yarışmanın amacı mümkün olduğunca çok hazineyi toplamaktır. Hizmetçilerin kampa dönmeye çalışmadığı her dönüşte belirli sayıda hazine bulacaklar. Hizmetçileriniz farklı zamanlarda kampa dönebilirler.

Bir işçinin hazine aramak için dışarıda kaldığı her dönüşte, işçi zaten kampta bulunan işçi sayısının (tüm botlardan) 1+Rbulunduğu hazinenin parçalarını bulur R. Ölü botlar bu hesaplamayı hesaba katmaz.

Her günün başlangıcında, bir rasgele sayı ( ndan) 2için max(3, floor(num_live_players/4))seçilecektir. (1. gün 10 oyuncular için bu 2kadar max(3,50/4)=12günde 1 20 oynatıcılarda, bu olurdu. 2İçin max(3,100/4)=25bu sayı o gün için ölüme terk edilecek oyuncu sayısını gösterir.), Ve programa verilmeyecek .

Eğer bir hizmetçi ngeri dönen son kişilerden biriyse, ölecek ve bulduğu hazineyi elinize devredemeyecektir. Ayrıca, hizmetçi maceranın geri kalanı için hazine avına katılamaz.

Nihai skorunuz, macera başına elde ettiğiniz ortalama hazine miktarıdır (kontrolörün çalışması).

Açık slotlardan daha fazla kişi aynı dönüşte kampa dönmeye çalışırsa, rasgele sayılar kimin girip kimin öldüğünü belirler.

Bu adada gün doğumundan gün batımına kadar bir gün 30 tur sürer. Geceleri çok sayıda tehlikeli hayvan olduğu için gün batımına dönmemek kampa girmenize izin verilmeyeceği anlamına gelir.

Giriş çıkış

Programınız simülasyonun tamamı için çalışmalıdır.

Simülasyonun başlangıcında, botunuzun dizini INDEX Inerede Igirilir (bu dizin 1'den sayılır).

Her günün başlangıcında , gün sayısına (başlangıçtan itibaren ) ve eşit olan START_DAY D/Nprogramınıza girilir; bu D, o gün ölen maksimum kişi sayısıdır.1Nmax(3, floor(num_live_players/4))

Her START_TURN Tturun başlangıcında, programınıza girilir, burada Ttur numarası (başlangıçtan itibaren 1).

Programınız bunu aldıktan sonra, hizmetçilerinizin her birinin virgülle ayrılmış hareketlerinin bir listesiyle yanıt vermesi gerekir.

Geçerli hamleler:

  • R: Kampa dönmeye çalışın.
  • S: Hazine aramaya devam et.
  • N: Hizmetçi zaten öldü ya da kampta.

Geçersiz bir hamle girmek Sbot kampta değil, kampta değil gibi yorumlanacaktır N.

Her turun sonunda, programınıza bir dize geçirilir:

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

burada her botun hizmetkarlarının hareketleri virgülle ayrılır.

Bu hamleler aşağıdakilerden biri olacaktır:

  • R: Başarıyla bu dönüş kampına döndü.
  • r: Bu dönüş kampına geri dönemedi.
  • S: Hala hazine arýyor.
  • D: Daha erken dönerek öldü.
  • N: Zaten kampa geri döndüm.

Botlar ve hizmetçiler tüm simülasyon boyunca aynı sırada kalır.

Örneğin:

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

Burada, r,r,r,r,rhala hayatta olan (ve şanssız bir şekilde dördünde de başarısız olan) dört hizmetçiyi geri vermeye çalışan ikinci bot ( ) sensin . Bot 1'in hizmetçileri kampa geri döndüler. Bot 3, biri kampta olmak üzere üç ölü hizmetçiye ve başarılı bir şekilde geri dönen beşinci hizmetçiye sahiptir. Bot 4'te kalan bir hizmetçi vardır (ve bu günün son dönüşü olarak ölecektir), kampta bir hizmetçi ve üç ölü hizmetçi vardır.

Bu dizelerden her birinin ardından, günün sonunu belirten bir dize de çıkmadıysa (aşağıya bakın), programınız hizmetçilerinizin virgülle ayırarak sonraki hareketlerini çıkarmasıdır. Tüm hizmetliler hesaplanmalıdır ( Nzaten kamptaysa ve Dzaten ölmüşse). Geçersiz hamleler S, hizmetçi zaten kampta / ölüde değilmiş gibi ele alınacaktır . Misal:

N,N,S,S,R

bunun anlamı:

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.

Bir günün sonunda END, kimin hayatta olduğunu bildiren son sıradaki ipin ardından aşağıdaki ip geçilir :

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

burada durum virgülle ayrılmış A(canlı) veya D(ölü) bir listedir . Ertesi gün hemen sonra başlar.

Simülasyon, 6'dan az canlı hizmetli olduğunda sona erer. Programınız simülasyonun sonunda aşağıdaki girdiyi alacaktır:

EXIT

Kurallar / Detaylar

  • Sadece eyleminizin olduğu Ssıralarda hazine bulacaksınız.
  • Gerçekleştirilen simülasyon sayısı: 1000 kez
  • Hareketlerinizi belirlemek için programınızın 1 saniyeden fazla sürmemesi gerekir.
  • Programınız erken çıkmamalıdır; tam olarak bir kez başlatılacak.
  • Her çıkışın ardından çıktı arabelleğinin (varsa) temizlendiğinden emin olun.
  • Dosyalar bot klasörünüze ( ./players/BotName/) yazılabilir . Bot adınız, botunuza adınız ne olursa olsun, tüm alfasayısal olmayan karakterler kaldırıldı ve CamelCase'de yazıldı. Girişler, sıralı olarak yapıldığından denetleyicinin çalışması arasında veri kaydedebilir.
  • Programınız alındıktan sonra çıkmalıdır EXIT.
  • Hata derleyemeyen veya atmayan veya geçersiz metin (virgülle ayrılmış 5 karakter biçiminde olmayan) çıkaran programlar yarışmanın dışında bırakılabilir. Her çıkışı yeni satır takip etmelidir.
  • Denetleyici GitHub'da bulunabilir .

Lütfen bot adını, dil + sürümünü, kodu ve botunuzu derlemek (varsa) ve çalıştırmak için komut ekleyin.

Misal

Program tarafından çıkarılan metnin önüne a ile gelir >. Programınız bu karakteri çıktılamamalıdır.

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

Yukarıdaki örneğin puanları:

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

Bu yüzden kazanan oyuncu, bot 2'dir. Kazananın mutlak sona kadar hayatta kalması gerekmediğini unutmayın. (Ayrıca, oyuncu bir gün daha geri gönderene kadar kampın dolu olmayacağından, 1. günde 30'a kadar oyuncu kalabilirdi).

Skorlar

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

Günlükler GitHub'da bulunur . Her deneme başına sonuçlar bu Google e-tablosunda mevcuttur .


Bir hizmetçi geri dönmezse, bu gün ölen insan sayısına sayılıyor mu?
EagleV_Attnam

@EagleV_Attnam Gün, daha önce belirlenen ölüm sayısına bakılmaksızın, geri dönen yeterli hizmetçi olduğunda veya geri dönmeyen herkesin öleceği 30 dönüş geçtiğinde sona erer.
es1024

Tamam, bu aptalca, üzgünüm.
EagleV_Attnam

Bir hizmetçi kampa geri dönerse, şimdiye kadar bulunan hazineyi teslim edip aynı gün tekrar aramak için dışarı çıkabilir mi?
Mantık Şövalyesi

1
Bir hizmetçi geri döndüğünde kalır.
es1024

Yanıtlar:


5

Bob - 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);
  }

Derlemek için:

g++ -o Bob.exe Bob.cpp

Koşmak:

./players/Bob/Bob.exe

6

İstatistikçiler, Python 3

İstatistikçiler her zaman birlikte çalışırlar. İlk dönüşte, rakiplerinin üçte ikisi bunu yaptığında kampa geri dönüyorlar. Sonraki dönüşlerde, diğer hizmetçilerin alışkanlıklarını tahmin etmek için önceki dönüşlerden topladıkları verilere güveniyorlar ve son güvenli anda kampa geri dönmeye çalışıyorlar.

program

# 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

Gördüğünüz gibi program yapısını utanmadan @Mike Sweeney'den çaldım.

komuta

python3 statisticians.py

DÜZENLEME: Eve dönüş kontrolündeki bir hata düzeltildi. Şimdi biraz daha iyi performans göstermeliler.

DÜZENLEME 2: İstatistikçiler artık öncekinden daha akıllılar: mevcut hizmetçilerin kampa geri döndüklerini takip ediyorlar ve tahminlerini buna göre ayarlıyorlar. Ayrıca, daha fazla risk alırlar ve maksimum ölmekte olan hizmetçinin 3 / 4'ü kaldığında kampa geri dönerler. Bu onları tekrar yukarı iter (zar zor; Bob çok tehlikeli hale geldi).


5

Sarhoşlar, Perl 5

Biraz fazla alkol ve asla kampa dönüş yolunu bulamazlar.

Bu giriş öncelikle bir örnektir, ancak katılacaktır.

program

#!/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;
    }
}

komuta

perl ./players/Drunkards/Drunkards.pl

Kodunuzu mı $status[$i] eq 'A' ? 'S' : 'D';olmak $status[$i] eq 'A' ? 'S' : 'N';özelliklerini karşılamıyor mu?
Mantık Şövalyesi

@MikeSweeney İyi yakaladın. Bu meydan okuma hala sanal alanda iken spec değiştirdiğimde düzeltmeyi unuttum.
es1024 15:14

4

Sabah kuşları

Erken kalkan yol alır!!!

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];
    }

}

Düzenleme: Herkes kolayca alt sınıf olabilir böylece yaptı. Sadece doMove(int playerNumber)kendi botunuz için yeniden tanımlayın . Birkaç yararlı alan ve yöntem ekledim. Bunu kapsamlı bir şekilde test ettim. O mu değil önceki simülasyonlar gelen durumları kaydedin. Lütfen herhangi bir sorun olup olmadığını söyle.

Şununla derleyin: javac ./players/MorningBirds/MorningBirds.java

Şununla çalıştır: java players.MorningBirds.MorningBirds


Yöntemleri ve değişkenleri koruma altına alıp daha sonra meydan okuma için bunun bir alt sınıfını yapmam uygun olur mu?
TheNumberOne

Gerekirse birden fazla kaynak dosyası kullanmaktan çekinmeyin veya girişler birlikte çalışmadığı sürece kodu diğer girdilerden yeniden kullanın.
es1024

@ es1024 Denemede bir botun 1 gün boyunca hiç bir şey yapmazsa öldüğünü fark ettim.
TheNumberOne

RHerhangi bir günde ( ) döndürmeyen bir bot her zaman o gün ölecektir.
es1024

Oyuncu SlowReturners ve Randomizers eklersem denetleyici yanıt vermiyor. Not: Üzgünüm, buraya yorum gönderiyorum. Başka bir yerde yayınlamak için gereken itibarım yok.
TheNumberOne

3

Randomizörler - Ruby

Sadece istatistik odaklı botları karıştırmak için, randomizatörler oldukça tahmin edilemez. Hepsi bir anda, başkalarını sarmak için rastgele bir dönüşle geri dönüyor.

(Diğer oyunculardan etkilenmez.)

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

Gezinti Şakaları, Python 2

Bu, önceden ayarlanmış bir "geri gitme" zamanına ulaşana kadar hizmetçileri gönderen basit bir Python botudur, daha sonra kampa girmeye ve ertesi güne kadar kalmaya çalışırlar.

Aynı zamanda, başkalarının kullanmak isteyebileceği daha karmaşık botlar için temel bir çerçevedir. Bununla birlikte, hakim motor ile test edilmemiştir, bu yüzden bir hata yapıp yapmadığımı bana bildirin.

program

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)

komuta

python WanderingFools.py

Düzenleme: Kural açıklaması sonrasında kod karar verme eylemi değiştirildi.


2

Evolved

Bu botu yapmak için Genetik Programlama (JGAP aracılığıyla) kullandım. Diğerlerini (zar zor) yenen basit bir cevap geldi.

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);
    }
}

Şununla derleyin: javac players/Evolved/Evolved.java

Şununla çalıştır: java players.Evolved.Evolved

Edit: Grrr ... Bob beni berbat !!!

Düzenle: Yay !!! Bob, kötü bir veba tarafından öldürüldü !!!


1

SlowReturners - Yakut

Her 5 turda bir hizmetçi geri gönderir.

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

Veba

Veba bir hastalıktır. Rasyonel değil. Tahmin edilebilir. Hastalıklar hazineyi toplayamaz ve hazineye önem vermez. Veba diğer oyuncuları hasta eder. Bilge olanlar evde kalır ve hazineyi unuturlar. Aptal olanlar her zaman aptaldır ve asla çok fazla hazine alamazlar. Evrim geçirdi ve (neyse ki) Veba'ya karşı bağışık. O da bilge. Gidiyor, hazine topluyor ve ölmüyor.

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;
        }
    }
}

Şununla derleyin: javac players/Plague/Plague.java

Şununla çalıştır: java players.Plague.Plague

Bob ve İstatistikçiler artık vebaya karşı dirençli.


hmm ... bu botu çalıştırdığımda her zaman ilk günde ölüyor ...

Bunu yapmak için genetik bir algoritma kullandım. İkinci gün ölmeli. Evrim ile karşılaştırıldığında oldukça kötü performans göstermeleri için istatistik güdümlü botları dağıtır.
TheNumberOne
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.