- vừa được xem lúc

[Procedural Programming + Ada] Bài 25 - Console Tic-Tac-Toe App (tiếp theo)

0 0 15

Người đăng: Semi Dev

Theo Viblo Asia

Bây giờ chúng ta sẽ bổ sung thêm logic xử lý bước đi cuối cùng cho Computer;Và với thời lượng trung bình của các bài viết mà mình đang áp dụng thì rất có thể chúng ta sẽ cần thêm vài bài viết nữa để hoàn thành procedure này kèm theo cả một phần nội dung tóm lược về những thứ đáng lưu ý nhất mà mình nghiệm thu được về Procedural Programming nhờ sự giúp đỡ của Ada.

Ở đây chúng ta sẽ nói một chút về cách tư duy xử lý trường hợp có nhiều Double_Threat ở cuối bài viết trước.

User : X
Computer : O + - - + - - + - - +
| | | X |
+ - - + - - + - - +
| | O | |
+ - - + - - + - - +
| X | | |
+ - - + - - + - - +
Computer move : 

Giả sử nếu đặt mình vào vị trí xử lý lượt đi của Computer thì chúng ta sẽ thấy rằng ở lượt tiếp theo User phía bên kia đang có cơ hội tạo Double_Threat nếu chọn ô ở góc phía trên bên trái hoặc góc phía dưới bên phải. Rõ ràng là việc chặn trực tiếp Block_Double_Threat sẽ không giải quyết được tình huống để cân bằng kết quả của ván cờ. Nếu vậy chúng ta cần tạo ra một cơ hội thắng trực tiếp Direct_Chance để buộc phía User phải ưu tiên việc chặn lại thay vì tạo Double_Threat ở bước đi tiếp theo như họ dự tính.

Chúng ta có thể sẽ có nhiều lựa chọn ở bước đi tiếp theo để khởi tạo cơ hội thắng trực tiếp với bất kỳ ô trống nào có khả năng kết hợp với các ô đã đánh dấu O để tạo ra đường thẳng gần hoàn thiện. Tuy nhiên, mục tiêu của chúng ta trong trường hợp này không chỉ đơn thuần là tạo ra Direct_Chance mà là khiến cho User phải chọn vào Direct_Chance để chặn và chệch hướng khỏi các bước đi tạo Double_Threat. Và điều đó có nghĩa là khi chọn ra một giá trị Direct_Chance cho Computer thì chúng ta phải loại trừ trường hợp giá trị này cũng đồng thời có mặt trong tập Double_Threat từ phía User.

Vậy chúng ta sẽ gọi bước đi tiên đoán để khởi tạo cơ hội là Direct_Chance_Init, và bước đi thắng cuộc mà User cần phải chặn là Direct_Chance. Và những procedure hỗ trợ mà chúng ta cần có là:

  • Get_Double_Threats; - Tiên đoán tập giá trị các bước đi mà User có thể đang hướng tới để tạo Double_Threat.
  • Get_Direct_Chance_Inits; - Tiên đoán tập giá trị các bước đi sẽ khởi tạo cơ hội thắng cuộc trực tiếp cho Computer.
  • Get_Direct_Chance; - Tiên đoán bước đi sẽ hoàn thành đường thẳng thắng cuộc của Computer tương ứng với bước đi đã tiên đoán trước đó và đồng thời đây cũng chính là bước đi mà Computer cần phải chọn vào để chặn lại.

Và tệp khai báo cấu hình của package AI_Mockup sẽ có danh sách đầy đủ với các sub-program mới đang tạm thời được -- comment như sau:

with App_Model; use App_Model; package AI_Mockup is procedure Get (Computer_Move : out Digit; App_State : in State); procedure Get_Prioritized (Computer_Move : out Digit; App_State : in State); procedure Block_Direct_Winning (Computer_Move : in out Digit; App_State : in State); procedure Block_Double_Threat (Computer_Move : in out Digit; App_State : in State); -- procedure Redirect_User_Concern (Computer_Move : in out Digit; App_State : in State); -- procedure Get_Double_Threats (User_Moves : in out Digit_Array; App_State : in State); -- procedure Get_Direct_Chance_Inits (Computer_Moves : in out Digit_Array; App_State : in State); -- procedure Get_Direct_Chance (Computer_Move : in out Digit; App_State : in State); function Count_Direct_Threats (App_State : State) return Integer; -- function Count_Double_Threats (App_State : State) -- return Integer; -- function Count_Direct_Chances (App_State : State) -- return Integer;
end AI_Mockup;

