Xác định tay bài


19

Tôi đã thực hiện một trò chơi Texas Hold'Em như một phần của đánh giá và tôi đã nghiên cứu cách kiểm tra 7 thẻ có sẵn và xác định xem có tồn tại tay không.

Phương pháp khả thi duy nhất tôi có thể nghĩ đến là sắp xếp các thẻ theo số, sau đó kiểm tra từng nhóm 5 thẻ có thể và kiểm tra xem chúng có khớp với danh sách của mỗi bàn tay có thể không. Điều đó sẽ mất một thời gian dài snd sẽ chỉ khả thi để xác định các cặp, vì bộ đồ là không liên quan.

Các thẻ là mỗi chuỗi, được tạo thành từ một số / a / j / q / k và một bộ đồ (char)3(tạo ra một biểu tượng spades nhỏ).

Có ai có bất kỳ đề xuất, công thức hoặc liên kết nào tôi có thể sử dụng để giúp tạo ra một hệ thống phân tích bằng tay không?

Đừng lo lắng về việc xếp tay với nhau, đó là một ấm cá khác nhau.


1
Chỉ cần chỉ ra nhưng thẻ vector trong ngữ cảnh của nó là về đại số tuyến tính. Không phải container.
Sidar

@Sidar Hãy thoải mái chỉnh sửa các thẻ trong tương lai nếu bạn tin rằng chúng không phù hợp. Nếu bạn di chuột qua các thẻ và tùy chọn "Chỉnh sửa thẻ" bật lên (ít nhất là đối với tôi?) Và bạn chỉ có thể chỉnh sửa các thẻ mà không cần chỉnh sửa câu hỏi.
MichaelHouse

@ Byte56 Tôi có thói quen suy nghĩ kỳ lạ này, tôi không chắc mình có đúng không nên tôi thực hiện nó một cách thụ động để nhận xét ... Đó là lý do tại sao tôi không chỉnh sửa bài đăng. Có lẽ tôi đã bỏ lỡ điều gì đó trong bài viết, vì vậy tôi đang chờ phản hồi của anh ấy.
Sidar

Ngoài ra còn có một bài viết tốt đẹp ở đây đã xuất hiện trong trò chơi phát triển một vài năm trước đây: cowboyprogramming.com/2007/01/04/programming-poker-ai
celion

1
Tôi đã thực hiện một cách thú vị trong java một thời gian trước, bạn có thể tìm thấy nó ở đây: codereview.stackexchange.com/questions/10973/ . Nếu bạn tìm trong PokerHand.java, bạn sẽ tìm thấy các phương pháp để kiểm tra từng loại tay (ví dụ: isFullHouse). Chúng chỉ hoạt động nếu các thẻ được sắp xếp đầu tiên.
bughi

Câu trả lời:


20

Tôi nghĩ rằng bạn có thể tìm thấy phần lớn các ván bài xì phé bằng cách chỉ cần tạo một vài bảng có bao nhiêu lá bài trong tay có mỗi cấp bậc và bộ đồ.

Nói cách khác, tạo một thứ hạng thẻ ánh xạ mảng (số và A / J / Q / K) cho số lượng thẻ của thứ hạng đó trong tay bạn. Nếu người chơi có một cặp hoặc ba loại, sẽ có một yếu tố trong mảng này bằng 2 hoặc 3, v.v. Họ có một ngôi nhà đầy đủ nếu có một yếu tố đó là 2 và một yếu tố khác là 3 và một đường thẳng nếu có năm phần tử liên tiếp bằng 1 trong mảng này.

Tương tự như vậy, bạn có thể tạo một mảng tương tự về số lượng thẻ của mỗi bộ đồ, và sử dụng nó để phát hiện các lần xả.

Khi bạn đã phát hiện ra sự hiện diện của một bàn tay cụ thể, thật dễ dàng để quay lại và tìm các thẻ cụ thể trong tay, để làm nổi bật chúng trong UI hoặc bất cứ điều gì bạn cần làm.

Trong mã giả:

