Professional Documents
Culture Documents
Nội dung
A. Tổng quan............................................................................................................................ 1
B. Các yêu cầu.......................................................................................................................... 1
1. Phần mề
m........................................................................................................................1
2. Kiế
n thức......................................................................................................................... 2
C. Phần mề
m chơi...................................................................................................................3
1. Cấu trúc thư mục.............................................................................................................3
2. Phím tắt........................................................................................................................... 3
3. map.xml.......................................................................................................................... 3
4. Replay..............................................................................................................................4
D. Pacman đầu tiên.................................................................................................................4
1. Ngôn ngữ C#...................................................................................................................4
2. Ngôn ngữ VB.NET...........................................................................................................8
E. API tham khảo...................................................................................................................12
1. Kiểu dữ liệu....................................................................................................................12
2. Map................................................................................................................................13
3. Pacman.......................................................................................................................... 15
4. Ghost.............................................................................................................................. 16
5. Utils................................................................................................................................ 17
F. Các qui định.......................................................................................................................17
G. Hỏi đáp.............................................................................................................................. 18
Cúp Sáng Tạo Công Nghệ Thông Tin 201
0
A. Tổng quan
Rượt đuổi là một trò chơi dành cho các lập trình viên, mô phỏng game kinh đi ển Pacman 1. Ý
tưởng chính của trò chơi này là thay vì dùng bàn phím để di chuyển Pacman nh ư người dùng
bình thường, các lập trình viên có thể viế
t mã để tạo ra Pacman thông minh, có khả năng tiêu
diệt các Pacman khác, tìm đường ăn được nhiề u điểm và tránh gặp phải các Ghost trong mê
cung.
Tài liệu này mô tả các bước chi tiế t để tạo ra được một Pacman như trên, từ các công cụ và
kiến thức lập trình, cho đến các ví dụ mẫu, cách sử dụng phần mềm chơi cùng các API mà nó
cung cấp, kể cả giải đáp một sốthắc mắc thường gặp.
- Các lập trình viên chuyên và không chuyên, có kiế n thức căn bản vềlập trình, muốn
trải nghiệm một phần công việc lập trình robot.
- Các đội thi ITICup 2010 muốn biế t cách lập trình cho trò chơi Rượt đuổi để cạnh
tranh với Pacman của đội bạn và Ghost của BTC.
1. Visual Studio 2010 Express: Đây là chương trình soạn thảo mã nguồn cho các
ngôn ngữ C# hoặc VB.NET. Phần mề m IDE này hoàn toàn miễn phí, và đã bao gồm cả
Microsoft .NET Framework 4.
http://www.microsoft.com/express/downloads/#2010-All
1
http://www.freepacman.org/pacman.swf
2. Phần mềm Pacman: Đây là phần mề m chơi, kiểm thử các Pacman được lập trình,
đồng thời làm thư viện cung cấp các API để lấy thông tin vềbản đồ, các Pacman khác
và các Ghost.
http://iticlub.org
2. Kiến thức
Để chơi Rượt đuổi, lập trình viên cần có một sốkiế
n thức căn bản về1 trong 2 ngôn ngữ C#
hoặc VB.NET. Dưới đây là một sốmục quan trọng cần phải nắm:
- .NET Framework
- C# & VB.NET Language Fundamentals
- Classes & Objects
- Inheritance & Polymorphism
- Operator Overloading
- Structs
- Interfaces
2. Phím tắt
- Enter: khởi động trò chơi.
- Spacebar: tạm dừng hoặc tiếp tục trò chơi.
- Esc: kế t thúc trò chơi.
- F7: tắt âm thanh.
- F8: bật âm thanh.
- PageUp: bật chếđộ full screen.
- PageDown: bật chếđộ window screen.
3. map.xml
Đây là tập tin cấu hình bản đồ,có định dạng XML như sau:
<?xml version="1.0" encoding="utf-8" ?>
<map>
<width>Chiều rộng X của bản đồ</width>
<height>Chiều cao Y của bản đồ</height>
<ghost-duration>Số lượt di chuyển để xuất hiện thêm 1 Ghost</ghost-duration>
<magic-duration>Số lượt di chuyển để xuất hiện thêm 1 vật magic</magic-duration>
<weak-duration>Số lượt di chuyển để kết thúc trạng thái yếu</weak-duration>
<content>
<![CDATA[X*Y ký tự biểu diễn từng ô của bản đồ]]>
- Nế u thẻ ghost-duration không được định nghĩa, mặc định ghost sẽ không bao giờ xuất
hiện.
- Nế u thẻ magic-duration không được định nghĩa, mặc định vật magic sẽ không xuất
hiện ngẫu nhiên trong quá trình chơi.
- Nế u thẻ weak-duration không được định nghĩa, mặc định sốlượt di chuyển để thoát
khỏi trạng thái yế
u là chiề
u dài của mê cung.
4. Replay
Để lưu giữ lại diễn biế
n của những trận thi đấu hay, đồng thời hỗ trợ lập trình viên bẫy lỗi,
phần mề m cung cấp chức năng replay, dùng để xuất và nạp dữ liệu vềbản đồ, đường đi của
các Pacman và Ghost.
Bước 2: mở tập tin replay (Open With) bằng chương trình chơi hoặc kéo thả tập tin này vào
icon của chương trình chơi để xem lại diễn biế
n của trận thi đấu.
Bước 2: Thêm tham chiế u đến chương trình chơi bằng cách click phải vào project MyPacman
Add Reference. Sau đó tìm đến thư mục phần mề m chơi và chọn Pacman.exe. Click OK.
Tiế
p tục tham chiế
u đế
n thư viện PresentationCore và click OK.
Bước 3: Khai báo sử dụng thư viện của chương trình chơi và thư viện PresentationCore bằng
cách thêm vào 2 dòng sau ở phần đầu của Class1.cs.
using VCProjects.PacmanGame.Models;
using System.Windows.Media;
Bước 4: Thêm chuỗi “: Pacman” phía sau “public class Class1” để kếthừa từ lớp Pacman
do chương trình chơi cung cấp. Sau đó trỏ chuột vào chữ Pacman và chọn Implement
abstract class ‘Pacman’.
Bước 5: Chỉ định thuộc tính màu sắc cho Pacman, ví dụ chọn màu hồng.
Bước 6: Chỉ định thuộc tính tên cho Pacman, ví dụ chọn “My Pacman”.
// Nếu có nhiều hướng đi thì ưu tiên không đi theo đường ngược lại
// bằng cách xóa bỏ hướng đi ngược lại ra khỏi danh sách.
if (dirs.Count > 1)
dirs.Remove(Utils.GetOppositeDirection(this.Direction));
Bước 8: Sao lưu lại project bằng File Save All. Biên dịch project thành thư viện dll bằng
cách click phải vào project MyPacman Build. Copy MyPacman.dll trong thư mục bin (nơi
sao lưu project) vào thư mục Pacmans của phần mề m chơi.
Bước 9: Chạy chương trình chơi và mọi chuyện nên diễn ra suôn sẻ.
Bước 2: Thêm tham chiế u đến chương trình chơi bằng cách click phải vào project MyPacman
Add Reference. Sau đó tìm đến thư mục phần mề m chơi và chọn Pacman.exe. Click OK.
Tiế
p tục tham chiế
u đế
n thư viện PresentationCore và click OK.
Bước 3: Khai báo sử dụng thư viện của chương trình chơi và thư viện PresentationCore bằng
cách thêm vào 2 dòng sau ở phần đầu của Class1.vb.
Imports VCProjects.PacmanGame.Models
Imports System.Windows.Media
Bước 4: Thêm chuỗi “Inherits Pacman” bên dưới dòng “Public Class Class1” để kếthừa
từ lớp Pacman do chương trình chơi cung cấp. Sau đó nhấn Enter để tự động phát sinh các
hàm cần thiết.
Bước 5: Chỉ định thuộc tính màu sắc cho Pacman, ví dụ chọn màu hồng.
Bước 6: Chỉ định thuộc tính tên cho Pacman, ví dụ chọn “My Pacman”.
' Nếu có nhiều hướng đi thì ưu tiên không đi theo đường ngược lại
' bằng cách xóa bỏ hướng đi ngược lại ra khỏi danh sách.
If dirs.Count > 1 Then
dirs.Remove(Utils.GetOppositeDirection(Me.Direction))
End If
' Nếu có ít nhất một hướng đi thì chọn hướng đi ngẫu nhiên.
If dirs.Count > 0 Then
Me.Direction = dirs(Utils.GetRandom(dirs.Count))
Else
' Nếu không có hướng đi nào khác thì quyết định đứng yên.
Me.Direction = DirectionType.None
End If
End If
Loop
End Sub
Bước 8: Sao lưu lại project bằng File Save All. Biên dịch project thành thư viện dll bằng
cách click phải vào project MyPacman Build. Copy MyPacman.dll trong thư mục bin (nơi
sao lưu project) vào thư mục Pacmans của phần mề m chơi.
Bước 9: Chạy chương trình chơi và mọi chuyện nên diễn ra suôn sẻ.
1. Kiểu dữ liệu
Bản đồcủa mê cung được mô hình hóa thành một ma trận kích thước Map.Height x
Map.Width. Các ô trong ma trận có tọa độ dòng và c ột được đánh sốbắt đầu từ 0, do đó dòng
cuối cùng có sốthứ tự là Map.Height – 1, và cột cuối cùng có sốthứ tự là Map.Width – 1.
Mỗi ô của ma trận có giá trị thuộc kiểu CellType, mô tả ô này đang chứa vật gì:
Tại ô (i, j), Pacman và Ghost có thể di chuyển theo 4 hướng kếcận hoặc đứng yên. Hướng đi
được mô tả bằng một giá trị thuộc kiểu DirectionType như sau:
Thay vì mô tả tọa độ bằng một cặp giá trị sốnguyên (dòng, cột) như trên, lập trình viên có thể
sử dụng kiểu dữ liệu Coordinate được xây dựng sẵn như sau:
2. Map
Cung cấp các hàm tiện ích để làm việc với bản đồ.Đây là những hàm static có thể gọi trực tiế
p
từ lớp Map.
Prototype Mô tả
Map.CommandKey Nhận các mệnh lệnh của người dùng từ bàn
phím. Giá trị trả về thuộc kiểu
System.Windows.Input.Key. Lưu ý: thuộc
tính này chỉ được dùng để hỗ trợ kiểm thử
trong giai đoạn lập trình, để sử dụng cần tham
chiế u đế n thư viện Windows Base.
Map.GetCell(Coordinate coor) Lấy mô tả của ô trong mê cung có tọa độ coor.
Giá trị trả vềthuộc kiểu CellType.
Map.GetCell(Coordinate coor, Lấy mô tả của ô trong mê cung nằm theo
DirectionType dir) hướng dir cạnh bên ô có tọa độ coor. Giá trị trả
vềthuộc kiểu CellType.
Map.GetCell(Int32 i, Int32 j) Lấy mô tả của ô trong mê cung tại dòng i, cột j.
Giá trị trả vềthuộc kiểu CellType.
Map.GetCell(Int32 i, Int32 j, Lấy mô tả của ô trong mê cung nằm theo
DirectionType dir) hướng dir cạnh bên ô tại dòng i, cột j. Giá trị
trả vềthuộc kiểu CellType.
Map.GetGhost(Int32 index) Lấy đối tượng Ghost theo số thứ tự index
(được đánh sốbắt đầu từ 0). Giá trị trả về
thuộc kiểu Ghost, hoặc trả vềnull nế u Ghost
này không còn tồn tại.
Map.GetGhosts() Lấy mảng toàn bộ các Ghost có trong mê cung.
Giá trị trả vềthuộc kiểu Ghost[].
Map.GetGhosts(Coordinate coor) Lấy mảng các Ghost hiện đang nằm tại tọa độ
coor trên mê cung. Giá trị trả vềthuộc kiểu
Ghost[].
Map.GetGhosts(Int32 i, Int32 j) Lấy mảng các Ghost hiện đang nằm tại dòng i,
cột j trên mê cung. Giá trị trả vềthuộc kiểu
Ghost[].
Map.GetLocation(Coordinate coor, Lấy tọa độ ô trên mê cung nằm theo hướng dir
DirectionType dir) cạnh bên ô có tọa độ coor. Giá trị trả vềthuộc
kiểu Coordinate.
3. Pacman
Cung cấp các hàm tiện ích để làm việc với Pacman. Đây là những hàm gắn với một đối tượng
Pacman P cụ thể.
Prototype Mô tả
Pacman.CanEat(Pacman man) Kiểm tra Pacman P có khả năng ăn được
Pacman man hay không.
Pacman.CanEat(Ghost gho) Kiểm tra Pacman P có khả năng ăn được Ghost
gho hay không.
Pacman.CanGo(DirectionType dir) Kiểm tra Pacman P có thể đi tiếp theo hướng
dir hay không.
4. Ghost
Cung cấp các hàm tiện ích để làm việc với Ghost. Đây là những hàm gắn với một đối tượng
Ghost G cụ thể.
Prototype Mô tả
Ghost.CanEat(Pacman man) Kiểm tra Ghost G có khả năng ăn được
Pacman man hay không.
Ghost.CanGo(DirectionType dir) Kiểm tra Ghost G có thể đi tiế p theo hướng dir
hay không.
Ghost.Direction Lấy hướng đi hiện tại của Ghost G, trả vềgiá trị
hướng đi thuộc kiểu DirectionType.
Ghost.Index Lấy sốthứ tự chỉ mục của Ghost G trong danh
sách các Ghost có mặt ở mê cung. Giá trị trả về
thuộc kiểu Int32. Lưu ý: nế u Ghost đã bị tiêu
diệt thì trả về-1.
Ghost.IsDead Kiểm tra Ghost G đã bị tiêu diệt hay chưa.
Ghost.Location Lấy tọa độ hiện thời của Ghost G trên mê cung,
trả vềgiá trị tọa độ thuộc kiểu Coordinate.
Ghost.Weak Lấy trạng thái hiện tại của Ghost G. Nế u G
đang bình thường, trả vềgiá trị 0. Nế u G đang
5. Utils
Cung cấp một sốhàm tiện ích hỗ trợ cho công việc lập trình. Đây là những hàm static có thể
gọi trực tiế
p từ lớp Utils.
Prototype Mô tả
Utils.FillArray(T[] array, T value) Gán value làm giá trị của tất cả các phần tử
thuộc mảng một chiề u array.
Utils.FillArray(T[,] array, T value) Gán value làm giá trị của tất cả các phần tử
thuộc mảng 2 chiề u array.
Utils.FillArray(T[,,] array, T value) Gán value làm giá trị của tất cả các phần tử
thuộc mảng 3 chiề u array.
Utils.FillArray(T[,,,] array, T value) Gán value làm giá trị của tất cả các phần tử
thuộc mảng 4 chiề u array.
Utils.GetColor(String color) Lấy giá trị màu từ một chuỗi mô tả. Giá trị trả
vềthuộc kiểu System.Windows.Media.Color.
Utils.GetOppositeDirection( Trả vềhướng đi ngược lại với hướng đi dir
DirectionType dir) được cung cấp. Ví dụ, nế u dir là
DirectionType.North thì hàm trả về
DirectionType.South.
Utils.GetRandom() Trả vềmột sốnguyên dương kiểu Int32 có giá
trị ngẫu nhiên.
Utils.GetRandom(Int32 maxValue) Trả vềmột sốnguyên dương kiểu Int32 có giá
trị ngẫu nhiên nhỏ hơn maxValue.
Utils.GetRandom(Int32 minValue, Trả vềmột sốnguyên kiểu Int32 có giá trị
Int32 maxValue) ngẫu nhiên trong khoảng minValue và
maxValue.
Utils.GetRandom(IEnumerable<T> list) Trả vềmột phần tử ngẫu nhiên kiểu T có trong
tập hợp list. Nế u tập hợp rỗng thì trả vềgiá trị
mặc định của kiểu T.
Utils.GetRandomDouble() Trả vềmột sốthực có giá trị ngẫu nhiên trong
khoảng từ 0 đế n 1.
Utils.SetRandomBytes(Byte[] buffer) Gán các giá trị sốnguyên kiểu Byte ngẫu nhiên
vào từng vị trí của mảng buffer.
Utils.Shuffle(IEnumerable<T> list) Trả vềmột hợp gồm các phần tử kiểu T đã
được xáo trộn ngẫu nhiên từ tập hợp list.
G. Hỏi đáp
1. Trong thi đấu thì tôi có cần phải thực hiện cả 7 bước như ví dụ mẫu hay
không?
Không. BTC sẽ thực hiện các bước từ 1 đế n 4 và chuẩn bị sẵn máy tính cho việc lập trình.
Trong thời gian thi đấu, lập trình viên thực hiện tiếp tục từ bước 5 đế
n 7. Sau khi hoàn thành
xong phần chơi, BTC tiế p tục thực hiện bước 8 và 9.
2. Điều gì sẽ xảy ra nếu tôi cài đặt hàm Start() không phải là một vòng lặp vô
hạn?
Lập trình viên được phép thực hiện điều này. Tuy nhiên, do đặc tính của chương trình chơi,
khi hàm Start() kết thúc đồng nghĩa với việc báo hiệu Pacman sẽ không còn có khả năng cập
nhật hướng đi nữa. Kể từ lúc này cho đế n khi trò chơi chấm dứt, Pacman sẽ chỉ đi theo một
hướng – đó chính là hướng đi cuối cùng mà nó cập nhật vào thuộc tính Direction.
3. Tôi có thể mang theo bàn phím và chuột riêng để thuận ti ện trong thao tác
hay không?
4. Tôi có quyền mang theo tài liệu trong lúc lập trình không?
Cuộc thi sẽ có 3 bản đồdành cho vòng loại, bán kết và chung kế t. Lập trình viên được quyề
n
biế
t trước bản đồđể chuẩn bị trong vòng một tuần trước ngày thi.
6. Thuật toán điều khiển Ghost của BTC thay đổi thếnào qua từng trận đấu?
Mỗi trận đấu BTC có quyề n thay đổi một thuật toán khác nhau, không nhất thiế
t phải giống
với chương trình chơi được cung cấp với mục đích làm quen. BTC cũng không thông báo gì
trước vềmức độ thông minh của các Ghost.
7. Trong trường hợp tên và màu của các Pacman trùng nhau thì xử lý nh ư thế
nào?
Để chạy Pacman, nế u lập trình viên phải copy thư viện dll và chạy chương trình chơi m ột cách
thủ công thì khá bất tiện trong lúc lập trình. Hướng dẫn sau đây mô tả cách thức thiế t lập chế
độ debug để thuận tiện cho việc dò lỗi. Trước khi thi đấu, tất cả máy tính cũng sẽ được BTC
cấu hình sẵn như bên dưới.
Bước 1: Do phiên bản Visual Studio 2010 Express không hỗ trợ nhiề u thiết đặt Start Options
nên lập trình viên cần làm thủ công như sau. Mở tập tin project *.csproj (C#) ho ặc *.vbproj
(VB.NET) bằng notepad, thêm nội dung StartAction và StartProgram vào bên dưới thẻ
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">:
<StartAction>Program</StartAction>
<StartProgram>Đường dẫn đến chương trình chơi Pacman.exe</StartProgram>
Ngôn ngữ C#
Bước 2: Trong Visual C# 2010 Express, click phải vào project và ch ọn Properties.
Bước 3: Trong tab Build, mục Output, chọn Output Path là thư mục Pacmans c ủa phần mề
m
chơi.
Bước 2: Trong Visual Basic 2010 Express, click phải vào project và ch ọn Properties.
Bước 3: Trong tab Compile, chọn Build output path là thư mục Pacmans c ủa phần mề
m chơi.
Cả 2 ngôn ngữ
Bước 4: Trong tab Debug, mục Start Options, chọn Working directory là thư m ục gốc của
phần mề m chơi.
Bước 5: Sao lưu lại project, đặt breakpoint tại các vị trí cần thiế
t và nhấn F5 để bắt đầu debug.
Chương trình chơi Pacman.exe được project tham chiế u đế n trong lúc lập trình, do đó mặc
định nó sẽ được copy vào thư mục Output. Sự xuất hiện của nó, có hay không có, cũng không
gây ảnh hưởng gì đế n hoạt động của thư viện dll trong lúc thi đấu. Tuy nhiên, nế u cảm thấy
bất tiện, lập trình viên có thể tùy chỉnh như sau để ngăn việc tự động copy này: click vào
References\Pacman ở Solution Explorer, gán thuộc tính Copy Local ở Properties Window là
False.
10. Làm thếnào để ngăn chặn các Pacman khác gọi hàm Pacman.Start() của
tôi?
BTC đã có luật cấm gọi hàm Pacman.Start(). Pacman vi phạm luật này bị loại khỏi cuộc chơi.
Nếu lập trình viên vẫn chưa an tâm, có thể sử dụng cách thức sau để ngăn cản:
- Định nghĩa một biế n isStart kiểu Boolean và gán giá trị khởi tạo là False.
- Trong hàm Start(), nế u isStart là False thì gán isStart bằng True và chạy thuật toán,
ngược lại thoát khỏi hàm.
11. Pacman của tôi gây ra lỗi trong lúc thực thi, làm sao để tôi xem chi tiết nội
dung của lỗi?
Khi Pacman bị hủy vì gây ra lỗi, nội dung lỗi sẽ nằm ẩn bên dưới khu vực điểm sốcủa Pacman.
Để thấy được nội dung này, lập trình viên trỏ chuột vào gần điểm số, chú thích (tooltip) vềlỗi
sẽ hiện ra.
12. Chương trình chơi bị crash trong lúc chạy vì thư viện WINMM.dll?
13. Tôi có thể viết thêm mã ngoài các hàm được cung cấp không?
Lập trình viên được toàn quyề n viết thêm mã, ví dụ như các hàm mới, định nghĩa thêm các
biến, các cấu trúc dữ liệu mới. Nế u cảm thấy mã này khá thông dụng, có thể đềxuất với BTC
để BTC chuẩn hóa nó thành API, nhằm tiế t kiệm thời gian lập trình.
14. Tại sao tôi không nên cập nhật thuộc tính Direction nhiều lần trong một
vòng lặp?
Đôi khi có trường hợp chưa chạy hế t vòng lặp, mà chương trình chơi đã lấy thuộc tính
Direction ra để sử dụng. Khi này, thuộc tính Direction chưa phải là tối ưu nên sẽ làm Pacman
chạy không đúng theo ý của người thiế t kế.