King of the Hill - ลูกเต๋าที่โกหก


22

Liar's Diceเป็นเกมลูกเต๋าที่ค่อนข้างง่าย ฉันเห็นกฎที่แตกต่างกันไปเล็กน้อย แต่นี่เป็นรุ่นที่ฉันคุ้นเคยมากที่สุด:

  • ผู้เล่นแต่ละคนเริ่มต้นด้วย 5d6
  • ยกเว้นเมื่อทำการทอยลูกเต๋าในตอนท้ายของรอบผู้เล่นแต่ละคนอาจเห็นลูกเต๋าของตัวเอง แต่ไม่ใช่ของฝ่ายตรงข้ามใด ๆ
  • ในช่วงเริ่มต้นของรอบใด ๆ ผู้เล่นทุกคนหมุนลูกเต๋าอะไรก็ตามที่พวกเขามีอยู่ในปัจจุบัน
  • จากนั้นผู้เล่นหนึ่งคน (โดยปกตินี่คือทั้งผู้ชนะในรอบก่อนหน้าหรือผู้เล่นทางด้านซ้ายของผู้เล่นที่เริ่มต้นครั้งที่แล้วเราจะใช้อดีตสำหรับ KotH นี้ด้วยผู้เล่นสุ่มเริ่มรอบแรก) ทำให้เดาได้ว่ามีหมายเลขใดจำนวนหนึ่งอยู่บนโต๊ะ(อยู่ที่ป่า)
  • การเสนอราคาจะดำเนินต่อไปทางขวาจะสูงขึ้นในแต่ละครั้ง (ตัวอย่างเช่น 3 fives, 3 sixes และ 4 twos ทั้งหมดสูงกว่า 3 fours แต่ 3 threes ไม่ 3; 4 อันสูงกว่าเช่นกัน แต่การเสนอราคาอาจทำให้คุณ ข้อเสีย); จนกว่าผู้เล่นคนใดเรียกผู้เล่นก่อนหน้าพวกเขาว่าเป็นคนโกหก
  • ณ จุดนี้ผู้เล่นทุกคนเปิดเผยลูกเต๋าของพวกเขาและนับจำนวนของการเสนอราคาจำนวนสุดท้ายบนโต๊ะทั้งหมด
  • หากยอดรวมต่ำกว่าการประมูลผู้เล่นที่ทำการประมูลต้องให้ตายแก่ผู้เล่นที่เรียกพวกเขาว่าเป็นคนโกหกมิฉะนั้นผู้เล่นที่เรียกผู้ชนะการประมูลจะต้องให้ตายกับผู้ประมูล (ดังนั้นผู้ชนะจึงชนะ หากอย่างน้อยพวกเขาก็มีจำนวนมากเท่าที่เขามีการเสนอราคาไม่จำเป็นต้องมีจำนวนที่แน่นอน)
  • เมื่อคุณหมดลูกเต๋าคุณก็แพ้
  • ผู้เล่นคนสุดท้ายยืนชนะ

ตัวอย่างเช่น:

ผู้เล่นคนหนึ่งมี 1,1,2,4,6
ผู้เล่นสองมี 1,2,2,3,5
ผู้เล่นที่สามมี 1,3,3,4,6
ผู้เล่นคนที่หนึ่ง: สามแต้ม
ผู้เล่นที่สอง: สี่ twos
ผู้เล่นที่สาม: สี่สิบสาม
ผู้เล่นคนที่หนึ่ง: ห้าครั้ง
ผู้เล่นที่สอง: หก twos
ผู้เล่นที่สาม: หกสิบ
ผู้เล่นคนที่หนึ่ง: หกสี่คน
ผู้เล่นที่สอง: โกหก!
พวกเขาเปิดเผยลูกเต๋าของพวกเขาและนับคน (เพราะคนที่เป็นป่า) และสี่
ปรากฎว่าในความเป็นจริงมีแค่หกสี่เท่าเท่านั้น
ดังนั้นผู้เล่นสองให้ผู้เล่นหนึ่งตาย
พวกเขาเล่นใหม่และผู้เล่นคนหนึ่งเริ่มรอบต่อไป

