King of the Hill - Liar's Dice

22

Liar's Dice to dość prosta gra w kości. Widziałem kilka różnych odmian zasad, ale oto wersja, którą znam najbardziej:

  • Każdy gracz zaczyna od 5d6
  • Z wyjątkiem liczenia kości na końcu rundy każdy gracz może zobaczyć własne kości, ale nie kości dowolnego przeciwnika
  • Na początku każdej rundy wszyscy gracze rzucają dowolnymi kostkami
  • Następnie jeden gracz (zwykle jest to albo zwycięzca poprzedniej rundy LUB gracz po lewej stronie gracza, który zaczął ostatni raz; użyjemy tego pierwszego dla tego KotH; losowy gracz rozpocznie pierwszą rundę) zgaduje, ile konkretnej liczby jest na stole (ONES ARE WILD)
  • Licytacja jest kontynuowana w prawo, za każdym razem rosnąc (na przykład; 3 piątki, 3 szóstki i 4 dwójki są wyższe niż 3 czwórki, ale 3 trójki nie są; 4 są również wyższe, ale licytacja na nich prawdopodobnie spowoduje niekorzyść); dopóki jakikolwiek gracz nie wezwie gracza poprzedzającego go kłamcą
  • W tym momencie wszyscy gracze odkrywają swoje kości i liczą liczbę ostatniej liczby licytowanej na stole
  • Jeśli suma jest niższa niż stawka, gracz, który złożył ofertę, musi dać kostkę graczowi, który nazwał ich kłamcą, w przeciwnym razie gracz, który nazwał licytatora kłamcą, musi dać kostkę licytującemu (więc licytujący wygrywa jeśli ich liczba jest co najmniej tyle, ile licytował, nie musi być dokładnej liczby)
  • Kiedy skończą Ci się kości, przegrywasz
  • Ostatni stojący gracz wygrywa

Na przykład:

Gracz pierwszy ma 1,1,2,4,6
Gracz drugi ma 1,2,2,3,5
Gracz trzeci ma 1,3,3,4,6
Gracz pierwszy: trzy szóstki.
Gracz drugi: cztery dwójki.
Gracz trzeci: cztery trójki.
Gracz pierwszy: pięć dwójek.
Gracz drugi: sześć dwójek.
Gracz trzeci: sześć trójek.
Gracz pierwszy: sześć czwórek.
Gracz drugi: Kłamca!
Odsłaniają swoje kości i liczą te (ponieważ są dzikie) i czwórki.
Okazuje się, że w rzeczywistości jest dokładnie cztery czwórki.
Gracz drugi daje graczowi jedną kość.
Przewijają się ponownie, a gracz jeden rozpoczyna kolejną rundę.

Aby zagrać w tę grę, musisz napisać bota. Musi implementować następującą abstrakcyjną klasę Java:

public abstract class Player {
    public Player() {}
    public String toString() {
        return this.getClass().getSimpleName();
    }
    public abstract String bid(int yourId, int[] diceEachPlayerHas, int[] yourDice, String[] bids);
}
  • Musisz wdrożyć metodę licytacji
    • Pierwszy argument to aktualna pozycja twojego bota w kolejności tury, drugi to tablica pokazująca, ile kości ma obecnie każdy gracz (w tym ty), trzeci to tablica pokazująca wartości aktualnie pokazane na twoich kościach, a czwarty to tablica wszystkich ofert złożonych od początku bieżącej rundy - będzie miała długość 0, jeśli złożysz pierwszą ofertę rundy
    • Wynik powinien być ciągiem znaków „liczba twarzy” lub ciągiem „Kłamca!” nazwać poprzedniego oferenta kłamcą.
    • Jeśli Twoje dane wyjściowe są sformatowane nielegalnie, zostaniesz wyeliminowany.
  • Możesz zastąpić metodę toString, ale nie jest to wymagane. Nie można go jednak edytować w żaden sposób, który zakłóca czytelności danych wyjściowych kontrolera.
  • Możesz wywoływać dowolne inne publiczne metody kontrolera, ale nie jego główną metodę.
  • Możesz czytać i edytować tylko pliki w bieżącym katalogu poprzedzonym nazwą własnego bota
  • Nie możesz pobierać danych z żadnego innego źródła
  • Zmienne instancji są resetowane na początku każdej nowej gry, ale zmienne statyczne nie są.

