Coin Time Pelancong Waktu

19

Di masa depan ketika Time Travel (disingkat TT) akan menjadi hal yang umum, melempar koin akan menjadi olahraga pikiran yang serius. Untuk mempersiapkan masa depan, kami membuat kompetisi untuk program-program di mana perjalanan waktu akan benar-benar terjadi dari sudut pandang entri.

Kompetisi adalah gaya round-robin King of the Hill yang terdiri dari pertandingan lempar koin antara kelas-kelas Jawa.

Aturan pertandingan melempar koin

  • Ada dua pemain dan 100 putaran.
  • Di setiap putaran, koin dilemparkan dan berdasarkan hasil, salah satu pemain mendapat 1 poin. Setiap pemain memiliki peluang 50% untuk mencetak poin.
  • Setelah lemparan kedua pemain memiliki kesempatan untuk mengontrol waktu dengan menarik tuas.
  • Jika Anda menarik tuas biru (kembalikan stopper) tidak ada TT yang mungkin untuk putaran tuas digunakan atau putaran sebelumnya lagi. Upaya TT untuk pergi ke putaran ini tidak akan berpengaruh.
  • Jika Anda menarik tuas merah (reverter) Anda mencoba mengembalikan waktu kembali ke babak sebelumnya. Jika berhasil , memori lawan akan dikembalikan ke memorinya sebelum putaran yang dipilih dan hasil lemparan koin mulai dari putaran yang dipilih juga akan dihapus . Satu-satunya tanda yang mungkin untuk lawan Anda tentang TT adalah jumlah tuas yang tidak digunakan yang tidak akan dikembalikan kembali.
  • Setiap pemain memiliki 5 tuas biru dan 20 tuas merah yang tidak digunakan pada awal pertandingan. Tuas ini tidak terpengaruh oleh TT.
  • Jika tidak ada TT yang terjadi pada akhir ronde ke-100 permainan berakhir dan pemain dengan skor yang lebih tinggi menang.

Detail

  • Babak memiliki pengindeksan berbasis 1 (bentuk 1 hingga 100).
  • Sebelum putaran xAnda diberikan jumlah tuas biru dan merah yang tersedia, koin melemparkan hasil sampai gilirannya x(inklusif) dan memori x-1putaran terakhir (terakhir) Anda .
  • Menarik tuas biru di putaran xmenghentikan setiap TT yang memiliki tujuan di putaran xatau sebelumnya (itu memblokir TT jika itu terjadi pada putaran yang sama persis juga).
  • Mengembalikan ke putaran xberarti bahwa putaran berikutnya akan bulat x.
  • Jika kedua pemain memilih untuk kembali di akhir putaran waktu dikembalikan ke tujuan sebelumnya yang tidak diblokir. Pemain yang mencoba untuk kembali ke waktu ini akan menyimpan ingatan mereka.

Rincian teknis

  • Anda harus menulis kelas Java yang mengimplementasikan antarmuka Bot yang disediakan.
  • Tambahkan bot Anda ke proyek.
  • Tambahkan instance Bot Anda ke Botdalam file Controller.java.
  • Kelas Anda tidak boleh menyimpan informasi di antara panggilan . (Dalam kebanyakan kasus hanya memiliki finalvariabel di luar fungsi memenuhi persyaratan ini.)
  • Anda dapat memberikan informasi kepada pengontrol di memorybidang Actionobjek yang dikembalikan . Ini akan diberikan kembali kepada Anda di giliran berikutnya jika tidak ada TT terjadi. Jika TT terjadi, Anda akan menerima memori Anda sebelumnya yang sesuai.
  • Anda bisa menggunakan totalScore()metode Gamekelas untuk mendapatkan skor string sejarah.

Protokol

  • Pada setiap kesempatan, takeTurn(...)metode Anda dipanggil dengan 5 argumen:

    • jumlah tuas biru yang tidak digunakan
    • jumlah tuas merah yang tidak digunakan
    • koin melempar sejarah, string yang terdiri dari 1 dan 0 menandai kemenangan dan kerugian Anda di babak sebelumnya. Karakter pertama sesuai dengan lemparan koin pertama. (Di babak pertama panjang tali akan 1.)
    • sebuah string, memori Anda yang tersimpan dari babak sebelumnya
    • indeks berbasis 1 dari babak ini
  • Di setiap belokan, metode Anda mengembalikan Actionobjek yang berisi

    • bilangan bulat di movebidang yang menggambarkan tindakan Anda:

      • 0 tanpa tindakan
      • -1 untuk menarik tuas biru dan memblokir TT melalui putaran ini
      • bilangan bulat positif x, tidak lebih besar dari putaran saat ini, untuk menarik tuas merah dan mencoba untuk kembali ke putaranx
      • Bilangan bulat tidak valid dianggap sebagai 0.
    • string yang berisi ingatan Anda dari babak ini yang ingin Anda pertahankan. Perhatikan bahwa menyimpan memori bukan bagian penting dari tantangan . Anda dapat membuat entri yang bagus tanpa menyimpan data yang berguna dalam string. Pada putaran pertama string akan menjadi string kosong.

  • Metode Anda harus rata-rata tidak lebih dari 10 ms per putaran dalam suatu pertandingan.

  • Kegagalan batas waktu secara teratur menyebabkan diskualifikasi.

Mencetak gol

  • Memenangkan pertandingan menghasilkan 2 poin dan hasil seri menghasilkan 1 poin untuk kedua pemain. Kerugian tidak menghasilkan poin.
  • Skor bot adalah jumlah total poin yang dikumpulkannya.
  • Jumlah pertandingan yang dimainkan antara setiap pasangan kontestan akan tergantung pada jumlah entri dan kecepatan mereka.

