Bozuk Para Atma Zamanı Gezginleri


19

Gelecekte Time Travel (TT olarak kısaltılır) yaygın olacağı zaman, bozuk para atma ciddi bir zihin sporu haline gelecektir. Geleceğe hazırlanmak için, zaman yolculuğunun girişlerin bakış açısından gerçekten gerçekleşeceği programlar için bir yarışma yaratıyoruz.

Yarışma, Java sınıfları arasında madeni para savurma maçlarından oluşan yuvarlak-robin tarzı bir King of the Hill'dir.

Jeton savurma maçının kuralları

  • İki oyuncu ve 100 mermi var.
  • Her turda bir para atılır ve sonuca göre oyunculardan biri 1 puan alır. Her oyuncunun bir puan kazanma şansı% 50'dir.
  • Savurmadan sonra her iki oyuncunun da kolları çekerek zamanı kontrol etme şansı vardır.
  • Mavi bir kolu çekerseniz (geri durdurucu) , kolun kullanıldığı turda veya artık herhangi bir turda TT mümkün değildir. TT'nin bu turlara gitmeye çalışmasının hiçbir etkisi olmayacaktır.
  • Eğer bir çekersen kırmızı kolu (Reverter) Bir önceki turda zamanı geri dönmek için deneyin. Başarılı olursa, rakibin hafızası seçilen turdan önce hafızasına döndürülecek ve seçilen turdan başlayan jeton atma sonuçları da silinecektir . Rakibiniz için TT ile ilgili tek olası işaret, geri alınmayacak olan kullanılmamış kollarının sayısı olacaktır.
  • Her oyuncunun maçın başında 5 mavi ve 20 kırmızı kullanılmamış kolu vardır. Bu kollar TT'lerden etkilenmez.
  • 100. turun sonunda TT olmazsa oyun sona erer ve en yüksek puana sahip oyuncu kazanır.

ayrıntılar

  • Mermilerin 1 tabanlı bir dizini vardır (form 1 ila 100).
  • Turdan önce xsize mevcut mavi ve kırmızı kolların sayısı, jeton dönüşe x(dahil) ve (son) x-1turunuzun hafızasına kadar sonuçları verir .
  • Mavi bir kolu yuvarlak olarak xçekmek, turda xveya daha önce bir varış yeri olan TT'leri durdurur (aynı turda da bir TT'yi engeller).
  • Tura geri dönmek x, bir sonraki turun yuvarlak olacağı anlamına gelir x.
  • Her iki oyuncu da bir raundun sonunda geri dönmeyi seçerse, zaman engellenmeyen önceki hedefe geri döner. Bu zamana geri dönmeye çalışan oyuncular hafızalarını koruyacak.

Teknik detaylar

  • Sağlanan Bot arabirimini uygulayan bir Java sınıfı yazmalısınız.
  • Botunuzu projeye ekleyin.
  • BotDosyaya Bot'unuzun bir örneğini ekleyin Controller.java.
  • Sınıfınız aramalar arasında bilgi bulundurmamalıdır . (Çoğu durumda yalnızca finalişlevlerin dışında değişkenler olması bu gereksinimi karşılar.)
  • memoryDöndürülen Actionnesnenizin alanındaki denetleyiciye bilgi verebilirsiniz . TT olmazsa, bir sonraki dönüşte size geri verilecektir. Bir TT gerçekleşirse, daha önceki ilgili belleğinizi alırsınız.
  • Bir geçmiş dizesinin puanını almak için sınıf totalScore()yöntemini kullanabilirsiniz Game.