Punktacja

  • Za każdym razem, gdy dodawany jest bot (po przesłaniu trzech lub więcej botów), będzie symulowany jeden zestaw 1000 gier z 3-5 graczami, punktowany zgodnie ze źródłem kontrolera (w dowolnej grze zdobądź 1 na początku każdej tury, 10 za każdym razem, gdy złapiesz kostkę, i 1000 bonusów, jeśli wygrasz); egzekwowanie limitu 5000 TURN (nie rund) w każdej grze.
  • Twój bot zostanie oceniony na podstawie wyniku z najnowszego zestawu gier; plus dziesięciokrotność wyniku głosowania, jeśli nieujemne. (Jest mało prawdopodobne, aby ten ostatni miał znaczący wpływ na wynik)

Źródło kontrolera można znaleźć tutaj.

Wyniki na dzień 19.06.2015:

Badnomial: 434,924 + 6x10 = 424,984
Nobody: 282,329 + 6x10 = 282,389
StraightShooter: 265,205 + 5x10 = 265,255
MostlyHonestAbe: 158,958 + 4x10 = 158,998
The Pirate: 157,005 + 1x10 = 157,015
Statistician: 144,012 + 2x10 = 144,032
Fidelio: 49,973 + 2x10 = 49,993
Absurd Bot: 6,831
DrHouse: 2,638 + 3x10 = 2,668
SuperJedi224
źródło
1
Powinieneś wyjaśnić, że wynikiem powinno być „2 3”, a nie „dwa trójki”, jak pokazuje twój przykład. Czy kontroler ma też możliwość obejrzenia pojedynczego meczu?
Cain
Nie w oficjalnej wersji, ale opublikuję alternatywną wersję, która pozwala ci to zrobić.
SuperJedi224,
@Geobits: Jeśli chcesz. Będzie to dla ciebie nieco niekorzystne, jeśli ktoś do ciebie zadzwoni.
SuperJedi224,
1
Zakładam, że indeksy tablic są „identyfikatorami” graczy, więc diceEachPlayerHas[yourId]= liczą się twoje kości i bids[yourId]jest to Twoja pierwsza oferta (lub zero, jeśli to twoja pierwsza tura). Czy to jest poprawne?
Nie to, że Charles
1
Widziałem gry, w których niektóre zgłoszenia grają w więcej gier niż inne (Nikt: 414 gier, Straight Shooter: 409 gier). To niesprawiedliwe, czy możesz to naprawić?
CommonGuy,

Odpowiedzi:

6

Nikt

Próbuje odgadnąć kości od innych graczy. Nazywa innych botów kłamcami, jeśli nie wie, co robić.

Edycja: Naprawiono problem polegający na tym, że nikt nie licytował wiecznie, nigdy nie wzywając Kłamcy.

public class Nobody extends Player{

    @Override
    public String bid(int myId, int[] diceEachPlayerHas, int[] myDice,
            String[] bids) {
        if (bids.length == 0)
            return "1 2";
        int wilds = 0;
        int players = Controller.numPlayers();
        double myKnowledge = (double)diceEachPlayerHas[myId]/Controller.diceInPlay();
        double previousKnowledge = (double)diceEachPlayerHas[(myId-1+players)%players] / Controller.diceInPlay();
        int[] dice = new int[5];
        for (int i = 0; i < myDice.length; i++) {
            if (myDice[i] == 1) {
                wilds++;
            } else {
                dice[myDice[i]-2]++;
            }
        }
        wilds = (int) (1/myKnowledge+wilds-1)+1;
        for (int i = 2; i <= 6; i++) {
            dice[i-2] += wilds;
        }
        String best = "0 0";
        for (int i = 2; i <= 6; i++) {
            if (Controller.isGreaterThan(dice[i-2] + " " + i, best)) {
                best = dice[i-2] + " " + i;
            }
        }
        if (Controller.isGreaterThan(best, bids[bids.length - 1])) {
            return best;
        }
        if (previousKnowledge > 0.4) {
            int prev = Integer.valueOf(bids[bids.length - 1].split(" ")[0]);
            int prevFace = Integer.valueOf(bids[bids.length - 1].split(" ")[1]);
            if (dice[prevFace - 2] +2 >= prev)
                return (prev+1) + " " + bids[bids.length - 1].split(" ")[1];
        }
        return "Liar!";
    }
}
CommonGuy
źródło
Wydaje się, że twój ostatni zestaw aktualizacji naprawdę pomógł.
SuperJedi224
6

