Bước tiếp theo của bạn là gì?


18

Thử thách này là viết một hàm minimax bằng ngôn ngữ bạn chọn, để tạo ra bước đi tốt nhất tiếp theo trong trò chơi NxN của tic-tac-toe với trạng thái bảng hiện tại . Đầu vào bảng có thể được chấp nhận dưới dạng Ma trận, Bộ sưu tập 2D hoặc bất kỳ thứ gì khác có ý nghĩa với bạn, nhưng tuân thủ các quy tắc . Đầu ra là bước đi tốt nhất tiếp theo cho bất cứ ai hiện tại , nơi X được coi là đã bắt đầu .

Bối cảnh nhanh về thuật toán Minimax

Ý tưởng cơ bản của thuật toán minimax là liệt kê tất cả các kết quả có thể xảy ra như một DAG sau đó cân nhắc chúng bằng lợi ích mà chuỗi di chuyển mang lại cho người chơi, được chốt bởi bước di chuyển đầu tiên được thực hiện. Tất cả các kết quả có thể xảy ra sau đó là 'xô' bởi nước đi đầu tiên và được tính dựa trên tổng của tất cả các kết quả (-1 cho một trận thua, 0 cho hòa và 1 cho một chiến thắng). Trong các triển khai yêu cầu nhiều người chơi để chơi, bạn liệt kê tất cả các động tác có thể có của người chơi và tất cả các phản ứng có thể có của đối thủ. Chẳng hạn, trong một trò chơi tic-tac-toe (sau lần di chuyển đầu tiên), có 8 động tác đầu tiên có thể bạn có thể thực hiện, và tất cả chúng có vẻ như bằng nhau khi chỉ phân tích lượt tiếp theo. Nhưng bằng cách lặp qua tất cả các kết quả có thể có cho từng nhóm di chuyển có thể dẫn đến kết quả cuối cùng và tổng hợp tất cả chúng,

Để biết tóm tắt tốt hơn, sâu hơn và theo ngữ cảnh của thuật toán mini-max về mặt tic-tac-toe, hãy đọc thêm tại đây: http://neverstopbuilding.com/minimax

XKCD (Chỉ giải pháp 3x3)

Tất cả các động thái có thể cho một trò chơi 3x3 của tic-tac-toe.

Những quy định

  • Bất kỳ ngôn ngữ nào cũng có thể được sử dụng, nhưng không cho phép các thư viện minimax bên ngoài.
  • Đầu ra có thể là tọa độ (0-n, 0-n) hoặc số (1-n * n) cho thấy bước tiếp theo tốt nhất.
    • Ngoài ra, bạn phải có khả năng xác định khi nào tình huống tốt nhất là thua hoặc hòa thay vì thắng.
    • Cách bạn biểu thị một sự mất mát hoặc một sự ràng buộc là, một lần nữa, tùy thuộc vào bạn.
  • Đầu vào phải sử dụng X và O truyền thống và bạn phải giả sử X di chuyển trước; không gian trống có thể được đại diện bởi bất cứ điều gì.
  • Bạn có thể cho rằng bất kỳ đầu vào nào vào chương trình của bạn đều có n O và n + 1 X, nói cách khác, bạn có thể cho rằng bạn đang nhận được một bảng mạch tốt.
  • Trạng thái hiện tại của bảng phải là đầu vào duy nhất cho chương trình của bạn, nếu bạn đang sử dụng đệ quy, các phương thức trợ giúp phải được thực hiện để tạo thuận lợi cho các yêu cầu đầu vào. Xem /codegolf//a/92851/59376 để được làm rõ.
  • Mọi giá trị 10> = n> = 1 phải được hỗ trợ; nếu chương trình của bạn "hết thời gian" cho n> 10, tôi cũng thấy điều này có thể chấp nhận được, vì một số ngôn ngữ có sức mạnh xử lý thấp hơn đáng kể (Đặc biệt là sử dụng bảng điều khiển đối diện web).

Đánh giá

  • Đây là môn đánh gôn, do đó, số byte thấp nhất của chương trình sẽ thắng và các sơ hở tiêu chuẩn không được phép.
  • Trong trường hợp hòa, chương trình hỗ trợ 'n' lớn nhất sẽ giành chiến thắng.

Ví dụ đầu vào

2x2

[[X,O]
 [-,-]]

Đầu ra: 2 hoặc [0,1] (3 hoặc [1,1] cũng có thể được cho là chính xác) (Một số dạng biểu thị vị trí, tùy ý miễn là bạn có thể dễ dàng giải thích định dạng bạn đã sử dụng)


3x3

[[X,O,X]
 [O,X,-]
 [-,-,-]]

Đầu ra: -1 (Mất)