คุณต้องเขียนบอทเพื่อเล่นเกมนี้ จะต้องใช้คลาส 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);
}
  • คุณต้องใช้วิธีการเสนอราคา
    • อาร์กิวเมนต์แรกคือตำแหน่งปัจจุบันของบอทของคุณในลำดับเทิร์นที่สองคืออาร์เรย์แสดงจำนวนลูกเต๋าที่ผู้เล่นแต่ละคน (รวมถึงตัวคุณเอง) มีอยู่ในขณะนี้ที่สามคืออาร์เรย์ที่แสดงค่าที่แสดงบนลูกเต๋าของคุณในปัจจุบัน อาร์เรย์ของการเสนอราคาทั้งหมดที่ทำตั้งแต่เริ่มต้นรอบปัจจุบัน - จะมีความยาว 0 ถ้าคุณทำการประมูลครั้งแรกของรอบ
    • เอาต์พุตควรเป็นสตริงของฟอร์ม "number face" หรือสตริง "Liar!" เพื่อเรียกร้องให้ผู้เสนอราคาก่อนหน้าเป็นคนโกหก
    • หากผลลัพธ์ของคุณถูกฟอร์แมตอย่างผิดกฎหมายคุณจะถูกกำจัด
  • คุณสามารถแทนที่เมธอด toString แต่ไม่จำเป็นต้อง อย่างไรก็ตามคุณไม่สามารถแก้ไขได้ในลักษณะที่รบกวนความสามารถในการอ่านเอาต์พุตของคอนโทรลเลอร์
  • คุณได้รับอนุญาตให้เรียกวิธีการสาธารณะอื่น ๆ ของคอนโทรลเลอร์ แต่ไม่ใช่วิธีหลัก
  • คุณสามารถอ่านและแก้ไขเฉพาะไฟล์ในไดเรกทอรีที่ทำงานอยู่ซึ่งมีคำนำหน้าชื่อบอทของคุณ
  • คุณไม่ได้รับอนุญาตให้รับข้อมูลจากแหล่งอื่น
  • ตัวแปรอินสแตนซ์จะถูกรีเซ็ตในช่วงเริ่มต้นของแต่ละเกมใหม่ แต่ตัวแปรแบบสแตติกไม่ใช่

เกณฑ์การให้คะแนน

  • หนึ่งชุดของเกม 1,000 เกมที่มีผู้เล่น 3-5 คนในแต่ละครั้งจะถูกจำลองในแต่ละครั้งที่มีการเพิ่มบอท (ทันทีที่มีบอทสามตัวหรือมากกว่าถูกส่ง) คะแนนที่แสดงในแหล่งตัวควบคุม (ในเกมใดก็ตาม รับ 1 ในช่วงเริ่มต้นของแต่ละตาของคุณ 10 ครั้งในแต่ละครั้งที่คุณตายและ 1,000 โบนัสถ้าคุณชนะ) บังคับใช้ขีด จำกัด 5,000 TURNS (ไม่ใช่รอบ) ในแต่ละเกม
  • บอทของคุณจะได้คะแนนจากคะแนนจากเกมล่าสุด บวกสิบเท่าของคะแนนการลงคะแนนหากไม่เป็นลบ (หลังไม่น่าจะมีผลกระทบอย่างมีนัยสำคัญกับคะแนน)

แหล่งที่มาของตัวควบคุมสามารถพบได้ที่นี่

คะแนน ณ วันที่ 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
คุณควรชี้แจงว่าผลลัพธ์ควรเป็น "2 3" และไม่ใช่ "two threes" ตามที่แสดงในตัวอย่าง นอกจากนี้ยังมีวิธีในการควบคุมเพื่อดูการแข่งขันเดียวหรือไม่?
Cain

ไม่ใช่ในรุ่นอย่างเป็นทางการ แต่ฉันจะโพสต์รุ่นอื่นที่ให้คุณทำเช่นนั้นได้
SuperJedi224

@Geobits: ถ้าคุณต้องการ มันจะทำให้คุณเสียเปรียบนิดหน่อยถ้ามีคนโทรหาคุณ
SuperJedi224

1
ฉันถือว่าดัชนีของอาร์เรย์เป็น "รหัส" ของผู้เล่นดังนั้นdiceEachPlayerHas[yourId]= จำนวนลูกเต๋าของคุณและbids[yourId]เป็นการเสนอราคาครั้งแรกของคุณ ถูกต้องหรือไม่
ไม่ใช่ว่า Charles

1
ฉันเคยเห็นเกมที่มีผู้ส่งบางคนเล่นเกมมากกว่าคนอื่น ๆ (ไม่มีใคร: 414 เกม, Straight Shooter: 409 เกม) ไม่ยุติธรรมคุณช่วยแก้ไขได้มั้ย
CommonGuy

คำตอบ:


6

ไม่มีใคร

พยายามที่จะเดาลูกเต๋าจากผู้เล่นคนอื่น เรียกคนโกหกคนอื่น ๆ ถ้าไม่รู้ว่าจะทำอย่างไร

แก้ไข:แก้ไขปัญหาที่ไม่มีใครเสนอราคาตลอดไปไม่เคยเรียก Liar

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

การอัปเดตชุดล่าสุดของคุณดูเหมือนจะมีส่วนช่วยจริงๆ
SuperJedi224

6