Badnomial, bot, który podejmuje złe decyzje na podstawie rozkładów dwumianowych: Edycja: Naprawiono głupi błąd w obliczeniach prawdopodobieństwa, teraz uwzględnia następnego Licytującego, a także poprzedniego.

    public class Badnomial extends Player{
    public String toString() {return "Badnomial";}

  public String bid(int myId, int[] diceEachPlayerHas, int[] myDice, String[] bids) {
  int[] dieCounts = new int[7];
  for(int i:myDice)
   dieCounts[i]++;
  for(int i=2; i<7; i++)
   dieCounts[i] += dieCounts[1];

  if(bids.length > 0)
  {
   String[] lastBid = bids[bids.length - 1].split(" ");
   int bidCount = Integer.valueOf(lastBid[0]);
   int bidDie = Integer.valueOf(lastBid[1]);
   // Check if I hold a better bid
   boolean betterBid = false;
   int myBidDie;
   int myBidCount;
   int myHighestCount = 0;
   int myHighDie = bidDie +1;

   for(int i = 2; i < 7; i++) {
    if(dieCounts[i] >= myHighestCount) {
     myHighestCount = dieCounts[i];
     myHighDie = i;
    }
   } 
    if((myHighestCount > bidCount) || ((myHighestCount == bidCount) && (myHighDie > bidDie))) {
     betterBid = true;
     myBidDie = myHighDie;
     myBidCount = myHighestCount;
     }

   if(betterBid == false) {
    int unknownDice = Controller.diceInPlay() - myDice.length;
    int myDiceNeeded = bidCount - myHighestCount;
 if(myHighDie <= bidDie)
  myDiceNeeded++;
    int previousBidder = myId - 1;
    if(previousBidder < 0)
     previousBidder = Controller.numPlayers() -1;
    int bidderDiceNeeded = bidCount - dieCounts[bidDie] - (int)(diceEachPlayerHas[previousBidder]/3 +1);
    int bidderUnknown = Controller.diceInPlay() - diceEachPlayerHas[previousBidder] -myDice.length;
 int nextBidder = myId + 1;
 if(nextBidder == Controller.numPlayers())
  nextBidder = 0;
 int nbDiceNeeded = myDiceNeeded - (int)(diceEachPlayerHas[nextBidder]/3 +1);
    int nbUnknown = Controller.diceInPlay() - diceEachPlayerHas[nextBidder];
    //float myChances = (unknownDice/3 - myDiceNeeded)/((float)unknownDice/9);
    //float bidderChances = (bidderUnknown/3 - bidderDiceNeeded)/((float)bidderUnknown/9);
    double myChances = 1 - cumBinomialProbability(unknownDice, myDiceNeeded -1);
    double bidderChances;
    if(bidderDiceNeeded > 0)
     bidderChances = 1- cumBinomialProbability(bidderUnknown, bidderDiceNeeded -1);
    else bidderChances = 1.0;
    double nbChances;
    if(nbDiceNeeded > 0)
      nbChances = 1- cumBinomialProbability(nbUnknown, nbDiceNeeded -1 );
    else nbChances = 1.0;
    if(((myChances < .5) && (nbChances <.5)) || (bidderChances < .2))
     return "Liar!";
   }

   return (bidCount+1) + " " + myHighDie;
  }

  return 2 + " " + 2;
 } 

 private double cumBinomialProbability(int n, int k) {
   double sum = 0;
   for(int i = 0; i <=k; i++)
     sum += binomialProbability(n, i);
   return sum;
 }

 private double binomialProbability(int n, int k) {
   double nfact = 1;
   double dfact = 1;
   int greater;
   int lesser;
   if((n-k) > k) {
     greater = n - k;
     lesser = k;
   }
   else {
     greater = k;
     lesser = n-k;
   }
   for(int i = greater+1; i <= n; i++)
     nfact = nfact * i;
   for(int i = 2; i <= lesser; i++)
     dfact = dfact * i;
   return (nfact/dfact)*(Math.pow((1.0/3), k))*Math.pow(2.0/3, (n-k));
 }

}