Một lần nữa, bất kỳ định dạng đầu vào nào bạn muốn đều được cho phép, nhưng phải sử dụng X và O, các ví dụ được cung cấp không có nghĩa là hạn chế định dạng đó, chỉ để truyền cảm hứng.


Xin lỗi DJMCMayhem, tôi thực sự đã cố gắn thẻ những thứ đó nhưng tôi không thể, vì tôi là người mới ở đây.
Bạch tuộc ma thuật Urn

Tiền thưởng cũng được gỡ bỏ, không thêm gì ngoài tedium.
Bạch tuộc ma thuật Urn

Định dạng đầu ra sau đây có được phép không: một sơ đồ của vị trí bảng với mỗi khoảng trống ban đầu là một ký tự duy nhất cho biết nếu chơi ở đó dẫn đến thắng / thua / hòa (ví dụ: W, L và D)
TonMedel

1
Trong ví dụ 3x3, O sẽ thua bất kể anh ta chơi gì, nhưng bạn nói đầu ra phải là [2.1], tại sao vậy?
Dada

Chỉnh sửa, bắt tốt. Không biết tôi đang nghĩ gì, đó là ví dụ tiêu cực.
Bạch tuộc ma thuật Urn

Câu trả lời:


8

Perl, 101 98 byte

Bao gồm +4cho-0p

Chạy với đầu vào trên STDIN

tictactoe.pl
OXO
---
--X
^D

Đầu ra là cùng một sơ đồ, nhưng với mỗi lần di chuyển được cập nhật với trạng thái của nó, 1đại diện cho một chiến thắng, 2đại diện cho một trận hòa và 3đại diện cho một trận thua. Đối với trường hợp này đó sẽ là

OXO
223
21X

vì vậy 3 lần rút thăm, 1 thắng và 1 thua (Tôi sẽ cập nhật giải pháp nếu định dạng đầu ra này không được chấp nhận, nhưng mã cơ bản sẽ giữ nguyên)

tictactoe.pl:

#!/usr/bin/perl -0p
m%@{[map"O.{$_}"x"@-"."O|",1-/.(
)(.)/,@-]}Z%sx||s%-%$_="$`X$'";y/XO/OX/;do$0%eg?/1/?3:1+/2/:2

Điều này đã rất chậm và sử dụng rất nhiều bộ nhớ cho bảng 3 * 3 trống (tại sao thực sự, đệ quy không đi sâu đến thế. Phải bị rò rỉ bộ nhớ). Thêm chi phí ghi nhớ 6 byte nhưng sẽ hiệu quả hơn nhiều:

#!/usr/bin/perl -0p
$$_||=m%@{[map"O.{$_}"x"@-"."O|",1-/.(\n)(.)/,@-]}Z%sx||s%-%$_="$`X$'";y/XO/OX/;do$0%eg?/1/?3:1+/2/:2

Wow, nhìn ra rằng đó là pl và có khả năng sẽ hoàn toàn không chạy trong n = 10 với rất nhiều trống rỗng ... Bạn đã làm cả hai điều mà tôi hy vọng sẽ thấy ai đó làm. Một chuỗi đầu vào và ánh xạ kết quả cho tất cả các di chuyển, không chỉ là tốt nhất. Bravo.
Bạch tuộc ma thuật Urn

Nếu một hàm đệ quy 'rò rỉ' thì làm sao có thể ok ??? Ngôn ngữ quá cao khiến không thấy thanh ghi 32 bit trong CPU (hoặc một cái gì đó là hướng dẫn đơn giản)
RosLuP

@RosLup Rò rỉ trong bối cảnh này không nhất thiết có nghĩa là bộ nhớ bị mất không thể truy cập. Perl khá đặc biệt khi giải phóng bộ nhớ, thường làm việc này muộn hơn bạn mong đợi và do đó sử dụng nhiều bộ nhớ hơn bạn mong đợi. Nó cũng có xu hướng phân bổ nhiều hơn mức cần thiết trực tiếp với kỳ vọng rằng bạn sẽ phát triển cơ sở dữ liệu của mình. Trong trường hợp này, sử dụng đệ quy "bình thường" với một hàm thay vì lạm dụng do$0sẽ sử dụng bộ nhớ ít hơn 10 lần. Nhắc bạn, trường hợp này cực kỳ nghiêm trọng, nó thực sự có thể là một rò rỉ bộ nhớ thực.
TonMedel

Không chỉ một người không nhìn thấy các thanh ghi hoặc các hướng dẫn cơ sở (từ các hướng dẫn hlls) mà còn mất quyền kiểm soát sử dụng bộ nhớ ... Đối với tôi, chúng không mở rộng ...
RosLuP

