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

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

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


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

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

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

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 :).


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

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

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!";
    }
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.