Vua đồi - Xúc xắc của kẻ nói dối


22

Liar's Dice là một trò chơi súc sắc khá đơn giản. Tôi đã thấy một vài biến thể khác nhau của các quy tắc, nhưng đây là phiên bản tôi quen thuộc nhất:

  • Mỗi người chơi bắt đầu với 5d6
  • Ngoại trừ khi kiểm tra súc sắc ở cuối vòng, mỗi người chơi có thể thấy xúc xắc của riêng mình, nhưng không phải là của bất kỳ đối thủ nào
  • Khi bắt đầu bất kỳ vòng nào, tất cả người chơi sẽ tung bất kỳ con xúc xắc nào họ hiện có
  • Sau đó, một người chơi (thông thường, đây là người chiến thắng của vòng trước HOẶC người chơi ở bên trái của người chơi đã bắt đầu lần trước; chúng tôi sẽ sử dụng người chơi trước cho KotH này; với một người chơi ngẫu nhiên bắt đầu vòng đầu tiên) đoán xem có bao nhiêu số cụ thể trên bàn (ONES IS WILD)
  • Đặt giá thầu tiếp tục ở bên phải, tăng cao hơn mỗi lần (ví dụ: 3 fives, 3 sixes và 4 twos đều cao hơn 3 fours, nhưng 3 threes thì không, 4 cái cũng cao hơn nhưng đấu thầu trên những cái có thể sẽ đưa bạn vào một bất lợi); cho đến khi bất kỳ người chơi nào gọi người chơi trước họ là kẻ nói dối
  • Tại thời điểm này, tất cả người chơi tiết lộ súc sắc của họ và đếm số lần đặt giá cuối cùng trên bàn
  • Nếu tổng số tiền thấp hơn giá thầu, người chơi đã đặt giá thầu phải chết cho người chơi gọi họ là kẻ nói dối, nếu không, người chơi gọi người trả giá là người nói dối phải chết cho người trả giá (để người trả giá thắng nếu số lượng của họ ít nhất là nhiều như anh ta đã trả giá, thì đó không phải là con số chính xác)
  • Khi bạn hết xúc xắc, bạn sẽ thua
  • Người chơi cuối cùng đứng thắng

Ví dụ:

Người chơi có 1,1,2,4,6
Người chơi hai có 1,2,2,3,5
Người chơi ba có 1,3,3,4,6
Người chơi một: ba sáu.
Người chơi hai: bốn twos.
Người chơi ba: bốn chục.
Người chơi một: năm twos.
Người chơi hai: sáu twos.
Người chơi ba: sáu sáu.
Người chơi một: sáu bốn.
Người chơi hai: Kẻ nói dối!
Họ tiết lộ súc sắc của họ và đếm những người (vì những người hoang dã) và bốn người.
Thực tế, có sáu chính xác.
Vì vậy, người chơi hai cung cấp cho người chơi một chết.
Họ reroll và người chơi bắt đầu vòng tiếp theo.

Bạn phải viết một bot để chơi trò chơi này. Nó phải thực hiện lớp java trừu tượng sau:

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);
}
  • Bạn phải thực hiện phương thức đấu thầu
    • Đối số đầu tiên là vị trí hiện tại của bot của bạn theo thứ tự lần lượt, thứ hai là một mảng cho biết mỗi người chơi (bao gồm cả chính bạn) hiện có bao nhiêu, thứ ba là một mảng hiển thị các giá trị hiện được hiển thị trên súc sắc của riêng bạn và thứ tư là một mảng của tất cả các giá thầu được thực hiện kể từ khi bắt đầu vòng hiện tại - sẽ có độ dài 0 nếu bạn thực hiện giá thầu đầu tiên của vòng
    • Đầu ra phải là một chuỗi có dạng "mặt số" hoặc chuỗi "Kẻ nói dối!" để gọi người trả giá trước đó là kẻ nói dối.
    • Nếu đầu ra của bạn được định dạng bất hợp pháp, bạn sẽ bị loại.
  • Bạn có thể ghi đè phương thức toString, nhưng không bắt buộc. Tuy nhiên, bạn không thể chỉnh sửa nó theo bất kỳ cách nào cản trở khả năng đọc của đầu ra của bộ điều khiển.
  • Bạn được phép gọi bất kỳ phương thức công khai nào khác của bộ điều khiển, nhưng không được gọi là phương thức chính của nó.
  • Bạn chỉ có thể đọc và chỉnh sửa các tệp trong thư mục đang chạy có tiền tố tên bot của bạn
  • Bạn không được phép lấy đầu vào từ bất kỳ nguồn nào khác
  • Biến sơ thẩm được đặt lại khi bắt đầu mỗi trò chơi mới, nhưng biến tĩnh thì không.