Protokol

  • Her dönüşte takeTurn(...)yönteminiz 5 argümanla çağrılır:

    • kullanılmayan mavi kaldıraç sayısı
    • kullanılmayan kırmızı kol sayısı
    • jeton savurma geçmişi, önceki turlarda kazancınızı ve kayıplarınızı gösteren 1 ve 0'lardan oluşan bir dize. İlk karakter ilk madeni paraya karşılık gelir. (İlk turda dize uzunluğu olacaktır 1.)
    • bir dizge, önceki turda depolanan belleğiniz
    • bu turun 1 tabanlı endeksi
  • Her dönüşte yönteminiz aşağıdakileri Actioniçeren bir nesne döndürür:

    • movealandaki işleminizi açıklayan bir tam sayı :

      • 0 eylemsiz
      • -1 mavi bir kolu çekmek ve TT'nin bu turdan geçmesini engellemek için
      • xkırmızı bir kolu çekmek ve tekrar tura geri dönmek için geçerli turdan daha büyük olmayan pozitif bir tam sayıx
      • Geçersiz tamsayılar olarak kabul edilir 0.
    • bu turdan korumak istediğiniz hafızanızı içeren bir dize. Bellek depolamanın zorluğun önemli bir parçası olmadığını unutmayın . Dizede yararlı herhangi bir veri saklamadan iyi girişler yapabilirsiniz. İlk turda dize boş bir dize olacaktır.

  • Metodunuz bir maçta ortalama tur başına 10 ms'den fazla zaman almamalıdır.

  • Zaman sınırının düzenli olarak başarısız olması diskalifiye ile sonuçlanır.

puanlama

  • Maçı kazanmak 2 puan, beraberlik her iki oyuncu için 1 puan kazanır. Kayıp puan kazanmaz.
  • Bir botun puanı topladığı toplam puan sayısı olacaktır.
  • Her bir yarışmacı çifti arasında oynanan maç sayısı, giriş sayısına ve hızlarına bağlı olacaktır.

İki basit örnek bot yanıt olarak gönderilir.

Denetleyici ve ilk çift Bot burada bulunabilir .

Botların 3 Kasım'a kadar gönderildiği test sonuçları:

Toplam Puanlar:

Oldschool: 3163
Random: 5871
RegretBot: 5269
Nostalgia: 8601
Little Ten: 8772
Analyzer: 17746
NoRegretsBot: 5833
Oracle: 15539
Deja Vu: 5491
Bad Loser: 13715

(Denetleyici, Cat avcısı meydan okumasının denetleyicisine dayanır . @Flawr için bunun için bir temel oluşturduğu için teşekkürler.)

Bonus: Benzer bir konsepte dayanan güzel bir 6 dakikalık film .


1
Bu kuralın ne anlama geldiğini anlamıyorum. If you pull a blue lever (revert stopper) no TT is possible through that round anymore. TT's attempting to go through the round will have no effect."Bir raunttan geçmek" nedir?
feersum

@feersum Doğru anlarsam, mavi kolu çekerek mevcut turu (ve böylece önceki tüm turları) kalıcı olarak "kilitler", böylece sonuçlar zaman yolculuğu ile değiştirilemez. Herhangi biri mavi kolu çektiğinizden daha erken bir zamana TT'ye girmeye çalışırsa, yapamazlar.
PhiNotPi

@feersum @PhiNotPi doğru, bu sürüm daha net mi? If you pull a blue lever (revert stopper) no TT is possible to the round the lever was used or any earlier round anymore. TT's attempting to go to these rounds will have no effect.
randomra

Kırmızı kolu çektiğinizde, o tur için bozuk parayı yeniden yapmak için şu anda bulunduğunuz turu seçebilir misiniz?
TheNumberOne

@TheNumberOne Evet, Rastgele örnek botunun yaptığı budur.
randomra

Yanıtlar:


12

analizör

Bu, geleceğe yönelik en iyi tahminleri yapmak için geçmişi analiz eder.

EDIT: Mavi kaldıraç sürelerini önler. Mavi kolları etkili bir şekilde kullanır. Kırmızı kolları daha etkin kullanır. Cadılar Bayramı sezonu için kibir eklendi.

EDIT: 1 hata ile giderildi.

EDIT: Geliştirilmiş computeWinningProbabilityişlev. Şimdi kırmızı ve mavi kolları daha agresif bir şekilde kullanıyor.

//Boo!
package bots;

import main.Action;
import main.Game;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Created 10/24/15
 *
 * @author TheNumberOne
 */
public class Analyzer implements Bot{

    @Override
    public String getName(){
        return "Analyzer";
    }