Próbuje ustalić, czy powinien blefować, czy wezwać Kłamcę na podstawie szacunkowych skumulowanych rozkładów dwumianowych dla siebie i szans poprzednich i następnych licytantów na obecność potrzebnych kości.

Zasadniczo, wywołuje Kłamcę, jeśli poprzedni Licytant najprawdopodobniej będzie Kłamcą lub jeśli czuje, że zarówno on, jak i następny Licytator kłamią, a nie kłamią.

Brak działania
źródło
Dzięki tym zmianom Badnomial wydaje się zdalnie kompetentny w porównaniu do innych botów.
InactionPotential
5

Straight Shooter

Gra prosto i nie blefuje. Jest również na tyle naiwny, by myśleć, że inni też tak robią, więc nigdy nie wzywa kłamcy, chyba że stawka przekroczy całkowitą liczbę kości w grze (minus jego własne kości, które nie pasują do stawki).

Aby być nieco bardziej konserwatywnym niż dokładna oczekiwana liczba dla każdej kości, nie liczy własnych dziczy, ale zakłada, że ​​inne mają równomierny rozkład. Przy obecnych czterech graczach albo on, albo MostlyHonestAbe pojawiali się na pierwszym miejscu za każdym razem, z dość bliskimi wynikami.

Zakładam, że minimalna oferta to 2 2. Jeśli licytacja jednej kości (lub licytacji) jest dozwolona, ​​daj mi znać, abym mógł dokonać tej zmiany.

public class StraightShooter extends Player{
    public String toString(){return "Straight Shooter";}
    public String bid(int me, int[] numDices, int[] dice, String[] bids){
        int[] counts = new int[7];
        double[] expected = new double[7];
        int unknown = Controller.diceInPlay() - dice.length;
        for(int i:dice)
            counts[i]++;
        for(int i=2;i<7;i++)
            expected[i] = counts[i] + unknown / 3d;
        int bidCount = 2;
        int bidDie = 2;
        if(bids.length > 0){
            String[] lastBid = bids[bids.length-1].split(" ");
            bidCount = Integer.valueOf(lastBid[0]);
            bidDie = Integer.valueOf(lastBid[1])+1;
            int possible = Controller.diceInPlay();
            for(int i=2;i<7;i++)
                if(i != bidDie)
                    possible -= counts[i];
            if(bidCount > possible)
                return "Liar!";

            if(bidDie > 6){
                bidDie = 2;
                bidCount++;
            }
        }
        double best = Double.MAX_VALUE;
        int bestCount = bidCount;
        int bestDie = bidDie;
        for(int count=bidCount;count<=Controller.diceInPlay();count++){
            for(int die=bidDie;die<7;die++){
                double score = Math.abs(expected[die]-bidCount);
                if(score < best){
                    best = score;
                    bestCount = count;
                    bestDie = die;
                }
            }
            bidDie = 2;
        }   
        return bestCount + " " + bestDie;
    }
}
Geobity
źródło
To i MostlyHonest są bardzo niezdecydowani, by kłamać lub nazywać kłamcami, niektóre gry przechodzą na 2000 tur, kiedy testuję haha. : P
Cain
Tak samo u mnie. W porządku, ponieważ każda kolej jest dodatkowym punktem w kierunku końcowego wyniku. Jeśli przetrwam 2000 tur i nie wygram, to lepiej niż wygrać po 100 w mojej książce;)
Geobits
Po prostu musiałem jeszcze raz przyjrzeć się regułom punktacji. Nowa gra XD
Cain
Tak, z tym wynikiem wydaje się, że optymalną strategią może być bycie tak konserwatywnym, jak to tylko możliwe, i zbieranie punktów. Może jest coś lepszego, ale nie widzę tego.
Geobits
1
Nie jestem pewien , czy miałoby to znaczącą różnicę. Bycie konserwatystą nadal byłoby zaletą, tylko dlatego, że masz mniejszą szansę na utratę kości. Powodem, dla którego więcej ludzi nie gra w ten sposób, jest nudne, ale czym jest nuda dla bota?
Geobits
4