Chấm điểm

  • Một bộ gồm 1.000 trò chơi, mỗi trò chơi có 3-5 người chơi, sẽ được mô phỏng mỗi lần thêm bot (ngay khi ba hoặc nhiều bot được gửi), được ghi như thể hiện trong nguồn điều khiển (trong bất kỳ trò chơi cụ thể nào, bạn nhận 1 khi bắt đầu mỗi lượt của bạn, 10 mỗi lần bạn bắt được một con súc sắc và 1.000 phần thưởng nếu bạn giành chiến thắng); thi hành giới hạn 5.000 TURNS (không phải vòng) mỗi trò chơi.
  • Bot của bạn sẽ được ghi điểm bởi điểm số của nó từ bộ trò chơi mới nhất; cộng với mười lần số phiếu bầu của nó, nếu không âm. (Cái sau không chắc có ảnh hưởng đáng kể đến điểm số)

Nguồn điều khiển có thể được tìm thấy ở đây.

Điểm số của 2015-06-19:

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
Bạn nên làm rõ rằng đầu ra phải là "2 3" chứ không phải "hai phần ba" như ví dụ của bạn cho thấy. Ngoài ra, có cách nào trong bộ điều khiển để xem một trận đấu không?
Cain

Không phải trong phiên bản chính thức, nhưng tôi sẽ đăng một phiên bản thay thế cho phép bạn làm điều đó.
SuperJedi224

@Geobits: Nếu bạn muốn. Nó sẽ khiến bạn gặp bất lợi nếu có ai đó gọi cho bạn.
SuperJedi224

1
Tôi giả sử các chỉ số của các mảng là "id" của người chơi, do đó diceEachPlayerHas[yourId]= số xúc xắc của bạn và bids[yourId]là giá thầu đầu tiên của bạn (hoặc null nếu đến lượt đầu tiên của bạn). Đúng không?
Không phải là Charles

1
Tôi đã thấy các trò chơi trong đó một số bài nộp chơi nhiều trò chơi hơn các trò chơi khác (Không có ai: 414 trò chơi, Trò chơi bắn súng thẳng: 409 trò chơi). Điều này không công bằng, bạn có thể vui lòng sửa nó không?
CommonGuy

Câu trả lời:


6

Không ai

Thử đoán súc sắc từ những người chơi khác. Gọi những kẻ nói dối bot khác nếu nó không biết phải làm gì.

Chỉnh sửa: Đã khắc phục sự cố trong đó Không ai sẽ trả giá mãi mãi, không bao giờ gọi cho Kẻ nói dối.

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

Bộ cập nhật cuối cùng của bạn thực sự có vẻ đã giúp ích.
SuperJedi224

6

Badnomial, bot đưa ra quyết định tồi dựa trên phân phối nhị thức: Chỉnh sửa : Đã sửa một lỗi ngu ngốc trong tính toán xác suất, hiện chiếm tài khoản cho Nhà thầu tiếp theo cũng như trước đó.

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

}

Nó cố gắng xác định xem có nên lừa gạt hay gọi Liar dựa trên các phân phối nhị thức tích lũy ước tính cho chính nó và cơ hội của các nhà thầu trước đó và tiếp theo để có xúc xắc cần thiết của họ.

Về cơ bản, nó gọi Liar nếu Nhà thầu trước rất có khả năng là Kẻ nói dối hoặc nếu cảm thấy rằng cả Nhà thầu và Nhà thầu tiếp theo có nhiều khả năng nói dối hơn là không.


Với những thay đổi này, Badnomial thực sự có vẻ có thẩm quyền từ xa so với các bot khác.
InactionPotential

5

Cú sút thẳng

Anh ấy chơi thẳng và không vô tội vạ. Anh ta cũng đủ ngây thơ để nghĩ rằng những người khác cũng vậy, vì vậy anh ta không bao giờ gọi những kẻ nói dối trừ khi giá thầu vượt quá tổng số xúc xắc đang chơi (trừ xúc xắc của chính anh ta không khớp với giá thầu).

Để bảo thủ hơn một chút so với con số dự kiến ​​chính xác cho mỗi lần chết, anh ta không tính số tự nhiên của mình, nhưng giả sử những người khác có phân phối đồng đều. Với bốn người chơi hiện tại, anh ta hoặc MostlyHonestAbe lần đầu tiên xuất hiện, với điểm số khá gần.

Tôi giả sử giá thầu tối thiểu là 2 2. Nếu giá thầu của một người chết (hoặc đấu thầu) được cho phép, hãy cho tôi biết để tôi có thể thực hiện thay đổi đó.

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

Điều này và MostlyHonestAbe đều rất do dự khi nói dối hoặc gọi điện nói dối, có một số trò chơi sẽ đến 2000 lượt khi tôi kiểm tra haha. : P
Cain

Tương tự trong tôi. Mặc dù vậy cũng không sao, bởi vì mỗi lượt là một điểm phụ cho điểm số cuối cùng. Nếu tôi kéo dài 2000 lượt và không thắng, điều đó tốt hơn là thắng sau 100 trong cuốn sách của tôi;)
Geobits

Tôi chỉ cần nhìn vào các quy tắc ghi bàn một lần nữa. Trò chơi hoàn toàn mới XD
Cain

Phải, với cách tính điểm này, có vẻ như chiến lược tối ưu có thể là bảo thủ nhất có thể, và chỉ cần ghi điểm. Có lẽ có một cái gì đó tốt hơn, nhưng tôi không thể nhìn thấy nó.
Geobits