    @Override
    public Action takeTurn(int blue_levers, int red_levers, String history,
                           String memory, int roundNumber) {
        /*System.out.println(Game.totalScore(history) + " : " + history);
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
        }*/
        int roundsLeft = 100 - roundNumber;
        int myScore = (Game.totalScore(history) + roundNumber) / 2; //My number of wins.
        int enemyScore = roundNumber - myScore;                     //Enemy's number of wins.
        Map<Integer, Double> bestRounds = new HashMap<>();
        int timeLimit = 0;

        Scanner scanner = new Scanner(memory);
        if (scanner.hasNext()){     //No memory, first turn.
            boolean triedTimeTravel = scanner.nextBoolean();
            if (triedTimeTravel){
                int time = scanner.nextInt();
                if (roundNumber > time) {     //Failed.
                    timeLimit = time;
                }
            }
            timeLimit = Math.max(timeLimit, scanner.nextInt());
            int size = scanner.nextInt();
            for (int i = 0; i < size; i++) {
                bestRounds.put(scanner.nextInt(), scanner.nextDouble());
            }
        } else {
            bestRounds.put(1, 0.5);
        }

        clean(bestRounds, roundNumber, timeLimit);
        double winningProb = computeWinningProbability(myScore, enemyScore, roundsLeft);
        String newMemory = computeMemory(bestRounds, roundNumber, winningProb);

        if (winningProb >= new double[]{1.5, .75, .7, .65, .6, .55}[blue_levers]){ //Ensure success ... slowly.
            return getAction(-1, newMemory, timeLimit, roundNumber);
        }

        int bestRound = bestRound(bestRounds);
        double bestRoundProb = bestRounds.get(bestRound);

        if ((winningProb <= bestRoundProb - .05 || winningProb < .5 && bestRoundProb > winningProb) && red_levers > 0){
            return getAction(bestRound, newMemory, timeLimit, roundNumber);  //Let's find the best past.
        } else {
            return getAction(0, newMemory, timeLimit, roundNumber); //Let's wait it out :)
        }
    }

    //Should be combined with computeMemory.
    private static Action getAction(int actionNum, String newMemory, int timeLimit, int roundNumber){
        if (actionNum == -1){
            timeLimit = Math.max(timeLimit, roundNumber);
            newMemory = "false " + timeLimit + " " + newMemory;
            return new Action(actionNum, newMemory);
        }
        if (actionNum == 0){
            return new Action(actionNum, "false " + timeLimit + " " + newMemory);
        }
        if (actionNum > 0){
            return new Action(actionNum, "true " + actionNum + " " + timeLimit + " " + newMemory);
        }
        return null;
    }

    private static int bestRound(Map<Integer, Double> bestRounds) {
        int best = 0;           //If no previous rounds ... just go forward a round.
        double bestScore = -1;
        for (Map.Entry<Integer, Double> entry : bestRounds.entrySet()){
            if (entry.getValue() > bestScore){
                best = entry.getKey();
                bestScore = entry.getValue();
            }
        }
        return best;
    }

    private static String computeMemory(Map<Integer, Double> map, int roundNumber, double winningProb) {
        StringBuilder builder = new StringBuilder();
        builder.append(map.size() + 1).append(" ");
        for (Map.Entry<Integer, Double> entry : map.entrySet()){
            builder.append(entry.getKey()).append(" ").append(entry.getValue()).append(" ");
        }
        builder.append(roundNumber + 1).append(" ").append(winningProb);
        return builder.toString();
    }

    private static void clean(Map<Integer, Double> data, int round, int timeLimit) {
        data
                .entrySet()
                .stream()
                .filter(entry -> entry.getKey() > round || entry.getKey() <= timeLimit)
                .map(Map.Entry::getKey)
                .collect(Collectors.toList()).forEach(data::remove);
    }

    private static double computeWinningProbability(int myScore, int enemyScore, int roundsLeft){ //Too complex for IntelliJ
        int height = myScore - enemyScore;
        double total = 0.0;
        for (int i = Math.max(height - roundsLeft, 2); i <= height + roundsLeft; i += 2){
            total += prob(roundsLeft, height, i);
        }
        total += prob(roundsLeft, height, 0) / 2;
        return total;
    }

