コイン投げ時間旅行者


19

将来的にはタイムトラベル(TT)が一般的になりますが、コイン投げは深刻な精神スポーツになります。将来に備えて、エントリーの観点から実際に時間旅行が行われるプログラムのコンテストを作成します。

競争は、Javaクラス間のコイン投げ試合で構成されるラウンドロビンスタイルのキングオブザヒルです。

コイン投げのルール

  • 2人のプレイヤーと100ラウンドがあります。
  • ラウンドごとにコインが投げられ、その結果に基づいてプレイヤーの1人が1ポイントを獲得します。各プレイヤーは50%の確率でポイントを獲得できます。
  • 投げた後、両方のプレイヤーはレバーを引いて時間を制御する機会があります。
  • 青色のレバー(ストッパーを元に戻す)を引くと、レバーが使用されたラウンドまたはそれ以前のラウンドではTTを使用できません。TTがこれらのラウンドに行こうとしても効果はありません。
  • 赤いレバー(リバーター)を引くと、時間を元のラウンドに戻そうとします。成功した場合、対戦相手の記憶は、選択されたラウンドの前に記憶に戻され、選択されたラウンドから始まるコイントスの結果も削除されます。TTに関して対戦相手に可能な唯一の兆候は、元に戻されない未使用のレバーの数です。
  • 各プレイヤーには、試合開始時に5個の青と20個の赤の未使用レバーがあります。これらのレバーはTTの影響を受けません。
  • 100ラウンドの終了時にTTが発生しない場合、ゲームは終了し、スコアの高いプレイヤーが勝ちます。

詳細

  • ラウンドには1から始まるインデックスがあります(フォーム1から100)。
  • ラウンドの前にx、利用可能な青と赤のレバーの数が提供され、コインが投げられるまでx(最後を含む)、最後のx-1ラウンドのメモリがトスされます。
  • ラウンドで青色のレバーを引くと、xラウンドx前またはラウンド前に目的地があるTTが停止します(同じ正確なラウンドでもTTがブロックされる)。
  • ラウンドに戻すxことは、次のラウンドがラウンドになることを意味しxます。
  • 両方のプレイヤーがラウンドの終わりに復帰することを選択した場合、時間はブロックされていない以前の目的地に戻ります。この時間に戻ろうとしたプレーヤーは記憶を保持します。

技術的な詳細

  • 提供されたBotインターフェイスを実装するJavaクラスを作成する必要があります。
  • ボットをプロジェクトに追加します。
  • Botファイルのにボットのインスタンスを追加しますController.java
  • クラスは、呼び出し間で情報を保持するべきではありません。(ほとんどの場合final、関数の外部に変数のみがあると、この要件が満たされます。)
  • memory返されたActionオブジェクトのフィールドでコントローラーに情報を提供できます。TTが発生しなかった場合、これは次のターンに返されます。TTが発生した場合、対応する以前のメモリを受け取ります。
  • クラスのtotalScore()メソッドを使用してGame、履歴文字列のスコアを取得できます。

プロトコル

  • 毎回、takeTurn(...)メソッドは5つの引数で呼び出されます。

    • 未使用の青いレバーの数
    • 未使用の赤いレバーの数
    • コイン投げの履歴、1と0で構成される文字列は、前のラウンドでの勝敗を示します。最初のキャラクターは、最初のコイン投げに対応しています。(最初のラウンドでは、文字列の長さはになります1。)
    • 文字列、前のラウンドで保存されたメモリ
    • このラウンドの1から始まるインデックス
  • 毎回、メソッドは以下Actionを含むオブジェクトを返します

    • moveアクションを説明するフィールドの整数:

      • 0 何もしない
      • -1 青いレバーを引いて、TTがこのラウンドを通過するのをブロックします
      • x赤いレバーを引いてラウンドに戻ろうとする現在のラウンドよりも大きくない正の整数x
      • 無効な整数はとして扱われ0ます。
    • 保存したいこのラウンドのメモリを含む文字列。メモリの保存は、チャレンジの重要な部分ではないことに注意してください。文字列に有用なデータを保存せずに、適切なエントリを作成できます。最初のラウンドでは、文字列は空の文字列になります。

  • あなたの方法は、試合の平均でラウンドごとに10ミリ秒以上かかることはありません。

  • 定期的に時間制限に違反すると、失格となります。