int countByRank[13] = { 0 };        // Initialize counter to zero for each rank
for (cards in hand)
    countByRank[card.rank] += 1;    // Increment counter for this card's rank
if (countByRank.find(2))
    // There's a pair
else if (countByRank.find(3))
    // There's a three-of-a-kind
// etc...

17

Đó là một chút khó khăn vì có rất nhiều sự kết hợp. May mắn thay, bạn có một bộ xử lý có thể kiểm tra một số lượng lớn các kết hợp trong một thời gian rất ngắn.

Bạn sẽ cần một vài chiến lược khác nhau, để phát hiện các loại tay khác nhau. May mắn thay, một vài trong số các loại khác nhau có thể chồng chéo các chiến lược. Tôi sẽ tìm kiếm thông qua, theo thứ tự của bàn tay.

  1. Thẳng tuôn
  2. Bốn của một loại
  3. Ngôi nhà hạnh phúc
  4. Tuôn ra
  5. Thẳng
  6. Ba của một loại
  7. Hai cặp
  8. Một cặp
  9. Thẻ cao

2, 3, 6, 7, 8Đều đếm đơn giản. Sử dụng danh sách các thẻ Ace to King, chỉ cần đặt số lượng của từng giá trị trong danh sách, tăng dần cho mỗi thẻ bổ sung được tìm thấy. Sau đó kiểm tra danh sách cho 4s, nếu không có 4s, bạn không có 4 loại. Kiểm tra nó trong 3 giây, nếu không có 3 giây, bạn không có 3 loại. Nếu bạn có số 3, hãy kiểm tra số 2 (biểu thị toàn nhà). Và cứ thế ...

Đối với 1, 5bạn có thể sử dụng cùng một danh sách và tìm kiếm các chuỗi trong đó tất cả các thẻ có một hoặc nhiều mục trong danh sách cho một chuỗi gồm 5 thẻ. Nếu họ cũng có bộ đồ tương tự, thì đó là một cú lộn thẳng.

4có thể có cùng một thiết lập danh sách nhưng lần này bạn đang đếm bộ đồ. Hãy tìm số từ 5 trở lên.

Cuối cùng, 9bạn có thẻ cao nhất, đó là một vấn đề đơn giản để xem giá trị cao nhất cuối cùng từ một trong các danh sách của bạn ở trên.

Bạn có thể thoát ra khi bạn tìm thấy một trận đấu nếu bạn tìm kiếm theo thứ tự. Mặc dù việc tiếp tục tìm kiếm và tìm tất cả các kết quả trùng khớp sẽ rất tầm thường nếu bạn muốn cung cấp tất cả thông tin đó cho người dùng.


Về cơ bản, bạn đang đổ đầy xô. Sau đó kiểm tra các thùng cho sự kết hợp. Để minh họa:

nhập mô tả hình ảnh ở đây

Bắt đầu với một mảng, với một thùng cho mỗi thẻ, lặp qua các thẻ và đếm số thể hiện của mỗi thẻ. Sau đó, bạn có thể dễ dàng lặp lại mảng và kiểm tra các kết hợp nhất định. Trong ví dụ này, rõ ràng có 4 loại vì một trong các thùng có 4 vật phẩm trong đó.


6

Tôi đã va vào thuật toán này một lần. Nó nhân số nguyên tố để xác định tay và là một cách đọc rất thú vị. Công cụ đánh giá bài xì phé của Cactus Kev


1
Đó là một điều thú vị, nhưng tôi không chắc bạn đã đọc tất cả. Thuật toán đó dành cho 5 thẻ . Bạn có thể đã tìm thấy trong một tìm kiếm Google liên quan đến 7 thẻ, vì tác giả nói rằng họ có thuật toán cho 7 thẻ, nhưng không chia sẻ nó. Xem văn bản màu xám gần đầu trang. Vì vậy, tôi không chắc thuật toán đó hữu ích như thế nào đối với bộ 7 thẻ.
MichaelHouse

1
Vì chỉ có 21 tay 5 thẻ khác nhau có thể được tạo từ một tay 7 thẻ, nên sử dụng một bộ đánh giá 5 thẻ trên mỗi thẻ, và chọn loại tốt nhất.
Adam