    private static double prob(int roundsLeft, int height, int i){
        double prob = 1;
        int up = i - height + (roundsLeft - Math.abs(i - height))/2;
        int down = roundsLeft - up;
        int r = roundsLeft;
        int p = roundsLeft;
        while (up > 1 || down > 1 || r > 1 || p > 0){  //Weird algorithm to avoid loss of precision.
            //Computes roundsLeft!/(2**roundsLeft*up!*down!)

            if ((prob >= 1.0 || r <= 1) && (up > 1 || down > 1 || p > 1)){
                if (p > 0){
                    p--;
                    prob /= 2;
                    continue;
                } else if (up > 1){
                    prob /= up--;
                    continue;
                } else if (down > 1){
                    prob /= down--;
                    continue;
                } else {
                    break;
                }
            }
            if (r > 1) {
                prob *= r--;
                continue;
            }
            break;
        }
        return prob;
    }

}

Puan (2 Kasım'dan bu yana):

Total Scores:
Oldschool: 3096
Random: 5756
RegretBot: 5362
Nostalgia: 8843
Little Ten: 8929
Analyzer: 17764
NoRegretsBot: 5621
Oracle: 15528
Deja Vu: 5281
Bad Loser: 13820

1
Etkileyici! Botunuz etkili bir şekilde engeller ve en uygun zamanda geri döner. Bunun üstesinden gelebilecek bir bot oluşturmak çok zor olacak.
TNT

Bu botla uğraşmak ve başka bir botu artırmak için özel olarak tasarlanmış bir sürü giriş kullanmadan bu botun durduğundan emin değilim.
Mego

4

Nostalji

package bots;

import main.Action;
import main.Game;

public class Nostalgia implements Bot {

    @Override
    public String getName() {
        return "Nostalgia";
    }

    @Override
    public Action takeTurn(int blue_levers, int red_levers, String history,
            String memory, int roundNumber) {

        int current_score = Game.totalScore(history);

        // wait until the end to use blue levers
        if (current_score > 0 && blue_levers >= (100 - roundNumber)) {
            return new Action(-1, memory);
        }

        // become increasingly likely to go back as the gap between the good old days
        // and the horrible present increases
        if (current_score < 0 && red_levers > 0) {
            //identify the best time to travel back to
            int best_score = -100;
            int good_old_days = 1;
            int past_score = 0;

            int unreachable_past = 0;
            if(memory != "") {
              unreachable_past = Integer.parseInt(memory, 10);
            }

            for(int i = unreachable_past; i<roundNumber ; i++) {
              if(history.charAt(i) == '1') {
                past_score += 1;
                if(past_score > best_score) {
                  best_score = past_score;
                  good_old_days = i + 1;
                }
              }
              else {
                past_score -= 1;
              }
            }
            if(roundNumber >= 95 || Math.random() < (best_score - current_score) / 100.0) {
              return new Action(good_old_days, Integer.toString(good_old_days));
            }
        }

        // if neither action was needed do nothing
        return new Action(0, memory);
    }
}

Test edilmedi, sadece engellenmesi zor bir bot yapmaya çalışırken hızlı bir bıçak (çünkü kırmızı kolu çoğunlukla rastgele çekeceğine karar verir), ancak bu iyi kararlar verir.

Düzenleme: Bu kuralı kaçırdım:

Mavi kolu çekerseniz (geri durdurucu) artık bu turda TT mümkün değildir

Bu, bellek kullanmak için iyi bir neden gibi görünüyor - belirli bir tura TT'yi denemeyi hatırlıyorsanız, başarısız olabilirsiniz, bu yüzden TT'yi o tura tekrar denememelisiniz. Bundan kaçınmak için botumu düzenledi.


4

torpil

Utanmazca Analyzer bazı kod kopyaladım (belleği ayrıştırmak için). Bu teslim, mavi kolu erken çekmeye çalışır ve sonra yavaşça liderliğini oluşturur. Bence bu bot performansı çirkin kodu oluşturuyor :)

package bots;

import java.util.*;
import java.util.Map.Entry;
import main.*;

