- Tham gia
- 8/6/06
- Bài viết
- 14,606
- Được thích
- 22,927
- Nghề nghiệp
- U80
Bài I: PHẦN KHỞ ĐỘNG
Tại http:www.giaiphapexcel.comforumshowthread.php?414-Xin-gỏi-các-bạn-tham-khảo-trò-chơi-xếp-số-theo-1-trật-tự đang có file trò chơi dịch chuyển số đế xếp theo một trật tự nào đó mà bạn mong muốn hay định sẵn.
Trong hình là cảnh lúc mà ta mở file excel lên. Trên trang tính sẽ xuất hiền các ô chứa 40 số & 2 ô còn trống. Bên fía fải ta thấy thêm nút lệnh có tên là NEW. Nếu ta bấm vô nút này, các số trong bảng trên sẽ xáo trộn & cho ta 1 fương án khác (có nghĩa là chúng ta có thể bắt đầu với ván mới)
Cách thức chơi như sau
+ Di chuyển số: Hiện trên hình ta thấy 2 ô [G4] & [D9] đang trống;
Nếu ta dùng chuột bấm vô ô [H4] đang chứa trị 22 thì trị này lập tức sẽ nhảy sang ô trống bên trái liền kề & ô vừa bị ta bấm sẽ trở thành trống;
+ Xếp các số theo 1 trật tự đã định: Người chơi hoàn toàn có quyền định đoạt trật tự mà mình muốn về dẫy số tao thành,

Như tăng dần theo hàng & cột; như vậy [c4] sẽ là số 1, [D4] số 2. . . & [c5] - số 8 (hai ô trống sẽ ở hàng cuối
Hoặc tăng dần theo cột & hết cột 6 ô này đến cột 6 ô kết tiếp liền kề bên fải. (Cột cuối sẽ chứa 2 ô trống)
Cứ mỗi lần nhấn vô ô có nền sọc tím là 1 bước đi. Như vậy bạn cần chú í tránh bấm sai sót để khỏi bị trừ điểm oan. & nhiệm vụ của người chơi là dùng số bước đi tối thiểu để hoàn thành nhiệm vụ mà mình tự đề ra.
Lưu í là số bước đi của lần chơi mới (ván mới, khi ta nhấn vô nút ‘New’) được ghi lại trên ô [B3]
Nhưng bài này không fải nhằm quảng bá 1 trò chơi, mà chủ yếu là cùng nhau nghiên cứu giải fáp hiện tại để có thể cải tiến nó về mọi mặt, nhất là về mặt giải thuật.
Vì sao fải nêu vấn đề cải tiến; Vì rằng bài này đã có cách đây 4 năm; & trong quảng thời gian đó GPE.COM của chúng ta đã vươn vai & lớn mạnh không ngừng về tất cả các mặt, trong đó có mặt giải thuật.
Tác giả mong muốn giới thiệu kỹ giải thuật trò chơi này đến các bạn yêu thích VBA & hơn nữa sẽ nhận được các góp í cải tiến nhằm hoàn thiện trò chơi hơn trong tương lai.
I. Phần chuẩn bị hay gọi là giai đoạn khởi đầu)
1. Macro Aut