1
Tôi không chắc nó sẽ tạo ra nhiều khác biệt. Bảo thủ vẫn sẽ là một lợi thế, chỉ vì bạn có cơ hội mất một cái chết thấp hơn. Lý do nhiều người không chơi theo cách đó trong cuộc sống thực là vì nó chỉ nhàm chán, nhưng bot là gì?
Geobits

4

Chủ yếu là tốt nhất

Abe đưa ra những phỏng đoán bảo thủ về phần còn lại của đối thủ sẽ chết, và sau đó giữ trung thực cho đến khi anh ta không nghĩ rằng có đủ súc sắc để đánh bại giá thầu hiện tại. Lúc này anh ta vô tội vạ một lần, rồi gọi kẻ nói dối lần sau.

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
Bạn đang đùa tôi à Tôi đã không đến năm phút kể từ khi đăng HonestAbe . Bây giờ tôi phải nghĩ ra một cái tên mới: P
Geobits

1
Không thể có một trò chơi với Liar trong tên mà không có tài liệu tham khảo của Abraham Lincoln ở đâu đó.
Cain

4

Nhà bác sĩ

Mọi người đều nói dối!

public class DrHouse extends Player
{   
  public String bid(int yourId, int[] diceEachPlayerHas, int[] yourDice, String[] bids)
  {
    return "Liar!";
  }
}

1
Tôi đề nghị thêm logic đặc biệt khi bạn có giá thầu đầu tiên của vòng.
SuperJedi224

4
@ SuperJedi224 Tôi tưởng tượng rằng bot sau đó xem xét bộ điều khiển nói với anh ta rằng đến lượt anh ta là kẻ nói dối
Nathan Merrill

Làm cho ngày của tôi lol
Rohan Jhunjhunwala

2

Fidelio

Bot này biết rằng chỉ có giá trị thường xuyên nhất của anh ta sẽ dẫn anh ta đến chiến thắng, vì vậy anh ta gắn bó với nó. Anh ta cho rằng có một phần súc sắc của mọi người giống như của anh ta, nếu có ai trả giá cao hơn phần đó, anh ta cho rằng anh ta là kẻ nói dối.

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

Tôi hy vọng anh ấy sẽ làm một số công việc tốt :).


Tôi đang nhận được IndexOutOfBoundException trên dòng 13. Hãy nhớ rằng các mảng được lập chỉ mục 0 trong java.
SuperJedi224

Bây giờ tôi nhận được một ở đầu kia trên dòng 19, với chỉ số -1. Có vẻ như nó đang cố đọc phần tử cuối cùng từ một mảng trống, bạn nên bao gồm một kiểm tra cho điều đó.
SuperJedi224

Đã sửa lỗi, kiểm tra xem (hồ sơ dự thầu.length == 0) đã được thực hiện sau khi tôi sử dụng giá thầu ...
Katenkyo

Ồ, tôi vừa đề xuất một giải pháp khả thi khác, nhưng điều này có lẽ cũng sẽ hiệu quả.
SuperJedi224

Ah, vậy chỉnh sửa đề xuất này không còn cần thiết?
mbomb007

2

Thống kê

Bạn có 1/3 cơ hội có bất kỳ số nào ngoài con át chủ bài. Một anh chàng đã từng nói với tôi rằng không kiểm tra súc sắc của bạn và biết rằng tỷ lệ cược có thể khiến bạn thắng trò chơi này. EDIT: Nó đã được đặt giá thầu quá cao. Nhưng nó không cải thiện điểm số rất nhiều.

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

Bot vô lý

Khiến cho tất cả các con xúc xắc là 6 s trừ khi không thể. Nếu bot không thể làm điều đó, điều đó có nghĩa rằng đây là một tình huống không thể hoặc gần như không thể. Bởi vì điều này, nó gọi là kẻ nói dối. Tôi tò mò về việc bot này sẽ hiệu quả như thế nào.

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

Về mức độ hiệu quả: Chức năng chính của nó dường như đang đưa xúc xắc cho bất kỳ người chơi nào theo dõi nó: P
Geobits

@Geobits Tôi đã sửa mã. Đây là những gì xảy ra khi bạn cố gắng nhảy vào một ngôn ngữ lập trình mà bạn chưa lập trình trước đó ...
frederick

@Geobits Cảm ơn tất cả sự giúp đỡ. Tôi nghĩ rằng điều này cuối cùng đã hoạt động đúng. Phải không? (Java khó hiểu)
frederick

Vâng, nó chạy ngay bây giờ. Chiến lược này là tự tử điên cuồng, mặc dù. Nó chỉ đạt ~ 2% người chơi thấp nhất tiếp theo.
Geobits

@Geobits Tôi chưa bao giờ thử chạy nó với những người chơi khác. Bạn đã chạy nó chống lại những người khác?
frederick

1

Cướp biển

Tôi đã tạo ra một vài bot đơn giản trong khi thử nghiệm bộ điều khiển và đây là cái duy nhất thực sự tốt.

Sẽ có khả năng được cải thiện sau này.

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!";
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.