Badnomial บอตที่ทำการตัดสินใจที่ไม่ดีโดยพิจารณาจากการแจกแจงทวินาม:แก้ไข: แก้ไขข้อผิดพลาดโง่ ๆ ในการคำนวณความน่าจะเป็นตอนนี้บัญชีสำหรับผู้ประมูลรายถัดไป

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

}

มันพยายามที่จะตรวจสอบว่ามันควรป้านหรือโทรโกหกโดยพิจารณาจากการแจกแจงทวินามสะสมโดยประมาณสำหรับตัวเองและโอกาสในการประมูลก่อนหน้าและถัดไปของการมีลูกเต๋าอยู่ในปัจจุบัน

โดยพื้นฐานแล้วมันจะเรียก Liar หากผู้เสนอราคาก่อนหน้ามีแนวโน้มที่จะเป็น Liar หรือหากรู้สึกว่าทั้งผู้ประมูลและผู้เสนอราคารายถัดไปมีแนวโน้มที่จะโกหกมากกว่าไม่


ด้วยการเปลี่ยนแปลงเหล่านี้ Badnomial ดูเหมือนจะมีความสามารถจากระยะไกลเทียบกับบ็อตอื่น ๆ
InactionPotential

5

ยิงตรง

เขาเล่นตรงและไม่ทู่ นอกจากนี้เขายังไร้เดียงสาพอที่จะคิดว่าคนอื่นทำเช่นกันดังนั้นเขาจึงไม่เคยเรียกคนโกหกว่าการเสนอราคาจะมากกว่าจำนวนรวมของลูกเต๋าที่เล่น (ลบด้วยลูกเต๋าของตัวเองที่ไม่ตรงกับการเสนอราคา)

เป็นคนหัวโบราณมากกว่าที่คาดไว้สำหรับการตายแต่ละครั้งเขาจะไม่นับป่าของเขา แต่ถือว่าคนอื่นมีการแจกแจงแบบเดียวกัน ด้วยผู้เล่นสี่คนในปัจจุบันไม่ว่าเขาหรือ MostlyHonestAbe จะมาเป็นอันดับแรกในแต่ละครั้งด้วยคะแนนที่ค่อนข้างใกล้เคียง

2 2ฉันสมมติเสนอราคาต่ำสุดคือ หากอนุญาตให้มีการเสนอราคาหนึ่งรายการ (หรือรายการประมูล) แจ้งให้เราทราบเพื่อที่ฉันจะได้ทำการเปลี่ยนแปลงนั้น

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

นี่และ MostlyHonestAbe ทั้งคู่จึงลังเลที่จะโกหกหรือเรียกคนโกหกมีเกมบางเกมถึง 2000 รอบเมื่อฉันทดสอบฮ่าฮ่า : P
Cain

เหมือนกันในเหมือง แต่ก็ไม่เป็นไรเพราะทุกเทิร์นจะเป็นคะแนนพิเศษสำหรับคะแนนสุดท้าย หากฉัน
ย้อนไป

ฉันแค่ต้องไปดูกฎการให้คะแนนอีกครั้ง เกมใหม่ XD
Cain

ใช่ด้วยการให้คะแนนนี้ดูเหมือนว่ากลยุทธ์ที่เหมาะสมอาจจะอนุรักษ์นิยมมากที่สุดเท่าที่จะทำได้และเพียงแค่เพิ่มคะแนน อาจจะมีสิ่งที่ดีกว่านี้ แต่ฉันมองไม่เห็น
Geobits

1
ฉันไม่แน่ใจว่ามันจะสร้างความแตกต่างมาก การเป็นคนอนุรักษ์นิยมยังคงเป็นข้อได้เปรียบเพียงเพราะคุณมีโอกาสน้อยที่จะเสียชีวิต เหตุผลที่คนจำนวนมากไม่เล่นแบบนั้นในชีวิตจริงก็เพราะมันน่าเบื่อ แต่เบื่อกับบอทคืออะไร?
Geobits

4

MostlyHonestAbe

เอ็บทำการคาดเดาอย่างระมัดระวังเกี่ยวกับฝ่ายตรงข้ามที่เหลือเสียชีวิตจากนั้นก็ซื่อสัตย์ต่อไปจนกว่าเขาจะไม่คิดว่ามีลูกเต๋าเพียงพอที่จะเอาชนะการเสนอราคาปัจจุบัน เมื่อมาถึงจุดนี้เขาบลัฟฟ์อีกครั้งแล้วเรียกคนโกหกในครั้งต่อไป

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
คุณล้อเล่นกับฉันไหม ฉันได้น้อยกว่าห้านาทีจากการโพสต์HonestAbe ตอนนี้ฉันต้องคิดชื่อใหม่: P
Geobits

1
ไม่สามารถเล่นเกมกับ Liar ในชื่อโดยไม่มีการอ้างอิง Abraham Lincoln ที่ไหนสักแห่ง
Cain

4

บ้านดร