@ Byte56 Bạn nói đúng, tôi nhớ tôi đã sử dụng nó tới 7 thẻ nhưng phải xác định trước 5 thẻ tốt nhất, loại nào làm giảm hiệu quả.
petervaz

Liên kết về câu trả lời này đã bị rách nát và tên miền được chọn bởi một người gửi thư rác. Tôi đã chuyển hướng liên kết đến một kho lưu trữ của trang gốc, nhưng để làm cho câu trả lời này mạnh mẽ hơn, thật lý tưởng để chỉnh sửa câu trả lời để bao gồm một bản tóm tắt thuật toán được đề xuất trong chính nội dung của câu trả lời.
DMGregory

2

Để bổ sung cho các câu trả lời xuất sắc mà câu hỏi này đã nhận được, tôi nghĩ sẽ hữu ích khi đưa ra một trong những cách so sánh đơn giản nhất một khi kỹ thuật phân loại cơ bản được áp dụng. Trước hết, bạn sẽ muốn gắn thẻ tay với họ lớp , vì nhiều câu trả lời đã được đề xuất - hầu hết các so sánh của bạn về 'là tay X tốt hơn tay Y?' sau đó có thể được thực hiện chỉ bằng cách so sánh các lớp của hai bàn tay và xem lớp nào tốt hơn. Đối với phần còn lại, bạn thực sự sẽ cần so sánh trên cơ sở từng thẻ, và hóa ra rằng một chút công việc hơn trong phân loại sẽ làm cho việc này dễ dàng hơn.

Như trường hợp cơ bản, hãy xem xét tình huống cả hai tay đều là tay 'thẻ cao'; trong trường hợp này, trước tiên bạn so sánh hai thẻ cao nhất, sau đó (nếu chúng khớp) hai thẻ tiếp theo, v.v. Nếu bạn giả sử rằng mỗi tay đầu vào được sắp xếp từ thẻ cao nhất đến thấp nhất, cách tiếp cận này dẫn đến mã giống như điều này:

int CompareHandsOfSameClass(Hand h1, Hand h2) {
  for ( int i = 0; i < 5; i++ ) {
    if ( h1[i].rank > h2[i].rank ) {
      return -1;
    } else if ( h1[i].rank < h2[i].rank ) {
      return 1;
    }
  }
  return 0;
}

Bây giờ, tin tốt: hóa ra là thứ tự từ điển này , được điều chỉnh phù hợp, hoạt động để so sánh hai bàn tay trong bất kỳcủa các lớp, miễn là lớp của họ là như nhau. Chẳng hạn, vì cách so sánh các cặp là so sánh các cặp trước, sau đó là ba thẻ còn lại, bạn có thể sắp xếp bàn tay của mình để đặt cặp trước (hoặc thậm chí một thẻ của cặp trước!) Và chạy cùng so sánh này. (Vì vậy, ví dụ, một bàn tay như A9772 sẽ được lưu trữ dưới dạng 77A92 hoặc tốt hơn là 7A927; tay A9972 sẽ được lưu trữ là 9A729 và so sánh với mã trên mà bạn bắt đầu bằng cách đặt 7 so với 9 và tìm thấy A9972 đã thắng). Một tay của hai cặp sẽ được lưu trữ với mức cao hơn của hai cặp trước, sau đó thấp hơn, sau đó là 'kicker' (vì vậy, ví dụ, A9977 sẽ lưu trữ là 97A97); ba trong số một loại sẽ được lưu trữ với một thẻ của ba người đầu tiên, sau đó là người đá, sau đó là các thẻ khác (ví dụ: A7772 sẽ là 7A277); một ngôi nhà đầy đủ sẽ được lưu trữ với một trong ba và sau đó một trong hai (ví dụ: 99777 sẽ được lưu trữ là 79779); và cả căng thẳng và xả nước đều có thể được lưu trữ theo thứ tự 'từ điển trực tiếp' vì cả hai đều được so sánh giống như tay bài cao. Điều này dẫn đến một hàm so sánh bên ngoài đơn giản, hoạt động cho tất cả các lớp tay với chức năng đã cho:

