Kỹ thuật bảng phương án cho các bài toán trò chơi
Lưu Anh Tuấn
Trong lĩnh vực trò chơi, ngày nay máy tính đã có một số ưu thế so với con người. Đó là tốc
độ tính toán cực nhanh và khả năng lưu trữ các cấu hình trò chơi rất lớn. Rõ ràng máy tính
có thể phân tích và ghi nhớ các thế của trò chơi với tốc độ vượt xa con người.
Hơn nữa, lĩnh vực khoa học máy tính ngày càng phát triển những kỹ thuật tiên tiến để trợ
giúp cho khả năng “suy nghĩ” của máy tính. Một trong các kỹ thuật đó là kỹ thuật “bảng
phương án”.
Vậy kỹ thuật bảng phương án là gì? Đó là kỹ thuật dùng để tính toán và lưu trữ tất cả các
khả năng tốt nhất có thể có của mỗi cấu hình của trò chơi. Ta có thể coi đó như là một từ
điển giúp máy tính có thể có quyết định tốt nhất tại mỗi thế của trò chơi. Và ta cũng có thể
nhận ra một điều rằng, kỹ thuật này đòi hỏi một sự tính toán rất lớn và đòi hỏi phải lưu trữ
rất nhiều, nhiều khi là thừa thãi. Hạn chế này làm cho kỹ thuật bảng phương án không thể
áp dụng cho những trò chơi có không gian lớn như các trò chơi cờ tướng, cờ vua... Tuy
nhiên đối với những bài toán có không gian nhỏ thì kỹ thuật này tỏ ra rất hữu hiệu.
Ta xét một trò chơi đơn giản sau:
Trò chơi thứ 1
Cho một lưới ô vuông m x n ô. Một con hậu nằm ở một ô nào đó trên lưới. Mỗi nước đi
con hậu có thể đi một trong các hướng với số ô không hạn chế. Hai đấu thủ chơi với nhau,
đến lượt ai thì người đó cho con hậu đi. Nếu không đi được nữa thì người đó thua. Hãy lập
trình cho máy chơi với người để khả năng thắng của máy là cao nhất.
Ta cũng phải giả sử rằng nếu có một thuật toán tối ưu cho trò chơi này thì các đấu thủ đều
phải biết, do đó ở đây chỉ có yêu cầu rằng khả năng thắng của máy là cao nhất có thể được,
bởi vì nếu máy đã rơi vào thế thua thì không thể làm gì hơn.
Đối với trò chơi này, ta có thể nhận thấy rằng nếu ai đưa được con hậu về đến ô dưới trái
( ô [1,1]) thì là người đó thắng. Ta sẽ đánh dấu ô đó bằng số 1. Các ô có thể đi về được ô
này thì rõ ràng là ở thế thua, do đó phải được đánh số 0. Ta được bảng như sau:
Sau đó ta lại có thể thấy rằng nếu ta đưa được con hậu về ô [3,2] hoặc ô [2,3] thì đối thủ
của ta đến lượt họ đi chắc chắn phải đưa hậu đến một trong các ô đã được đánh dấu là 0,
đó chính là thế thằng cho ta, do đó hai ô này sẽ được đánh dấu là 1. Tương tự như trên, các
ô có thể đưa hậu về hai ô này là ở thế thua sẽ được đánh dấu là 0. Cứ tiếp tục như vậy ta
được bảng như sau:
Máy tính có thể dựa trên bảng này để có thể quyết định nước đi tại mỗi vị trí của con hậu.
Nó có thể đưa hậu đến một ô được đánh số 1 nếu ô hậu đang đứng là 0. Còn nếu ô hậu
đang đứng là 1 thì rõ ràng máy tính đang ở thế thua, phải tìm một nước đi ngẫu nhiên nào
đó để chờ thời, hi vọng đối thủ sai lầm để lật lại thế cờ.
Trò chơi thứ 2
Hai đấu thủ chơi trò lật quân bài như sau: Trên bàn có 5 quân bài được đánh số từ 1 đến 5,
có một con lật ngửa còn 4 con còn lại sấp. Tổng S ban đầu được gán bằng giá trị của con
bài ngửa. Đến phiên ai, người đó lật một con bài đang úp và lật sấp con bài ngửa cũ, tổng S
được cộng với số hiệu của con bài mới lật. Sau khi ai đi mà tổng S vượt quá một số N cho
trước thì người đó thua. Hãy tìm cách đi tốt nhất.
Để giải quyết bài toán này, ta phải tính khả năng tốt nhất tại mỗi cấu hình của trò chơi, hay
nói cách khác là mỗi giá trị của tổng S. Ta sẽ đi tính bảng phương án từ giá trị N trở xuống.
Trước hết ta xây dựng một bảng hai chiều, một chiều đánh số từ 1 đến 5, một chiều đánh
số từ 1 đến N.
Nếu tổng S đang bằng N thì dù ta có lật quân bài nào đi chăng nữa cũng thua, do đó cả cột
[N] đều được đánh số 0. Ta xét các cột N-5, N-4,..., N-1 và thấy rằng nếu S đang là một
trong các giá trị đó thì nếu ta lật các quân bài 5, 4,..., 1 tương ứng thì S sẽ bằng N và ta sẽ
thắng. Do đó các ô [5,N-5], [4,N-4],..., [1,N-1] sẽ được đánh số là 1. Riêng ô [1,N-2] ta
phải điền 1, lí do là nếu S đang là N-2 mà ta lật quân bài 1 ta sẽ được tổng là N-1, nhưng
địch thủ lại không thể lật quân 1 được nữa, do đó họ lật bất kì quân bài nào cũng thua. Cứ
tiếp tục suy luận như vậy ta có bảng sau:
Đây chính là bảng phương án của trò chơi này. Đến lượt máy tính đi, máy tính sẽ tra ở cột
S, tìm ô nào có giá trị bằng 1 mà quân bài tương ứng đang úp thì sẽ lật quân bài tương ứng.
Vậy thuật toán xây dựng bảng là như thế nào. Ta thấy rằng nếu đang có tổng S, xét quân
bài i thì ta phải xem xét đến cột S+i (vì sau khi lật thì tổng mới sẽ là S = S+i). Nếu trên cột
đó, trừ ô [i,S+i] mà có một ô có giá trị là 1 thì chắc chắn ô [i,S] sẽ được gán là 0, ngược lại
sẽ được gán là 1.
Ta có thể xây dựng một đoạn chương trình đơn giản để tính bảng phương án như sau:
For j:=N downto 1 do
For i:=1 to 5 do
Begin
T:=0;
For k:=1 to 5 do T:=T+a[k,j+i];
T:=T-a[i,j+i];
If T=0 then a[i,j]:=1
Else a[i,j]:=0;
End;
Ta thấy chương trình này còn có một lỗ hổng, đó là nếu tính các cột từ N-4 đến cột N ta
phải xét đến các cột N+1 đến N+5 mà lại chưa có giá trị cho các cột này. Các bạn hãy thử
nghĩ xem ta sẽ khởi tạo giá trị gì cho các cột đó.
Trò chơi thứ 3
Hai người chơi trò lật xúc xắc như sau: có một con xúc xắc trên bàn, tổng S bằng giá trị
mặt trên cùng của con xúc xắc. Đến lượt ai thì người đó lật 1 trong bốn mặt bên của con
xúc xắc và cộng giá trị mặt trên vào tổng S. Sau lượt ai mà tổng S lớn hơn N cho trước thì
người đó thua. Hãy tìm cách chơi tốt nhất.
Các bạn hãy tự giải bài toán này nhé.
Chúc các bạn thành công.