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

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

0 0 16

Người đăng: Semi Dev

Theo Viblo Asia

Thao tác cập nhật User_Set sau khi người dùng nhập vào bước đi muốn thực hiện trên bàn cờ chỉ đơn giản là chúng ta sẽ di chuyển giá trị User_Move từ mảng Common_Set tới vị trí tương ứng trong mảng User_Set. Tuy nhiên chúng ta có lẽ sẽ muốn tạo ra một cơ chế để đảm bảo rằng sau bất kỳ thủ tục cập nhật nào thì các *_Set vẫn sẽ bổ trợ lẫn nhau, và khi gộp các *_Set lại thì chúng ta sẽ thu được chính xác vừa đủ một bộ số 1 .. 9 như mảng Common_Set ban đầu:

  • Areas_Are_Unique (App_State); - đảm bảo rằng mỗi giá trị có ý nghĩa (khác 0) là duy nhất và không bị lặp lại trong phạm vi bao gồm tất cả các *_Set.
  • Sets_Are_Complement (App_State); - đảm bảo rằng tập các giá trị có ý nghĩa trong các *_Set hoàn thiện lẫn nhau và thể hiện vừa đủ bộ số nguyên 1 .. 9.

Như vậy là trong package App_Model, ngoài các type tự định nghĩa thì chúng ta sẽ có thêm các procedureInitUpdate_User_Set, và các function hỗ trợ sau:

package App_Model is -- type ... procedure Init (App_State : out State) with Post => Areas_Are_Unique (App_State) and Sets_Are_Complement (App_State); procedure Update_User_Set (App_State : out State; User_Move : in Digit) with Post => Areas_Are_Unique (App_State) and Sets_Are_Complement (App_State); function Areas_Are_Unique (App_State : State) return Boolean; function Sets_Are_Complement (App_State : State) return Boolean; function Found (Area : Digit; Move_Set : Digit_Array) return Boolean;
end App_Model;

Found (Area, Move_Set); đã được định nghĩa trong bài trước để hỗ trợ cho thao tác kiểm tra bước đi User muốn thực hiện vẫn đang có mặt trong Common_Set. Các procedure sử dụng tham số out State có khả năng sẽ chỉnh sửa các *_Set và chúng ta có thể khai báo gắn kèm contract Post để đảm bảo rằng trong tổng bộ các *_Set không có giá trị có nghĩa nào bị lặp hay bị mất đi so với tập 1 .. 9 ban đầu.

Areas_Are_Unique;

Để đảm bảo các giá trị thể hiện các ô area là duy nhất và không bị lặp lại trong tổng bộ các *_Set thì chúng ta có thể kiểm tra để loại trừ khả năng một giá trị xuất hiện trong nhiều hơn một *_Set; Hoặc thực hiện nối nội dung các mảng concat sau đó kiểm tra tần suất xuất hiện của mỗi phần từ của tập 1 .. 9 trong mảng Concatenated.

package body App_Model is -- ... function Areas_Are_Unique (App_State : State) return Boolean is -- local Origin_Set : Digit_Array; Area : Digit; Found_Duplicated : Boolean; Result : Boolean := TRUE; begin Origin_Set := (1, 2, 3, 4, 5, 6, 7, 8, 9); -- for Index in Origin_Set'Range loop Area := Origin_Set (Index); Found_Duplicated := (Found (Area, App_State.Common_Set) and Found (Area, App_State.User_Set)) or (Found (Area, App_State.Common_Set) and Found (Area, App_State.Computer_Set)) or (Found (Area, App_State.User_Set) and Found (Area, App_State.Computer_Set)); if Found_Duplicated then Result := FALSE; end if; end loop; -- return Result; end Areas_Are_Unique; -- ...
end App_Model;

Sets_Are_Complement;

Để kiểm tra các giá trị có nghĩa trong tổng bộ các *_Set vẫn hoàn thiện đủ tập giá trị 1 .. 9 thì chúng ta có thể thực hiện sát nhập mảng merge. Thao tác gộp sẽ là một dạng ghi đè đối với các trường hợp có giá trị trùng lặp (nếu có).

package body App_Model is -- ... function Sets_Are_Complement (App_State : State) return Boolean is -- local Merged_Set : Digit_Array := (others => 0); Area : Digit := 0; Result : Boolean := TRUE; begin -- for Index in Merged_Set'Range loop Area := App_State.Common_Set (Index); if Area /= 0 then Merged_Set (Index) := Area; end if; -- Area := App_State.User_Set (Index); if Area /= 0 then Merged_Set (Index) := Area; end if; -- Area := App_State.Computer_Set (Index); if Area /= 0 then Merged_Set (Index) := Area; end if; end loop; -- for Index in Merged_Set'Range loop if Merged_Set (Index) = 0 then Result := FALSE; end if; end loop; -- return Result; end Sets_Are_Complement;
end App_Model; -- ...
end App_Model;

Update_User_Set;

Và với các contract Post đã có thì nội dung của Update_User_Set sẽ không có gì phải xử lý thêm ngoài việc chuyển giá trị tương tứng với User_Move trong Common_Set sang User_Set.

package body App_Model is -- ... procedure Update_User_Set ( App_State : out State ; User_Move : in Digit ) is -- local Index : Integer := User_Move; begin App_State.Common_Set (Index) := 0; App_State.User_Set (Index) := User_Move; end Update_User_Set; -- ...
end App_Model;

Cuối cùng là code sử dụng tại Main, chúng ta sẽ đặt thêm Put_Chess_Board; ở lượt của Computer để hiển thị kết quả hoạt động của Update_User_Set;.

with Ada.Text_IO; use Ada.Text_IO;
with App_Model; use App_Model;
with Console_IO; use Console_IO; procedure Main is User_Symbol : Symbol; App_State : State; User_Move : Digit;
begin Put_Symbol_Menu; Get (User_Symbol); Init (App_State); -- loop Put_Chess_Board (App_State, User_Symbol); Get (User_Move, App_State); Update_User_Set (App_State, User_Move); -- 6. Update_Match_Status -- Put_Chess_Board (App_State, User_Symbol); -- 8. Get_Computer_Move -- 9. Update_Computer_Set -- 10. Update_Match_Status -- -- exit when App_State.Match_Status /= PLAYING; -- end loop
end Main;
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: 0
Choice number should be in 1 .. 9
Your move: A
Choice number should be in 1 .. 9 and has not been taken.
Your move: 1
+ - - + - - + - - + | 2 | 9 | 4 |
+ - - + - - + - - +
| 7 | 5 | 3 |
+ - - + - - + - - +
| 6 | X | 8 |
+ - - + - - + - - +

(chưa đăng tải) [Procedural Programming + Ada] Bài 21 - 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 67

- 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 47

- 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 41

- 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 75

- 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 280

- 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 50