// Compare two hands, returning -1/0/+1 as hand 1 is less than, equal to,
// or greater than hand 2. Note that this function assumes the hands have
// already been classified and sorted!
int CompareHands(Hand h1, Hand h2) {
  if ( h1.handClass > h2.handClass ) {
    return -1;
  } else if ( h1.handClass < h2.handClass ) {
    return 1;
  } else {
    return CompareHandsOfSameClass(h1, h2);
  }
}

Hy vọng điều này sẽ có ích


1

Có một số song song có thể sử dụng biểu diễn thẻ phù hợp và xoay vòng bit. Ví dụ, mã Java này đánh giá độ cứng 7 thẻ trả về một số nguyên có thể được sử dụng để so sánh hai tay. Nó có thể được điều chỉnh để báo cáo loại tay theo cách thân thiện hơn. Các ý tưởng cốt lõi đến từ trang của Cactus Kev được tham chiếu trong một câu trả lời trước đó.

Nếu bạn chỉ quan tâm đến việc triển khai có thể để đặt tên cho bàn tay bằng nhiều ngôn ngữ khác nhau hơn là hiệu quả và sự rõ ràng về mã, bạn cũng có thể xem thử thách Đặt tên bài xì phé trên codegolf.SE.


1

Đầu tiên, bạn cần biết thứ hạng và bộ đồ của tất cả các thẻ; tầm thường nhưng cần thiết

Sau đó, quay qua 7 thẻ này và tạo hai biểu đồ; lần lượt theo thứ hạng (sử dụng một mảng có 13 chỉ mục, tất cả được khởi tạo thành 0 và tăng thêm 1 nếu và khi tìm thấy một lá bài trong tay với thứ hạng đó) và một bằng cách phù hợp (sử dụng một mảng gồm bốn yếu tố được xây dựng tương tự như xếp hạng) . Đây là các hoạt động tuyến tính và bạn có thể thực hiện cả hai thao tác cho mỗi thẻ chỉ với một bộ giao dịch.

Sau đó, bạn có thể xác định liệu có bất kỳ bàn tay nào sau đây tồn tại hay không bằng cách kiểm tra từng biểu đồ cho các thùng phù hợp với tiêu chí và / hoặc thử nghiệm theo dõi đơn giản:

  • Cặp: Có chính xác một thùng xếp hạng có giá trị chính xác là 2, không có nhóm nào khác có giá trị trên 1 và không có tuôn ra?
  • Hai cặp: Hai thùng xếp hạng trở lên có giá trị chính xác là 2, không có thùng nào có nhiều hơn 2 và không có xô? (rõ ràng ba cặp không phải là một tay, nhưng đó là khả năng được đưa ra bảy thẻ; hai cặp mạnh nhất là tay của người chơi)
  • TOAK: Có chính xác một thùng có giá trị chính xác là 3, không có thùng nào khác có giá trị lớn hơn 1 và không xả?
  • Thẳng: Có năm thùng xếp hạng liên tiếp có giá trị từ 1 trở lên mà không xả? (Đừng quên rằng Aces đều cao và thấp; bạn có thể sử dụng biểu đồ xếp hạng gồm 14 yếu tố và đếm Aces trong hai nhóm nếu bạn muốn)
  • Flush: Có bộ xô nào có 5 thẻ trở lên không? (nếu vậy, hãy quét tay để tìm thẻ của bộ đồ đó và chọn top 5)
  • Nhà đầy đủ: Có bất kỳ nhóm xếp hạng nào có giá trị 3 và bất kỳ nhóm nào khác có giá trị là 2 (với 7 thẻ, không thể có một ngôi nhà đầy đủ trừ khi bạn chơi với một sàn Pinochle)
  • Four of a Kind: Có ai xếp hạng có giá trị 4 không? (không nên kết hợp với nhau)
  • Straight Flush: Có cả thẳng tuôn ra được biểu thị bằng biểu đồ không? Nếu vậy, có ít nhất một thẻ trong bộ quần áo được chỉ định có thứ hạng phù hợp với từng cấp bậc được chỉ định không? .