得点

  • 試合に勝つと2ポイントが得られ、引き分けは両方のプレイヤーに対して1ポイントを獲得します。損失は​​ポイントを獲得しません。
  • ボットのスコアは、収集したポイントの総数になります。
  • 競技者の各ペア間でプレイされる試合の数は、エントリーの数とスピードに依存します。

2つの簡単なボットの例が回答として投稿されています。

コントローラーと最初のカップルのボットはこちらから入手できます

11月3日までに送信されたボットのテスト結果:

合計スコア:

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

(コントローラーは、Cat catcherチャレンジのコントローラーに基づいています。@ flawrがこのコントローラーのベースとして提供してくれてありがとう。)

ボーナス:同様のコンセプトに基づいた6分間の素敵な映画


1
このルールの意味がわかりません。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.「ラウンドを通過する」とは何ですか?
feersum

@feersum正しく理解できれば、青色のレバーを引くと、現在のラウンド(したがって、以前のすべてのラウンド)が永続的に「ロック」され、タイムトラベルによって結果が変更されなくなります。誰かが青いレバーを引いたときよりも前の時間にTTを試みると、彼らはできなくなります。
PhiNotPi

@feersum @PhiNotPiは正しいですが、このバージョンはより明確ですか?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

赤いレバーを引いたときに、現在のラウンドと同じラウンドを選択して、そのラウンドのコイントスをやり直すことができますか?
-TheNumberOne

@TheNumberOneはい、これがRandomサンプルボットの動作です。
randomra

回答:


12

アナライザ

これは過去を分析し、将来の最良の予測を行います。

編集:青いレバー時間を回避します。青いレバーを効果的に使用します。赤いレバーをより効果的に使用します。ハロウィーンシーズンに怖さを追加しました。

編集: 1エラーで修正。

編集:computeWinningProbability機能を改善しました。現在、赤いレバーと青いレバーをより積極的に使用しています。

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

}

スコア(11月2日以降):

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
印象的!ボットは効果的にブロックし、最適なタイミングで元に戻ります。これに勝てるボットを作成するのは非常に困難です。
TNT

このボットを混乱させ、別のボットをブーストするために特別に設計された一連のエントリを使用せずに、このボットが停止可能かどうかはわかりません。
メゴ

4

懐かしさ

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

テストされていませんが、ブロックするのが難しいボットを作ろうとするだけで簡単に突き刺されます(赤いレバーをほとんどランダムに引くタイミングを決定するため)が、それはまともな決定を下します。

編集:私はこのルールを見逃しました:

青色のレバー(ストッパーを戻す)を引くと、そのラウンドでTTはできなくなります

それはメモリを使用する正当な理由のように思えます-与えられたラウンドにTTを試みることを覚えているなら、あなたは失敗したかもしれないので、そのラウンドにTTを再び試みるべきではありません。これを避けるためにボットを編集しました。


4

オラクル

Analyzerからいくつかのコードを恥知らずにコピーしました(メモリを解析するため)。このサブミッションは、青いレバーを早く引っ張ろうと試み、その後ゆっくりとリードを確立します。このボットのパフォーマンスはいコードを補うと思います:)

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

よくやった!私は自分の赤いレバーで十分に攻撃的ではないことを知っていました。アナライザーを改善します。;)
TheNumberOne

3

RegretBot

試合の最後に過去の失敗を後悔し、戻って修正しようとします。

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

リトルテン

リトルテンは、10の倍数である数値を使用して、10で多くの乗算と除算を行い、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);
    }
}

編集:青色のレバーを引いたときに何が起こるかの説明がより明確になったため、メカニズムを少し変更しました。また、少しバランスを取り直しました。


1

ランダム

ランダムの戦略は次のとおりです。

  • リードしている場合、10%の確率でブロックし、青いレバーが残っている
  • スコアが遅れ、赤いレバーが残っている場合は、10%のチャンスで1ターン(最後のラウンドをリプレイ)戻ります
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

悪い敗者

このボットはメモリを使用せず、驚くほど優れています(ただし、Analyzerや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, "");
    }
}

0

古い学校

オールドスクールは時間旅行を信じていないため、このボットはアクションを実行しません。

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

デジャヴボット

このボットは、その領域への赤の引き込みを避けるために、青を引き寄せるタイミングを追跡しようとします。スコアで大幅に遅れている場合にのみ、赤いレバーを引きます。

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

}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.