public class Oracle implements Bot {

    @Override
    public String getName() {
        return "Oracle";
    }

    @Override
    public Action takeTurn(int blue_levers, int red_levers, String history, String memory, int roundNumber) {
        int roundsLeft = 100 - roundNumber;
        Map<Integer, Integer> rounds = new HashMap<>();
        int myScore = (Game.totalScore(history) + roundNumber) / 2;
        int difference = myScore*2 - roundNumber;
        int highestBlockedRound = -1;
        int bestScore = 0;
        boolean hasUsedBlueLever = false;

        Scanner scanner = new Scanner(memory);
        if (scanner.hasNext()) {
            //timeTravel toRound highestBlockedRound hasUsedBlueLever bestScore rounds round1 percent1 round2 percent2 round3 percent3...
            boolean triedTravel = scanner.nextBoolean();
            int time = scanner.nextInt();
            if (triedTravel){
                if (roundNumber > time) {
                    highestBlockedRound = time;
                }
            }
            highestBlockedRound = Math.max(highestBlockedRound, scanner.nextInt());

            hasUsedBlueLever = scanner.nextBoolean();
            bestScore = scanner.nextInt();

            int size = scanner.nextInt();
            for (int i = 0; i < size && i < roundNumber; i++) {
                int number = scanner.nextInt();
                int diff = scanner.nextInt();
                if (number < roundNumber) {
                    rounds.put(number, diff);
                }
            }
        }
        rounds.put(roundNumber, difference);
        final int blockedRound = highestBlockedRound;

        int roundToRevert = 0;
        if (rounds.size() > 2) {
            Optional<Entry<Integer, Integer>> bestRound = rounds.entrySet()
                    .stream()
                    .filter(x -> x.getKey() >= blockedRound && x.getKey() <= roundNumber)
                    .sorted(Comparator
                        .comparingInt((Entry<Integer, Integer> x) -> x.getValue()*-1)
                        .thenComparingInt(x -> x.getKey()))
                    .findFirst();
            if (bestRound.isPresent()) {
                roundToRevert = bestRound.get().getKey();
            }
        }

        if (roundsLeft + Game.totalScore(history) <= 0 && red_levers > 0) {
            roundToRevert = highestBlockedRound+1;
        } else if (blue_levers > 0 && roundToRevert == roundNumber && ((hasUsedBlueLever && difference >= bestScore*1.5) || (!hasUsedBlueLever && difference > 1))) {
            roundToRevert = -1;
            hasUsedBlueLever = true;
            bestScore = difference;
            highestBlockedRound = roundNumber;
        } else if (red_levers > 0 && roundToRevert > 0 && rounds.get(roundToRevert) > difference+2) {
            roundToRevert += 1;
        } else {
            roundToRevert = 0;
        }

        StringBuilder sb = new StringBuilder();
        sb.append(roundToRevert > 0).append(' ');
        sb.append(roundToRevert).append(' ');
        sb.append(highestBlockedRound).append(' ');
        sb.append(hasUsedBlueLever).append(' ');
        sb.append(bestScore).append(' ');
        sb.append(rounds.size()).append(' ');
        rounds.entrySet().stream().forEach((entry) -> {
            sb.append(entry.getKey()).append(' ').append(entry.getValue()).append(' ');
        });
        String mem = sb.toString().trim();
        scanner.close();
        return new Action(roundToRevert, mem);
    }
}

Aferin! Kırmızı kollarımla yeterince agresif olmadığımı biliyordum. Şimdi Analizörü geliştirmek için. ;)
TheNumberOne

3

RegretBot

Sonunda hayatımızın maç, bizim geçmişteki hataları pişman ve geri dönüp bunları düzeltmek için çalışırlar.

package bots;

import main.Action;
import main.Game;

public final class RegretBot implements Bot {

    @Override
    public String getName() {
        return "RegretBot";
    }

