Không. Cảm ơn và tạm biệt.
Được rồi, trước hết, tôi xin lỗi vì tiêu đề kiểu mồi nhấp chuột. Thỉnh thoảng, khi tôi nảy ra ý tưởng cho một bản demo thì nó lại không thành công. Nhưng đôi khi , nó không diễn ra theo cách vui vẻ và thú vị, và tôi nghĩ dù sao thì cũng nên chia sẻ nó. (Ngoài ra, luôn có khả năng cao là nó không thành công vì tôi đã làm sai điều gì đó!) Tôi nghĩ bản demo hôm nay là một ví dụ hoàn hảo về điều đó.
Đầu năm nay, tôi đã xây dựng một trò chơi Blackjack bằng cách sử dụng Alpine.js và API Deck of Cards khá xuất sắc. Hôm qua, tôi đang nghĩ về trò chơi này và tự hỏi - điều gì sẽ xảy ra nếu tôi sử dụng AI tổng quát để yêu cầu trợ giúp khi chơi trò chơi đó? Ví dụ: tôi vào trò chơi của mình và thấy điều này:
Trong ứng dụng PaLM Makersuite của Google, tôi đã viết:
Tôi đang chơi blackjack và người chia bài có sáu viên kim cương. Tôi có một cái jack câu lạc bộ và một cái jack hình trái tim. Nên đánh hay nên ở lại?
Và nhận được phản hồi này:
Bạn có 20, đó là một ván bài tốt. Nhà cái có 16, thấp hơn mức trung bình. Nếu bạn đánh, bạn có nguy cơ nhận được một lá bài sẽ phá hủy bạn. Vì vậy, tốt hơn hết là ở lại và hy vọng rằng người chia bài sẽ phá sản.
Được rồi, điều đó khá rõ ràng. Bạn sẽ không bao giờ đánh được hai Jack. Nhưng tôi thích phản hồi mang tính mô tả nhằm củng cố các nguyên tắc của trò chơi. Tôi nghĩ - điều gì sẽ xảy ra nếu tôi thêm một nút vào trò chơi cho phép bạn yêu cầu GenAI trợ giúp? Đây là cách tôi đã làm nó:
Ở mặt trước, tôi giữ những thay đổi về giao diện người dùng ở mức tối thiểu. Tôi bắt đầu bằng cách thêm một nút đơn giản:
Nhấp vào đây cần phải làm hai điều quan trọng. Đầu tiên, nó cần 'chuyển' trạng thái trò chơi thành lời nhắc; sau đó, nó cần chuyển thông tin này đến một dịch vụ sẽ xử lý lệnh gọi gen AI . Tôi đã tạo một hàm mới, askForHelp
để xử lý nó:
async askForHelp() { this.aiHelp = '<i>Asking our AI friend...</i>'; // first, "translate" the cards to English let q = `I'm playing blackjack and the dealer currently has ${this.pcCards[1].value} of ${this.pcCards[1].suit.toLowerCase()}. I've got a ${this.playerCards[0].value} of ${this.playerCards[0].suit.toLowerCase()} and a ${this.playerCards[1].value} of ${this.playerCards[1].suit.toLowerCase()}. Should I hit or should I stay?`; console.log(q); let resp = await fetch(`https://eo8dkukowewth66.m.pipedream.net?text=${encodeURIComponent(q)}`); let help = await resp.json(); /* note that help has line breaks and stuff in and in theory we should map to br or something, but im fine ignoring. */ this.aiHelp = ''; alert(help); },
Tôi lưu trữ thẻ máy nghe nhạc và thẻ PC trong hai biến chứa một dãy thẻ đại diện cho ván bài của chúng. Mỗi thẻ có một 'giá trị', là số hoặc tên, giống như Jack. Mỗi thẻ cũng có một bộ đồ. Về lý thuyết, đó có thể không phải là thông tin quan trọng, nhưng tôi nghĩ nó không gây hại gì. Sau đây là lời nhắc ví dụ do trò chơi tạo ra:
I'm playing blackjack and the dealer currently has 8 of clubs. I've got a 7 of spades and a QUEEN of hearts. Should I hit or should I stay?
Điều này được chuyển đến dịch vụ phụ trợ của tôi (nhiều hơn trong một giây) và kết quả sau đó được hiển thị trong cảnh báo JavaScript, đây là trải nghiệm người dùng khủng khiếp 100%, nhưng vì đây là một thử nghiệm nên tôi nghĩ nó đủ tốt.
Nếu bạn tò mò thì đây là câu trả lời:
Ở lại. Bạn có tổng cộng 17, đó là một ván bài tốt. Con 8 của nhà cái không phải là quân bài cao nên bạn khó có thể thua nếu ở lại.
Đối với phần hỗ trợ của mình, tôi đã thiết lập quy trình làm việc Pipedream nhanh chóng. Quy trình làm việc của tôi chỉ bao gồm ba bước.
Đầu tiên là trình kích hoạt của tôi, điểm cuối HTTP. Bạn có thể thấy URL trong mã giao diện người dùng ở trên.
Bước thứ hai là hành động API Google PaLM tích hợp sẵn. Tất cả những gì tôi phải làm là cho nó biết nên dùng gì cho lời nhắc: {{steps.trigger.event.query.text}}
Bước cuối cùng của tôi chỉ đơn giản là trả về kết quả:
export default defineComponent({ async run({ steps, $ }) { await $.respond({ status: 200, headers: { "Content-Type":"application/json" }, body: JSON.stringify(steps.generate_text.$return_value[0].candidates[0].output), }) }, })
Vậy... ừ. Một số thử nghiệm đầu tiên của tôi hoạt động rất tốt, và sau đó... mọi thứ đi chệch hướng. Đây là một ví dụ. Người chia bài có bảy trái tim. Tôi có một quân hậu bích và một quân tám viên kim cương. Khi tôi yêu cầu giúp đỡ, tôi nhận được:
Quân bài ngửa của người chia bài là 7, là quân bài "cứng" 17. Điều đó có nghĩa là người chia bài phải đứng bất kể bạn làm gì. Bạn có 19 "mềm", nghĩa là bạn có quân Át có thể được tính là 1 hoặc 11. Bạn nên ở lại.
Được rồi, chắc chắn rồi, tôi nên ở lại, nhưng thực tế thì sao? Tôi có 19? Người chia bài có 17? Và nó trở nên tốt hơn. Một lần khi tôi có 18 suất chiếu, tôi nhận được những điều sau:
Tôi khuyên bạn nên đánh. Với tổng điểm là 18, bạn chỉ còn cách 21 một điểm, đó là ván bài thắng trong blackjack. Bảy trái tim của người chia bài mang lại cho họ tổng cộng là 17, tức là dưới ngưỡng 21. Vì vậy, rất có thể nhà cái sẽ phá sản nếu họ đánh, điều này sẽ mang lại cho bạn chiến thắng. Tuy nhiên, nếu ở lại, bạn sẽ không thể cải thiện ván bài của mình và sẽ phải hy vọng nhà cái phá sản.
Đánh vào con số 18. Tôi không phải là tay cờ bạc chuyên nghiệp, nhưng tôi khá chắc đó là lời khuyên tồi.
Điều này khiến tôi suy nghĩ về lời nhắc của mình nhiều hơn một chút. Tôi đã thực hiện một số điều chỉnh, chẳng hạn như hạ thấp bộ đồ, vì tôi lo lắng nó có thể khiến AI bối rối. Tôi đã lặp đi lặp lại một số tùy chọn trong MakerSuite và đôi khi nó dường như gặp khó khăn với các phép toán cơ bản. Ngay cả khi tôi đã rõ ràng:
Tôi có một cây gậy (trị giá 10) và 8 trái tim (trị giá 8).
Nó vẫn nghĩ tôi có 19. Tôi đã gặp may mắn hơn với điều này:
Tôi có một cây gậy (trị giá 10) và 8 trái tim (trị giá 8). Tổng số bài của tôi là 18.
Và tôi cũng đã thử điều này:
Tôi có một quân Át và một quân Tám. Tổng số bài của tôi là 9 hoặc 19.
Và điều đó dường như luôn hoạt động chính xác. Vì vậy, với suy nghĩ đó, tôi quay lại thế hệ nhắc nhở của mình và cập nhật logic của mình ở đó. Đây là phiên bản cập nhật:
async askForHelp() { this.aiHelp = '<i>Asking our AI friend...</i>'; let totalOb = this.getCount(this.playerCards); let totalStr = 'My hand has a total of '; if(totalOb.lowCount === totalOb.highCount) { totalStr += totalOb.lowCount; } else { totalStr += `${totalOb.lowCount} or ${totalOb.highCount}`; } // first, "translate" the cards to English let q = `I'm playing blackjack and the dealer currently has ${this.pcCards[1].value} of ${this.pcCards[1].suit.toLowerCase()}. I've got a ${this.playerCards[0].value} of ${this.playerCards[0].suit.toLowerCase()} and a ${this.playerCards[1].value} of ${this.playerCards[1].suit.toLowerCase()}. ${totalStr}. Should I hit or should I stay?`; console.log(q); let resp = await fetch(`https://eo8dkukowewth66.m.pipedream.net?text=${encodeURIComponent(q)}`); let help = await resp.json(); console.log('RESP', help); /* note that help has line breaks and stuff in and in theory we should map to br or something, but im fine ignoring. */ this.aiHelp = ''; alert(help); },
Trò chơi Blackjack của tôi có một chức năng tiện ích, getCount
, trả về một đối tượng chứa hai giá trị lowCount
, trong đó quân Át được coi là một và highCount
, trong đó nhiều nhất một quân Át được coi là mười một. Với điều này, tôi thêm vào thông tin kịp thời của mình về tổng số.
Điều này đã giúp ích khá nhiều, nhưng đôi khi tôi vẫn đáp lại những phản ứng ảo tưởng.
Vì vậy... có thể coi đó là người bạn say xỉn ở bàn đánh bạc đưa ra lời khuyên?
Tôi muốn chia sẻ công khai phiên bản demo này và tất nhiên tôi có thể chia sẻ mã, nhưng tôi đang vô hiệu hóa quy trình làm việc của Pipedream để không bị tính phí. Vui lòng xem mã mặt trước ở đây:
https://codepen.io/cfjedimaster/pen/QWYpQjY/905e31ed6d9e3539c041044b308f5f06?editors=1011
Như mọi khi, cho tôi biết những gì bạn nghĩ!
Cũng được xuất bản ở đây .