MostlyHonestAbe

Abe podaje konserwatywne przypuszczenia, że ​​reszta przeciwników umiera, a następnie pozostaje szczery, dopóki nie uzna, że ​​jest wystarczająca ilość kości, aby pokonać aktualną ofertę. W tym momencie blefuje raz, a następnym razem nazywa się kłamcą.

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;

public class MostlyHonestAbe extends Player{

    final boolean debug = false;
    boolean bluffedOnce = false;
    PrintStream out;
    @Override
    public String bid(int myId, int[] diceEachPlayerHas, int[] myDice, String[] bids) {
        try {
            File f = new File("abe.log.txt");
            out = new PrintStream(f);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            //e.printStackTrace();
        }
        if(debug){
            out = System.out;
        }

        //reset bluff counter on the first round
        if(bids.length < diceEachPlayerHas.length){
            bluffedOnce = false;
        }

        //Is it the first bid?
        if(bids.length == 0){
            out.println("I go first");
            return lowestViableBid(1,1, myDice, diceEachPlayerHas, true);
        }

        out.println("Last bid = " + bids[bids.length - 1]);
        out.print("My Dice = ");
        for(int d : myDice){
            out.print(d + ", ");
        }
        out.println();

        //What was the last bid?
        String[] lastBid = bids[bids.length -1].split(" ");
        return lowestViableBid(Integer.parseInt(lastBid[1]), Integer.parseInt(lastBid[0]), myDice, diceEachPlayerHas, false);


    }

    //Lowest honest bid, or liar
    private String lowestViableBid(int highestVal, int highestCount, int[] myDice, int[] otherDice, boolean firstTurn){

        //Make a better array for the dice
        //Include what the other players probably have
        int wilds = numDie(1, myDice);
        int[] diceCount = new int[6];
        diceCount[0] = wilds;
        int otherPlayerExpectedValue = 0;
        for(int d : otherDice){
            otherPlayerExpectedValue += d;
        }
        otherPlayerExpectedValue -= myDice.length;
        out.println("Number of other dice = " + otherPlayerExpectedValue);
        otherPlayerExpectedValue = otherPlayerExpectedValue / 4;
        //Note: Other player expected value is biased low, counting wilds the number should be divided by 3.

        out.println("playerExpectedVal = " + otherPlayerExpectedValue);
        for(int i = 1; i < 6; i++){
            diceCount[i] = numDie(i + 1, myDice) + wilds + otherPlayerExpectedValue;
        }


        //What's my array look like?
        for(int i = 0; i < diceCount.length; i++){
            out.println("diceVal = " + (i + 1) + ", diceCount = " + diceCount[i]);
        }

        //Can I bid the same number, but higher dice val?
        for(int diceVal = highestVal + 1; diceVal <= 6; diceVal++){
            if(diceCount[diceVal - 1] >= highestCount){ 
                out.println("1.Returning " + highestCount + " " + diceVal);
                return highestCount + " " + diceVal; }  
        }

        //What about more dice?
        for(int diceNum = highestCount + 1; diceNum <= myDice.length; diceNum++){
            for(int diceVal = highestVal + 1; diceVal <= 6; diceVal++){
                if(diceCount[diceVal - 1] == diceNum){ 
                    out.println("2.Returning " + (diceNum) + " " + diceVal);
                    return (diceNum) + " " + diceVal; } 
            }
        }

        if(firstTurn){ return "1 2"; }
        //If this is the first time I'm out of my league, bluff a round before calling liar.
        if(!bluffedOnce){
            out.println("bluffing " + (highestCount + 1) + " " + highestVal);
            bluffedOnce = true;
            return (highestCount + 1) + " " + highestVal;
        }
        out.println("Returning Liar!");
        //Well, wouldn't want to lie
        return "Liar!";
    }