Đã đủ lâu rồi, bạn thắng người đàn ông của tôi, thật buồn khi chúng tôi không có nhiều nỗ lực hơn.
Bạch tuộc ma thuật Urn

2

Javascript (ES6), 320 294 byte

(b,p,d,M,S=-2)=>(T=(p,q,r,s)=>b[p][q]==(n=b[r][s|0])&&n!='-',w=0,b.map((r,y)=>(l=r.length-1,m=15,r.map((c,x)=>(m&=8*T(l-x,x,l)+4*T(x,x,0)+2*T(x,y,0,y)+T(y,x,y))),w|=m)),w?-1:(b.map((r,y)=>r.map((c,x)=>S<1&&c=='-'&&(r[x]='O.X'[p+1],(s=-f(b,-p,1))>S&&(S=s,M=[x,y]),r[x]=c))),S=S+2?S:0,d?S:[M,S]))

Đầu vào

1) Một mảng các ký tự mô tả bảng hiện tại, chẳng hạn như:

[['X', '-'], ['-', 'O']]

2) Một số nguyên mô tả lượt hiện tại: 1 = X, -1 =O

Đầu ra

Một mảng làm bằng:

  • một mảng mô tả di chuyển tốt nhất trong [x, y]định dạng
  • kết quả của trò chơi là một số nguyên: 1 = thắng, -1 = thua, 0 = hòa

Thí dụ

Trong ví dụ sau, Xđược đảm bảo để giành chiến thắng bằng cách chơi [1, 2].

let f =
(b,p,d,M,S=-2)=>(T=(p,q,r,s)=>b[p][q]==(n=b[r][s|0])&&n!='-',w=0,b.map((r,y)=>(l=r.length-1,m=15,r.map((c,x)=>(m&=8*T(l-x,x,l)+4*T(x,x,0)+2*T(x,y,0,y)+T(y,x,y))),w|=m)),w?-1:(b.map((r,y)=>r.map((c,x)=>S<1&&c=='-'&&(r[x]='O.X'[p+1],(s=-f(b,-p,1))>S&&(S=s,M=[x,y]),r[x]=c))),S=S+2?S:0,d?S:[M,S]))

console.log(JSON.stringify(f(
  [['O','X','O'],
   ['-','-','-'],
   ['-','-','X']],
  1
)));

MỘT TRÒ CHƠI CHIẾN LƯỢC. CUỘC CHIẾN THẮNG CHỈ LÀ CHƠI.
LÀM THẾ NÀO VỀ MỘT TRÒ CHƠI CỦA NICE?


Tốt lắm, đầu vào tốt. Chỉ nhận xét tôi có khả năng lưu byte với thông tin đã cho 'X sẽ luôn di chuyển trước'. Và bạn đã thử với một bảng không 3x3;)?
Bạch tuộc ma thuật Urn

@carusocomputing - Không chắc chắn để hiểu những gì bạn có trong đầu với 'X sẽ luôn di chuyển đầu tiên'. Nó có thể được sử dụng để suy ra bên nào đang di chuyển chỉ có bảng, nhưng tính toán thực sự sẽ tốn nhiều byte hơn; Vì vậy, tôi đoán bạn đang nói về một cái gì đó khác. Có, tôi đã làm một số thử nghiệm với bảng lớn hơn một chút. Điều đó sẽ hoạt động như mong đợi miễn là ... err ... không có quá nhiều vị trí trống. :-)
Arnauld

Thử thách nói The current state of the board must be the only input to your program. Mã của bạn cần hai đầu vào, phá vỡ quy tắc này.
Dada

1
@Dada - Tôi đã tự hỏi về điều đó, nhưng tôi cho rằng màu hoạt động một phần của trạng thái của bàn cờ (giống như một vị trí cờ luôn đi kèm với màu hoạt động + en vuông thụ động + tính sẵn có của castling). Vì vậy, tôi đoán OP nên làm rõ điểm đó. (Và nếu bạn đúng, nghe có vẻ như là một khó khăn bổ sung không cần thiết, IMHO.)
Arnauld

1
Mmm .. tôi thực sự thích lời giải thích của nhà nước trong phản ứng của anh ấy. Suy nghĩ về nó, một số làn đường chỉ có thể sử dụng các chuỗi làm đầu vào, có một bảng như XXOOXO-OO sẽ khó giải mã được số lượng byte thấp mà không có thông tin bổ sung như kích thước bảng. Ill cho phép bất kỳ đầu vào bổ sung nào đóng góp vào trạng thái của hội đồng quản trị, mặc dù tôi vẫn nghĩ rằng thông tin 'giả sử X di chuyển trước' khác với 'khi được đưa ra là'. Một số ngôn ngữ sẽ lợi dụng điều đó như một giả định;).
Bạch tuộc ma thuật Urn
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.