    @Override
    public Action takeTurn(int blue_levers, int red_levers, String history, String memory, int roundNumber) {
        int actionNum = 0;
        if(roundNumber == 100) {
            // if it's the end of the game and we're losing, go back
            //  in time to the first loss, in hopes of doing better
            if(Game.totalScore(history)<=0 && red_levers > 0) {
                actionNum = history.indexOf("0")+1;
            }
            // if we're winning at the end, pull a blue lever if we can,
            //  to prevent our opponent from undoing our victory
            else if(blue_levers > 0) {
                actionNum = -1;
            }
        }
        // we don't need no stinkin' memory!
        return new Action(actionNum, null);
    }

}

2

Küçük On

Küçük Ten, 10'un katları olan sayıları kullanarak ve 10'un katları olan turlara geri dönerek, 10 ile çarpma ve bölme işlemlerini çok yapar.

package bots;

import main.Action;
import main.Game;

public class LittleTen implements Bot {

    @Override
    public String getName() {
        return "Little Ten";
    }

    @Override
    public Action takeTurn(int blue_levers, int red_levers, String history, String memory, int roundNumber) {
        int score = Game.totalScore(history);
        char c = history.charAt(history.length() - 1);
        if (memory.isEmpty())
            memory = "1";

        if (roundNumber == 100) {
            if (score >= 0)
                // We're tied or ahead by the end of the match. Prevent time
                // travel if we can; otherwise whatever happens happens.
                return new Action(blue_levers > 0 ? -1 : 0, memory);
            else {
                // Travel to earlier rounds the farther behind we are if we can
                // (of course using 10 as a reference)
                if (red_levers > 0) {
                    int i = Integer.parseInt(memory);
                    int round = score <= -10 ? i : 100 - ((100 - i) / (11 + (score <= -10 ? -10 : score)));
                    return new Action(round, memory);
                }
            }
        }
        else if (score >= 7 + roundNumber / 20 && blue_levers > 0) {
            // We're ahead; we don't want to lose our lead, especially if the
            // match is close to ending. But we don't want to use up our blue
            // levers too quickly.
            int choice = (int) (Math.random() * 100),
                bound = (roundNumber / 10 + 1) * 5 - ((6 - blue_levers) * 5 - 2);
            if (choice < bound) {
                memory = String.valueOf(roundNumber);
                return new Action(-1, memory);
            }
        }
        else if (score <= -3) {
            // Possibly use a red lever if we're falling too far behind
            if (red_levers > 0) {
                int choice = (int) (Math.random() * 100),
                    bound = score <= -11 ? 90 : 10 * (-3 - score + 1);
                if (choice < bound) {
                    // Check the first round that is the lower multiple of ten
                    // and decide if we've been successful up to that point; if
                    // so, travel back to that round, otherwise go back 10 more
                    int round = roundNumber / 10 * 10;
                    if (round < 10)
                        return new Action(1, memory);
                    String seq = history.substring(0, round-1);
                    int minRound = Integer.parseInt(memory);
                    while (Game.totalScore(seq) <= 0 && round > 10 && round > minRound) {
                        round -= 10;
                        seq = history.substring(0, round-1);
                    }
                    if (round == 0)
                        round = 1;
                    return new Action(round, memory);
                }
            }
        }
        return new Action(0, memory);
    }
}

Düzenleme: Mavi bir kol çekildiğinde ne olacağının açıklaması daha net olduğu için mekanik biraz değişti. Ayrıca biraz yeniden dengeleme yaptı.


1

rasgele

Random'ın stratejisi şudur:

  • blokönde 10% şans ile ve mavi kolları kaldı
  • Skorda ve kırmızı kol kaldıysa% 10 şansla bir tur geri gitme (son turu tekrarlama)
package bots;

import main.Action;
import main.Game;

public class RandomBot implements Bot {

    @Override
    public String getName() {
        return "Random";
    }

    @Override
    public Action takeTurn(int blue_levers, int red_levers, String history,
            String memory, int roundNumber) {

        // if in the lead and has blocks left, blocks with a 10% chance
        if (Game.totalScore(history) > 0 && blue_levers > 0
                && Math.random() > 0.9) {
            return new Action(-1, null);
        }

        // if behind and has travels left, travel back the current step to
        // replay it with a 10% chance
        if (Game.totalScore(history) < 0 && red_levers > 0
                && Math.random() > 0.9) {
            return new Action(roundNumber, null);
        }

        // if neither action were needed do nothing
        return new Action(0, null);
    }
}