    private int numDie(int i, int[] myDice){
        int result = 0;
        for(int j : myDice){
            if(i == j){ result++; }
        }
        return result;
    }
}
Kain
źródło
1
Czy ty żartujesz? Zostałem mniej niż pięć minut od opublikowania HonestAbe . Teraz muszę wymyślić nową nazwę: P
Geobits
1
Nie mogę mieć gry z Kłamcą w nazwie bez odniesienia do Abrahama Lincolna.
Cain
4

Dr House

Wszyscy kłamią!

public class DrHouse extends Player
{   
  public String bid(int yourId, int[] diceEachPlayerHas, int[] yourDice, String[] bids)
  {
    return "Liar!";
  }
}
Gus314
źródło
1
Sugeruję dodanie specjalnej logiki dla pierwszej oferty w rundzie.
SuperJedi224
4
@ SuperJedi224 Wyobrażam sobie, że bot uważa, że ​​kontroler mówi mu, że jego kolej jest kłamcą
Nathan Merrill
Zrobiłem mój dzień lol
Rohan Jhunjhunwala
2

Fidelio

Ten bot wie, że tylko jego najbardziej powtarzająca się wartość doprowadzi go do zwycięstwa, więc trzyma się go. Zakłada, że ​​część kości wszystkich jest taka sama jak jego, jeśli ktoś licytuje więcej niż ta część, zakłada, że ​​jest kłamcą.

public class Fidelio extends Player
{
    final String LIAR ="Liar!";
    @Override
    public String bid(int yourId, 
            int[] diceEachPlayerHas, 
            int[] yourDice,
            String[] bids) 
    {
        int[] myDices = new int[6];
        int valueToBid=1;
        for(int i : yourDice)
            myDices[i-1]++;
        for(int i=2;i<myDices.length;i++)
            if(myDices[i]>=myDices[valueToBid])
                valueToBid=i;
        if(bids.length==0)
            return 2+" "+valueToBid;
        int sum=0;
        String[] lastBidString=bids[bids.length-1].split(" ");
        int[] lastBid = new int[2];
        lastBid[0] = Integer.parseInt(lastBidString[0]);
        lastBid[1] = Integer.parseInt(lastBidString[1])-1;
        for(int i : diceEachPlayerHas)
            sum+=i;
        sum-=yourDice.length;
        if(lastBid[0]>sum/3+myDices[lastBid[1]]+myDices[0])
            return LIAR;
        if(lastBid[1]>= valueToBid)
        {
            if(lastBid[0]>=myDices[0]+myDices[valueToBid]+sum*2/5)
                return LIAR;
            return (lastBid[0]+1)+" "+myDices[valueToBid];
        }
        return lastBid[0]+" "+valueToBid;
    }
}

Mam nadzieję, że wykona kawał dobrej roboty :).

Katenkyo
źródło
Otrzymuję wyjątek IndexOutOfBoundsException w wierszu 13. Pamiętaj, że tablice są w Javie indeksowane jako 0.
SuperJedi224
Teraz dostaję jeden na drugim końcu w linii 19, dla indeksu -1. Wygląda na to, że próbował odczytać ostatni element z pustej tablicy, należy to sprawdzić.
SuperJedi224
Naprawiono sprawdzanie, czy (bids.length == 0) zostało wykonane po tym, jak użyłem ofert ...
Katenkyo
Och, właśnie zaproponowałem inne możliwe rozwiązanie, ale to prawdopodobnie również zadziała.
SuperJedi224
Ach, więc ta sugerowana edycja nie jest już potrzebna?
mbomb007
2

Statystyk