Dua contoh bot sederhana diposting sebagai jawaban.

Kontroler dan Bot pasangan pertama tersedia di sini .

Hasil tes dengan bot diajukan hingga 3 November .:

Skor Total:

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

(Pengontrol didasarkan pada pengontrol tantangan penangkap Cat . Terima kasih atas @ flawr yang menjadikannya sebagai basis untuk yang ini.)

Bonus: film 6 menit yang bagus berdasarkan konsep serupa.

randomra
sumber
1
Saya tidak mengerti apa arti aturan ini. 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.Apa yang "melalui putaran"?
feersum
@feersum Jika saya mengerti benar, menarik tuas biru secara permanen "mengunci" putaran saat ini (dan dengan demikian semua putaran sebelumnya) sehingga hasilnya tidak dapat dimodifikasi oleh perjalanan waktu. Jika ada yang mencoba untuk TT ke waktu lebih awal daripada ketika Anda menarik tuas biru, mereka tidak akan bisa.
PhiNotPi
@feersum @PhiNotPi benar, apakah versi ini lebih jelas? 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
Saat Anda menarik tuas merah, dapatkah Anda memilih ronde yang sama dengan yang Anda gunakan sekarang untuk mengulang lemparan koin untuk ronde itu?
TheNumberOne
@TheNumberOne Ya, itulah yang bot contoh Acak tidak.
randomra

Jawaban:

12

Penganalisa

Ini menganalisis masa lalu untuk membuat prediksi terbaik untuk masa depan.

SUNTING: Menghindari waktu tuas biru. Menggunakan tuas biru secara efektif. Menggunakan tuas merah lebih efektif. Menambah kelangkaan untuk musim Halloween.

EDIT: Diatasi oleh 1 kesalahan.

EDIT: Peningkatan computeWinningProbabilityfungsi. Sekarang gunakan tuas merah dan tuas biru lebih agresif.

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

}

Skor (sejak 2 November):

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
TheNumberOne
sumber
1
Impresif! Bot Anda memblokir secara efektif dan kembali pada waktu yang optimal. Akan sangat sulit untuk membuat bot yang bisa menjadi yang teratas ini.
TNT
Saya tidak yakin bot ini bisa dihentikan, tanpa menggunakan banyak entri yang dirancang khusus untuk mengacaukan bot ini dan meningkatkan bot lain.
Mego
4

Nostalgia

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

Tidak diuji, hanya tikaman cepat dalam mencoba membuat bot yang sulit untuk diblokir (karena memutuskan kapan harus menarik tuas merah kebanyakan secara acak) tetapi itu membuat keputusan yang layak.

Sunting: Saya melewatkan aturan ini:

Jika Anda menarik tuas biru (kembalikan stopper), TT tidak mungkin lagi melalui putaran itu

Itu sepertinya alasan yang baik untuk menggunakan memori - jika Anda ingat mencoba TT ke putaran tertentu, Anda mungkin gagal, jadi Anda tidak harus mencoba TT ke putaran itu lagi. Mengedit bot saya untuk mencoba menghindari ini.

histokrat
sumber
4

Peramal

Saya tanpa malu-malu menyalin beberapa kode dari Analyzer (untuk mengurai memori). Kiriman ini mencoba menarik tuas biru lebih awal dan kemudian perlahan-lahan membangun keunggulannya. Saya pikir kinerja bot ini menebus kode jelek :)

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);
    }
}
CommonGuy
sumber
Kerja bagus! Saya tahu saya tidak cukup agresif dengan tuas merah saya. Sekarang untuk meningkatkan Analyzer. ;)
TheNumberOne
3

RegretBot

Pada akhir hidup kita pertandingan, kami menyesal kegagalan masa lalu kita, dan berusaha untuk kembali dan memperbaikinya.

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

}
Mego
sumber
2

Sepuluh kecil

Little Ten melakukan banyak perkalian dan pembagian dengan 10, menggunakan angka yang merupakan kelipatan dari 10, dan kembali ke putaran yang merupakan kelipatan dari 10.

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

Sunting: Mengubah mekanika sedikit sekarang sehingga penjelasan tentang apa yang terjadi ketika tuas biru ditarik lebih jelas. Juga melakukan sedikit penyeimbangan kembali.

TNT
sumber
1

Acak

Strategi Random adalah sebagai berikut:

  • memblokir dengan peluang 10% jika dalam memimpin dan memiliki tuas biru yang tersisa
  • melakukan perjalanan satu putaran (mengulang babak terakhir) dengan peluang 10% jika tertinggal dalam skor dan memiliki tuas merah tersisa
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);
    }
}
randomra
sumber
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);
    }

}
Mego
sumber
1

Pecundang Buruk

Bot ini tidak menggunakan memori dan ternyata bagus (tetapi tidak mengalahkan Analyzer atau Oracle).

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, "");
    }
}
TheNumberOne
sumber
0

Oldschool

Bot ini tidak pernah melakukan tindakan apa pun karena Oldschool tidak percaya pada waktu bepergian.

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);
    }
}
randomra
sumber
0

Deja Vu Bot

Bot ini mencoba melacak ketika menarik biru untuk menghindari tarikan merah ke wilayah itu. Hanya akan menarik pengungkit merah ketika secara signifikan tertinggal dalam skor.

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

}
Cakar
sumber