1

NoRegretsBot

package bots;

import main.Action;
import main.Game;

public final class NoRegretsBot implements Bot {

    @Override
    public String getName() {
        return "NoRegretsBot";
    }

    @Override
    public Action takeTurn(int blue_levers, int red_levers, String history, String memory, int roundNumber) {
        // every 20 turns, pull a blue lever to lock in the past
        // hopefully this will thwart some of those pesky time-travelers
        return new Action(roundNumber%20==0?-1:0, null);
    }

}

1

Kötü Kaybeden

Bu bot bellek kullanmıyor ve şaşırtıcı derecede iyi (ancak Analyzer veya Oracle'ı geçmiyor).

package main;

import bots.Bot;

/**
 * Created 11/2/15
 *
 * @author TheNumberOne
 */
public class BadLoser implements Bot{
    @Override
    public String getName() {
        return "Bad Loser";
    }

    @Override
    public Action takeTurn(int blue_levers, int red_levers, String history, String memory, int roundNumber) {
        if (history.contains("00") && red_levers > 0){       //Subtract a zero for better performance against
            return new Action(history.indexOf("00") + 1, "");// Analyzer and Nostalgia, and worse performance 
                                                             // against everything else.
        }
        int wins = 0;
        for (char c : history.toCharArray()){
            wins += c - '0';
        }
        if (wins >= new int[]{101, 51, 40, 30, 20, 10}[blue_levers]){
            return new Action(-1, "");
        }
        return new Action(0, "");
    }
}

0

Eski okul

Oldschool zaman yolculuğuna inanmadığı için bu bot hiçbir zaman hiçbir şey yapmaz.

package bots;

import main.Action;

public class OldschoolBot implements Bot {

    @Override
    public String getName() {
        return "Oldschool";
    }

    @Override
    public Action takeTurn(int blue_levers, int red_levers, String history,
            String memory, int roundNumber) {       
        // never tries to block or travel at all
        return new Action(0, null);
    }
}

0

Deja Vu Bot

Bu bot, o bölgeye kırmızı çekilmekten kaçınmak için maviyi çektiğinde izlemeye çalışır. Kırmızı kolları sadece skorun çok gerisinde olduğunda çeker.

package bots;

import main.*;

public class Dejavu implements Bot
{
    @Override
    public String getName()
    {
        return "Deja Vu";
    }

@Override
public Action takeTurn(int blue_levers, int red_levers, String history,
                       String memory, int roundNumber) {

    if(roundNumber == 1)
    {
        memory = "-1";
    }
    int[] blevers = getBlueLevers(memory);
    char[] hist = history.toCharArray();
    int ms = 0;
    int ts = 0;
    int rl = -1;
    boolean bl = false;
    boolean url = false;

    for(int i = 0; i < hist.length; i++)
    {
        switch(hist[i])
        {
            case '1':
            ms++;
            break;
            case '0':
            ts++;
            break;
        }
    }

    if(ts - ms >= 10)
    {   
        for(rl = hist.length - 1; ts - ms <= 5 && rl >= 0; rl--)
        {
            switch(hist[rl])
            {
                case '1':
                ms--;
                break;
                case '0':
                ts--;
                break;
            }
        }
        url = true;
    }

    if(ms - ts >= 7)
    {
        bl = true;
        url = false;
        memory += "," + roundNumber;
    }

    for(int i = 0; i < blevers.length; i++)
    {
        if(rl <= blevers[i])
        {
            rl = blevers[i] + 1;
        }
    }

    if(url)
    {
        return new Action(rl, memory);
    }
    else if(bl)
    {
        return new Action(-1, memory);
    }
    else
    {
        return new Action(0, memory);
    }              
}

private int[] getBlueLevers(String s)
{
    String[] b = s.split(",");

    int[] bl = new int[b.length];
    for(int i = 0; i < b.length; i++)
    {
        bl[i] = Integer.parseInt(b[i]);
    }

    return bl;
}

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