Masz 1/3 szans na posiadanie dowolnej liczby innej niż asy. Jeden facet powiedział mi kiedyś, że nie sprawdzanie kości i po prostu znajomość szans może sprawić, że wygrasz tę grę. EDYCJA: Licytacja była zbyt wysoka. Ale to niewiele poprawia wynik.

public class Statistician extends Player{
    public String toString(){return "Statistician";}
    public String bid(int me, int[] numDices, int[] dice, String[] bids){
        int totalDices = 0;
        int currentBid, max;
        for (int i : numDices)
            totalDices += i;
        max = totalDices/3;
        if(bids.length>0){
            currentBid = Integer.valueOf(bids[bids.length-1].split(" ")[0]);
            if(currentBid>max)
                return "Liar!";
        }
        return max+" 6";
    }
}
Trafienie
źródło
1

Absurdalny Bot

Twierdzi, że wszystkie kości to 6, chyba że nie może. Jeśli bot nie może tego zrobić, oznacza to, że jest to sytuacja niemożliwa lub prawie niemożliwa. Z tego powodu nazywa się kłamcą. Jestem ciekawy, jak skuteczny będzie ten bot.

public class AbsurdBot extends Player {
    @Override
    public String bid(int yourId, int[] diceEachPlayerHas,int[] yourDice,String[] bids)
    {
        String[] lastbid;
        int a, b, d;
        d = 0;
        for (int dice : diceEachPlayerHas)
            d += dice;
        if (bids.length != 0)
            {
                lastbid = bids[bids.length-1].split(" ");
                a = Integer.parseInt(lastbid[0]);
                b = Integer.parseInt(lastbid[1]);
                if (a > d || a == d && b == 6)
                    return "Liar!";
            }
        return d + " 6";
    }
}
Frederick
źródło
Jeśli chodzi o skuteczność: jego główną funkcją wydaje się przekazywanie kostek temu,
kto podąży
@Geobits Naprawiłem kod. To co się dzieje podczas próby skoku na język programowania nie został zaprogramowany w przed ...
Frederick
@Geobits Dzięki za wszelką pomoc. Myślę, że teraz to wreszcie działa poprawnie. Czy to? (Java jest myląca)
Frederick
Tak, teraz działa. Ta strategia jest jednak szalenie samobójcza. Uzyskuje tylko ~ 2% najniższego gracza.
Geobits
@Geobits Nigdy nie próbowałem uruchomić go z innymi graczami. Czy działałeś przeciwko innym?
Frederick
1

Pirat

Zrobiłem kilka prostych botów podczas testowania kontrolera, i to jest jedyny naprawdę dobry.

Prawdopodobnie zostanie poprawiony później.

import java.util.Arrays;
import java.util.Scanner;

public class Pirate extends Player{
    public Pirate() {
    }
    public String toString(){
        return "The Pirate";
    }
    private String bid(int[] t,int tol){
        int[]z=t.clone();
        Arrays.sort(z);
        int j=0;
        for(int i=0;i<6;i++){
            if(t[i]==z[5]){j=i;break ;}
        }
        return (tol+t[j])+" "+(j+1);
    }
    @Override
    public String bid(int yourId, int[] diceEachPlayerHas, int[] yourDice,
            String[] bids) {
        int[] t=new int[6];
        for(int i=0;i<yourDice.length;i++){
            t[yourDice[i]-1]++;
        }
        for(int i=1;i<t.length;i++)t[i]+=t[0];
        int tol=(Controller.diceInPlay()-yourDice.length)/4;
        if(bids.length==0)return bid(t,1);
        Scanner i=new Scanner(bids[bids.length-1]);
        int x=i.nextInt(),y=i.nextInt();
        i.close();
        if(t[y-1]>x)return (t[y-1]+2)+" "+y;
        int nd=Controller.diceInPlay();
        if(x>nd+t[y-1]-yourDice.length)return "Liar!";
        if(Controller.isGreaterThan(bid(t,tol), bids[bids.length-1])){
            int z=Controller.valueOf(bids[bids.length-1]);
            for(int j=1;j<=tol;j++)if(Controller.valueOf(bid(t,j))>z)return bid(t,j);
        }
        return "Liar!";
    }
}
SuperJedi224
źródło