Chúng ta sẽ bắt đầu với dòng code bổ sung logic cho procedure Get (Computer_Move) và bỏ dần -- comment để viết code cho từng procedure hỗ trợ đang dự kiến. Logic xử lý mới bổ sung có tên gọi là Redirect_User_Concern; và có mức ưu tiên cao hơn so với Block_Double_Threat và thấp hơn so với Block_Direct_Winning.

with Ada.Text_IO; use Ada.Text_IO; package body AI_Mockup is procedure Get ( Computer_Move : out Digit ; App_State : in State ) is begin Get_Prioritized (Computer_Move, App_State); Block_Double_Threat (Computer_Move, App_State); Redirect_User_Concern (Computer_Move, App_State); -- new Block_Direct_Winning (Computer_Move, App_State); -- Put_Line ("Computer move:" & Digit'Image (Computer_Move)); end Get; -- ... end AI_Mockup;

Và ở đây chúng ta đang dự kiến rằng Redirect_User_Concern; sẽ chỉ thực sự hoạt động khi nhìn thấy nhiều Double_Threat, bởi nếu chỉ thấy một Double_Threat duy nhất thì chúng ta đã có kết quả mong muốn ở dòng gọi Block_Double_Threat; ngay trước đó rồi. Như vậy chúng ta sẽ cần tạo ra thao tác hỗ trợ để đếm số lượng Count_Double_Threats trước khi quyết định chạy logic xử lý tình huống.

with Ada.Text_IO; use Ada.Text_IO; package body AI_Mockup is -- ... procedure Redirect_User_Concern ( Computer_Move : in out Digit ; App_State : in State ) is begin if Count_Double_Threats (App_State) > 1 then Put_Line ("Double_Threats : " & Integer'Image (Count_Double_Threats (App_State))); end if; end Redirect_User_Concern; -- ... -- function Count_Direct_Threats ... function Count_Double_Threats (App_State : State) return Integer is -- local Foreseen_User_Move : Digit := 0; Foreseen_App_State : State; Counter : Integer := 0; begin for Index in App_State.Common_Set'Range loop if App_State.Common_Set (Index) /= 0 then Copy (Foreseen_App_State, App_State); Foreseen_User_Move := App_State.Common_Set (Index); Update_User_Set (Foreseen_App_State, Foreseen_User_Move); -- if Count_Direct_Threats (Foreseen_App_State) > 1 then Counter := Counter + 1; end if; end if; end loop; -- return Counter; end Count_Double_Threats; end AI_Mockup;

Ở đây chúng ta xem như bước đi tiếp theo của User có thể là bất kỳ ô trống nào đang còn lại trên bàn cờ hiện tại bởi vì chúng ta chưa chọn cố định bước đi cho Computer. Và như vậy sẽ cần lặp qua mỗi giá trị có ý nghĩa của Common_Set với giả định là sẽ được User chọn để tạo ra các phiên bản tiên đoán Forseen_App_State. Sau đó với trường hợp nào mà chúng ta tìm thấy số lượng nguy cơ trực tiếp Count_Direct_Threats là số nhiều thì chúng ta tăng biến đếm số lượng lên một đơn vị.

Bây giờ chúng ta cần kiểm tra lại trường hợp ván cờ ở đầu bài viết, User đang có các khả năng tạo ra Double_Threat ở các ô trống góc phía trên bên trái và góc phía dưới bên phải.

alr run Choose your Symbol ... 1. Letter 'X' 2. Letter 'O'
Your choice: 1
You've chosen: X + - - + - - + - - +
| 2 | 9 | 4 |
+ - - + - - + - - +
| 7 | 5 | 3 |
+ - - + - - + - - +
| 6 | 1 | 8 |
+ - - + - - + - - +
Your move: 6 PLAYING ...
+ - - + - - + - - +
| 2 | 9 | 4 |
+ - - + - - + - - +
| 7 | 5 | 3 |
+ - - + - - + - - +
| X | 1 | 8 |
+ - - + - - + - - +
Computer move: 5 PLAYING ...
+ - - + - - + - - +
| 2 | 9 | 4 |
+ - - + - - + - - +
| 7 | O | 3 |
+ - - + - - + - - +
| X | 1 | 8 |
+ - - + - - + - - +
Your move: 4 PLAYING ...
+ - - + - - + - - + + - - + - - + - - +
| 2 | 9 | X | => | ? | | X |
+ - - + - - + - - + + - - + - - + - - +
| 7 | O | 3 | => | | O | |
+ - - + - - + - - + + - - + - - + - - +
| X | 1 | 8 | => | X | | ? |
+ - - + - - + - - + + - - + - - + - - +
Double_Threats : 2
Computer move: _

Và một tình huống khác khi User đi trước ở ô trống trung tâm với nhiều khả năng tạo Double_Threat hơn.

alr run Choose your Symbol ... 1. Letter 'X' 2. Letter 'O'
Your choice: 1
You've chosen: X + - - + - - + - - +
| 2 | 9 | 4 |
+ - - + - - + - - +
| 7 | 5 | 3 |
+ - - + - - + - - +
| 6 | 1 | 8 |
+ - - + - - + - - +
Your move: 5 PLAYING ...
+ - - + - - + - - +
| 2 | 9 | 4 |
+ - - + - - + - - +
| 7 | X | 3 |
+ - - + - - + - - +
| 6 | 1 | 8 |
+ - - + - - + - - +
Computer move: 2 PLAYING ...
+ - - + - - + - - +
| O | 9 | 4 |
+ - - + - - + - - +
| 7 | X | 3 |
+ - - + - - + - - +
| 6 | 1 | 8 |
+ - - + - - + - - +
Your move: 8 PLAYING ...
+ - - + - - + - - + + - - + - - + - - +
| O | 9 | 4 | => | O | | ? |
+ - - + - - + - - + + - - + - - + - - +
| 7 | X | 3 | => | | X | ? |
+ - - + - - + - - + + - - + - - + - - +
| 6 | 1 | X | => | ? | ? | X |
+ - - + - - + - - + + - - + - - + - - +
Double_Threats : 4
Computer move: _

[Procedural Programming + Ada] Bài 26 - Console Tic-Tac-Toe App (tiếp theo)

Bình luận

Bài viết tương tự

- vừa được xem lúc

Closure trong Javascript - Phần 2: Định nghĩa và cách dùng

Các bạn có thể đọc qua phần 1 ở đây. Để mọi người không quên, mình xin tóm tắt gọn lại khái niệm lexical environment:.

0 0 51

- vừa được xem lúc

Var vs let vs const? Các cách khai báo biến và hằng trong Javascript

Dạo này mình tập tành học Javascript, thấy có 2 cách khai báo biến khác nhau nên đã tìm tòi sự khác biệt. Nay xin đăng lên đây để mọi người đọc xong hy vọng phân biệt được giữa let và var, và sau đó là khai báo hằng bằng const.

0 0 31

- vừa được xem lúc

VueJS: Tính năng Mixins

Chào mọi người, hôm nay mình sẽ viết về Mixins và 1 số vấn đề trong sử dụng Mixins hay ho mà mình gặp trong dự án thực. Trích dẫn từ trang chủ của VueJS:.

0 0 27

- vừa được xem lúc

Asset Pipeline là cái chi chi?

Asset Pipeline. Asset pipeline là cái chi chi. . Giải thích:.

0 0 47

- vừa được xem lúc

Tạo data table web app lấy dữ liệu từ Google Sheets sử dụng Apps Script

Google Sheets là công cụ tuyệt vời để lưu trữ bảng tính trực tuyến, bạn có thể truy cập bảng tính bất kỳ lúc nào ở bất kỳ đâu và luôn sẵn sàng để chia sẻ với người khác. Bài này gồm 2 phần.

0 0 266

- vừa được xem lúc

Học Deep Learning trên Coursera miễn phí

Bạn muốn bắt đầu với Deep Learning nhưng không biết bắt đầu từ đâu? Bạn muốn có một công việc ở mức fresher về Deep Learning? Bạn muốn khoe bạn bè về kiến thức Deep Learning của mình. Bắt đầu từ đâu.

0 0 35