ทุกคนโกหก!

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

1
ฉันขอแนะนำให้เพิ่มตรรกะพิเศษเมื่อคุณมีการเสนอราคารอบแรก
SuperJedi224

4
@ SuperJedi224 ฉันจินตนาการว่าบอทพิจารณาตัวควบคุมแล้วบอกเขาว่ามันเป็นตาของเขาที่จะเป็นคนโกหก
นาธานเมอร์ริลล์

ทำให้วันของฉันดีขึ้น
Rohan Jhunjhunwala

2

Fidelio

บอทนี้รู้ว่ามีเพียงค่ากำเริบที่สุดของเขาเท่านั้นที่จะนำเขาไปสู่ชัยชนะดังนั้นเขาจึงยึดมันไว้ เขาคิดว่ามีส่วนหนึ่งของลูกเต๋าของทุกคนที่เหมือนกับของเขาถ้าใครก็ตามเสนอราคามากกว่าส่วนนั้นเขาถือว่าเขาเป็นคนโกหก

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

ฉันหวังว่าเขาจะทำงานได้ดี :)


ฉันได้รับ IndexOutOfBoundsException ที่บรรทัดที่ 13 จำไว้ว่าอาร์เรย์นั้นมี 0-indexed ใน java
SuperJedi224

ตอนนี้ฉันจะได้หนึ่งในอีกปลายหนึ่งบนบรรทัดที่ 19 สำหรับดัชนี -1 ดูเหมือนว่าจะพยายามอ่านองค์ประกอบสุดท้ายจากอาเรย์ที่ว่างเปล่าคุณควรรวมการตรวจสอบสำหรับสิ่งนั้น
SuperJedi224

คงที่ตรวจสอบว่า (bid.length == 0) ทำหลังจากฉันใช้การเสนอราคา ...
Katenkyo

โอ้ฉันเพิ่งเสนอวิธีแก้ปัญหาอื่นที่เป็นไปได้ แต่นี่อาจจะใช้ได้เช่นกัน
SuperJedi224

อาดังนั้นการแก้ไขที่แนะนำนี้จึงไม่จำเป็นอีกต่อไป?
mbomb007

2

นักสถิติ

คุณมีโอกาส 1/3 ที่จะมีหมายเลขอื่นนอกเหนือจากเอซ ผู้ชายคนหนึ่งเคยบอกฉันว่าการไม่ตรวจสอบลูกเต๋าของคุณและเพียงแค่รู้ว่าโอกาสสามารถทำให้คุณชนะเกมนี้ได้ แก้ไข: มันเสนอราคาสูงเกินไป แต่มันก็ไม่ได้ปรับปรุงคะแนนมากนัก

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

บอทไร้สาระ

ทำให้การอ้างสิทธิ์ว่าลูกเต๋าทั้งหมดเป็น 6's เว้นแต่จะไม่สามารถทำได้ หากบอทไม่สามารถทำเช่นนั้นได้หมายความว่านี่เป็นสถานการณ์ที่เป็นไปไม่ได้หรือสถานการณ์ที่เกือบจะเป็นไปไม่ได้ ด้วยเหตุนี้มันจึงเรียกคนโกหกว่า ฉันอยากรู้ว่าบอทนี้จะมีประสิทธิภาพแค่ไหน

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

สำหรับวิธีที่มีประสิทธิภาพ: ฟังก์ชั่นหลักของมันดูเหมือนว่าจะส่งมอบลูกเต๋าให้กับผู้เล่นที่ตามมา: P
Geobits

@Geobits ฉันแก้ไขรหัสแล้ว นี่คือสิ่งที่เกิดขึ้นเมื่อคุณพยายามที่จะข้ามไปสู่ภาษาการเขียนโปรแกรมที่คุณไม่ได้ตั้งโปรแกรมมาก่อน ...
frederick

@Geobits ขอบคุณสำหรับความช่วยเหลือ ฉันคิดว่าในที่สุดมันก็ใช้งานได้ดีในตอนนี้ ทำมัน? (Java สับสน)
frederick

ใช่แล้วมันจะทำงานตอนนี้ แม้ว่ากลยุทธ์นี้จะฆ่าตัวตายอย่างบ้าคลั่ง คะแนนเพียง 2% ของผู้เล่นถัดไปที่ต่ำที่สุด
Geobits

@Geits ฉันไม่เคยลองเรียกใช้กับผู้เล่นคนอื่น คุณเรียกใช้กับผู้อื่นหรือไม่
frederick

1

โจรสลัด

ฉันทำบอทง่าย ๆ สองสามตัวในขณะที่ทำการทดสอบคอนโทรลเลอร์และนี่เป็นโปรแกรมเดียวที่ดีจริงๆ

จะมีโอกาสได้รับการปรับปรุงในภายหลัง

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!";
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.