Bạn có thể, hoàn toàn tự nhiên, kết hợp một số kiểm tra sau:

  • Có một tuôn ra?
  • Có thẳng không?
    • Nếu có cả hai, nó là một tuôn thẳng?
    • Nếu đó là một cú lộn thẳng, nó có cả Ace và King không?
  • Có bốn loại không?
  • Có bao nhiêu loại ba trong số đó? (Hai, đó là một ngôi nhà đầy đủ. Một, kiểm tra các cặp)
  • Có bao nhiêu cặp? (Với hai hoặc nhiều hơn, đó là hai cặp. Với một, nếu có ba thì đó là một ngôi nhà đầy đủ, nếu không thì đó là một cặp)
  • Không có cái nào ở trên (thẻ cao).

Về cơ bản, nếu câu trả lời cho những điều này mang lại bất kỳ bàn tay nào, hãy đặt giá trị "độ mạnh tay" kết quả thành độ mạnh của bàn tay được tìm thấy, nếu giá trị chưa cao hơn. Chẳng hạn, nếu bạn có một ngôi nhà đầy đủ, sức mạnh 7 trên 9, thì bạn cũng có ba loại một, loại 4, và một cặp, sức mạnh 2.

Có một vài phím tắt và outs nhanh, nhưng tổng thể nó không thực sự tốn kém để chỉ chạy tất cả các kiểm tra.


0

Bạn có thể chơi bài poker tương đối dễ dàng với cách tiếp cận lặp đơn giản.

Đối với mỗi thẻ, kiểm tra xem có một hoặc hai hoặc ba người khác có cùng khuôn mặt để kiểm tra cặp hoặc ba / bốn loại không.

Nhà đầy đủ cũng tương tự. Hoặc nếu bạn tìm thấy cả một cặp và ba loại không giống nhau, hãy gắn cờ một ngôi nhà đầy đủ như tìm thấy.

Đối với các lần xả, kiểm tra từng bộ quần áo để xem nếu có năm bộ đồ giống nhau.

Kiểm tra thẳng là dễ dàng, ngay cả khi chưa được sắp xếp. Đối với mỗi thẻ, kiểm tra xem có thẻ nào cao hơn không, và lặp lại cho đến khi tìm thấy năm thẻ liên tiếp.

Royal tuôn ra và tuôn thẳng có thể được tìm thấy tương tự như căng thẳng. Hoàng gia có một số điều kiện bổ sung trong đó thẻ có giá trị thấp hơn có thể được bỏ qua.

Vâng, cách tiếp cận này không hiệu quả, nhưng đối với hầu hết các trò chơi poker, điều đó không liên quan. Bạn đang kiểm tra một số ít người chơi cứ sau nửa phút, không kiểm tra hàng nghìn tay mỗi giây.

Các phương thức tốt hơn tồn tại nhưng có thể mất nhiều thời gian hơn để viết mã và bạn có thể có nhiều thứ quan trọng hơn để dành thời gian / tiền bạc cho điều đó sẽ tạo ra một trò chơi tốt hơn từ quan điểm của người chơi bên cạnh sự thông minh và hiệu quả của thuật toán.


0

một cách đơn giản để tìm cặp, cặp đôi, toaks, nhà đầy đủ, pokers, v.v ... như sau:

so sánh từng thẻ với nhau trong một vòng lặp lồng nhau như thế này:

int matches=0;
for (int i=0;i<5;i++)
   for (int j=0;j<5;j++)
      if (i!=j && cardvalue(card[j])==cardvalue(card[i])) matches++;

các trận đấu sẽ diễn ra như sau:
2 cho một cặp
4 cho hai cặp
6 cho toak
8 cho một nhà đầy đủ
12 cho một ván bài

để tăng tốc độ tối ưu hóa điều này: không cần thiết phải chạy vòng lặp j lên đến 5, nó có thể được chạy tới i-1. sau đó có thể xóa so sánh "i! = j", các giá trị cho khớp được giảm một nửa (1 = cặp, 2 = 2 cặp, v.v.)

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.