Khi bấm nút nào đó để mở file excel này lên, thì chúng ta đã cho các đòng lệnh dưới đây thực hiện
PHP:
Dim StrC As String: Global bRng As Range
Dim iZ As Integer: Dim SoBuoc As Integer
Sub Auto_Open()
Sheets("SaDQ").Select
Set bRng = Range("C4:I9"): Range("B3") = 0
End Sub
Tiếp theo là cho macro tự vận hành (Aut

Macro tự hành của chúng ta chỉ có 3 câu lệnh, đó là:
Kích hoạt trang tính, nhưng thật ra ở đây là lệnh thừa, vì chúng ta có mỗi 1 trang tính, chứ không nhiều nhặng gì cho cam.
Dòng thứ 2 là gán vùng cần thiết vô biến đã khai báo. (Các bạn tự tìm hiểu đó là vùng nào, nha)
Dòng 3: nạp số không cho [B3]; như trên ta biết, ô này sẽ thể hiện số bước mà chúng ta đã trãi qua trong 1 ván đấu.
2. Macro ván mới
Nội dung của macro này như dưới đây:
PHP:
Sub VanMoi()
On Error Resume Next
Dim SNg As Integer: Dim Schu As String
Dim Rng As Range
1 Auto_Open
StrC = "254026392738283729360001020304050607080900"
StrC = StrC & "101112131415161718192021222324303531343233"
3 For iZ = 1 To 999
Randomize: SNg = 1 + Int(36 * Rnd())
5 If SNg > 12 Then
StrC = Mid(StrC, 5, 2 * SNg) & Left(StrC, 4) & Mid(StrC, 5 + 2 * SNg)
7 Else
StrC = Mid(StrC, 2 * SNg + 1, 10) & Left(StrC, 2 * SNg) + Mid(StrC, 11 + 2 * SNg)
9 End If
Next iZ
11 iZ = 1
Application.ScreenUpdating = 0
13 For Each Rng In bRng
Schu = Mid(StrC, 2 * iZ - 1, 2)
15 Rng.Value = Val(Schu): If Schu = "00" Then Rng.Value = ""
17 iZ = 1 + iZ
Next Rng
19 Application.ScreenUpdating = True
End Sub
Xin diễn dịch các câu lệnh theo tuần tự & mở rọng lang bang chút đến 1 số trong chúng:
Dòng đầu tiên (sau tên macro) để báo cho chương trình là hễ gặp lỗi nào đó bất kỳ, thì bạn cứ viêc bỏ qua & thực thi các lệnh còn lại cho đến hết.
Nhiệm vụ của chúng ta sau khi đọc bài này là sẽ tìm trong các câu lệnh dưới, câu nào có thể gây ra lỗi. Đây sẽ là câu hỏi khó, rất khó nữa là đằng khác nếu fải xét các macro không fải của mình viết hay đó là chương trình của mình nhưng đã quá lâu không rờ đến.
Tiếp theo là 2 dòng lệnh dùng để khai báo 3 biến sẽ cần xài. (& 3 biến lại có 3 kiểu khác nhau)
Dòng lệnh có số 1: Triệu gọi chạy macro tự hành đã nói bên trên.
Kế tiếp là các dòng lệnh gán các ký số tứ đến 40 vô biến kiểu chuỗi
Dòng lệnh có số 3: Tạo vòng lặp khoảng trên 990 lần (cho đến dòng lệnh số 10).
Mục đích của vòng lặp này là tạo ra 1 chuỗi chứa ký số trong biến StrC fân bố 1 cách hết sức ngẫu nhiên.
Để đạt mục tiêu này, tác giả đã:
Fần đầu của dòng lệnh 4: Fát động bộ tạo số ngẫu
Fần sau: tạo ra 1 số ngẫu nhiên dao động từ 1 cho tới 36. Thật ra con số 36 này ta có thể thay bằng những con số khác. Sau khi nghiên cứu xong vòng lặp này, chính các bạn đưa ra các con số có thể thay vô số 36 xem sao?
Dòng có số 5: Tạo ra điều kiện, mà nếu thỏa sẽ thực thi lệnh tại dòng số 6, bằng ngược lại – sẽ là dòng lệnh số 8
Thực ra 2 dòng lệnh 6 & 8 cùng có 1 kiểu là đem chuỗi chứa trong biến StrC chặt ra làm 3 khúc & ráp lại thành chuỗi mới với 1 trật tự ráp khác nhau mà thôi
Với dòng lệnh 6, ráp khúc giữa làm đầu, khúc đầu làm giữa; Với dòng còn lại: Ráp khúc cuối làm đầu, khúc giữa làm cuối.
Với gần ngàn lần lặp lại như vây & hầu như nhắm mắt băm & đảo sau khi băm thì ruột gan của StrC lộn tùng fèo cả lên chứ chả chơi!
Khi đọc các dòng lệnh trong vòng lặp này, ta chú í 1 điều rằng, tuy là nhắm mắt băm, nhưng băm vô vị trí lẻ không thôi đó nhe.
Các bạn có thể hòi vì sao fải vậy; Thưa rằng chúng ta đang xáo trộn 40 các số hợp lại trong 1 chuỗi, gồm rất nhiều số có 2 chữ số & 9 số có 1 chữ số đã được biến thành chuổi 2 ký số (Thêm ký số 0 đằng trước chúng). Nếu chúng ta để í kỹ hơn, chúng ta sẽ trong StrC có 2 cặp ‘00’. Đó là tiền đề để tạo ra 2 ô trống ở bước tiếp theo ngay sau đây.
Nhiệm vụ còn lại của macro này là tự động cắt khúc 2 ký số làm 1 & ráp vô các ô có trong biến bRng. Việc này được thực hiện bằng các lệnh từ dòng 13 cho đến dòng 18
Nhiệm vụ cùa dòng lệnh 12 & 19: Yêu cầu mi làm xong mới hãy báo cáo.
/(/hững câu hỏi có thể fát sinh sau khi đọc bài đầu này (ngoài 2 câu trên):
(*) Tại sau tác giả xài con số 999? Nhỏ hơn hay lớn hơn có vấn đề gì không?
(*) Tại sau lại cắt chuỗi trong StrC làm 3 khúc, hai hoặc bốn, hay trên nữa có được không?
(*) Hãy bằng tư duy trừu tượng bạn hãy fát biểu kết quả sau khi bấm 1 ô có số, khi mà hai ô trống nằm ngày trên & dưới liền kề với ô ta bấm; Cũng câu hỏi như vậy với các trường hợp các ô trống nằm trái & fải ô bấm.. . .
(*) Các thắc mắc khác từ nơi bạn xung quanh vấn đề này.
(còn tiếp)
Chỉnh sửa lần cuối bởi điều hành viên: