Microsoft Word Bai 8 1 docx Trang 1 MÔN CÁC MẪU THIẾT KẾ HỚNG ỐI TỢNG Bài thực hành số 8 1 Viết chng trình son tho mê cung I Mục tiêu Giúp SV làm quen cách viết chng trình có kh nng tng[.]
Trang 1MÔN : CÁC MẪU THIẾT KẾ HỚNG ỐI TỢNG Bài thực hành số 8.1 : Viết chng trình son tho mê cung
I Mục tiêu :
Giúp SV làm quen cách viết chng trình có kh nng tng tác trực quan với ngời dùng Giúp SV nắm vững cấu trúc của mê cung mà s ợc dùng trong bài thực hành 9.1
II Nội dung :
Mê cung là 1 ma trận 2 chiều gồm nhiều hàng và cột Giao mỗi hàng và mỗi cột là
1 cell Cell có thể chứa 1 phần tử xác ịnh của mê cung Trong bài này, ta giới hn dùng 3 loi cell : cell trống là cell mà ngời chi có thể i qua; cell tờng là cell mà ngời chi không thể i qua; cell iểm là cell mà ngời chi có thể i qua và khi i qua, ngời chi s tng ợc 1 iểm tích lũy Trong bài thực hành 9.1, ta s sử dụng thuật toán tiến hóa ã viết ở bài thực hành 5.1 ể tìm ờng i tha mãn
iều kiện : số bớc i xác ịnh, n nhiều iểm nhất có thể có
Nội dung bài thực hành này là viết cng trình cho phép ngời dùng son tho mê cung bất kỳ ể có thễ dùng li trong bài thực hành 9.1 Chng trình gồm 1 form chứa :
file mê cung và Lu file mê cung
cung theo chuẩn 20 x 20 cell
có thể chọn từng thời iểm
Form có dng nh sau :
III Chuẩn ầu ra :
Nắm vững cách viết chng trình có kh nng tng tác trực quan với ngời dùng
IV Qui trình xây dựng chng trình
trong mê cung Chọn kích thớc 30x30 pixels Lu các hình lên các file bitmap
ở th mục xác ịnh Nhớ vị trí th mục này ể các bớc sau dùng li các file
nh
chọn icon "Windows Form Application" trong listbox "Templates" bên phi, thiết lập th mục chứa Project trong listbox "Location", nhập tên Project vào
Trang 2textbox "Name:" (td BaiTH81), click button OK ể to Project theo các thông
số ã khai báo
form là quá trình lặp 4 thao tác to mới/xóa/hiệu chỉnh thuộc tính/to hàm
xử lý sự kiện cho từng ối tợng cần dùng trong form
ợc, do ó ta viết code ể hiển thị ộng form Vào cửa sổ son code cho form
và thêm on code sau vào hàm khởi ộng form :
public Form1() {
InitializeComponent();
//to ối tợng qun lý assembly
System.Reflection.Assembly myAssembly =
System.Reflection.Assembly.GetExecutingAssembly();
//to ối tợng Stream miêu t nh bitmap
Stream myStream =
myAssembly.GetManifestResourceStream("BaiTH91.Resources.dot.bmp");
//to ối tợng nh bitmap cho cell dot
dotbm = newBitmap(myStream);
//to ối tợng nh bitmap cho cell space
myStream =
myAssembly.GetManifestResourceStream("BaiTH91.Resources.space.bmp");
spacebm = newBitmap(myStream);
//to ối tợng nh bitmap cho cell space
myStream =
myAssembly.GetManifestResourceStream("BaiTH91.Resources.wall.bmp");
wallbm = newBitmap(myStream);
this.ClientSize = newSize(COLS * CSIZE+300,ROWS * CSIZE);
this.MouseDown += newMouseEventHandler(Frm_MouseDown);
//tiêu ề form
this.Text = "Laby Builder";
//to mê cung
laby = newLabyrinth(ROWS, COLS);
//to Panel và menu
CreateCenterPanel();
CreateMenus();
}
//ịnh nghĩa các hằng cần dùng
privateconstlong serialVersionUID = 1L;
privateconstString SER_EXPORT_MENU = "Save labyrinth";
privateconstString SER_IMPORT_MENU = "Load labyrinth";
privateconstint ROWS = 20, COLS = 20;
privateconstint CSIZE = 30;
private Bitmap dotbm, spacebm, wallbm;
//vùng chứa các buttons
Trang 3private Panel sidePanel;
//mê cung cần hiển thị
private Labyrinth laby;
private LabyItem actionChoosed = LabyItem.WALL;
// Pour les tests getSource dans le Menu Listener : les sources d'événements menu private MenuItem mi_export;
private MenuItem mi_import;
//vùng hiển thị mê cung
private LabyPanel centerPanel;
privateint xl, yl;
//hàm to menu
privatevoid CreateMenus()
{
//to 2 option phục vụ thực hiện 2 tác vụ Export/Import mê cung
mi_export = new MenuItem(SER_EXPORT_MENU, Export_Click);
mi_import = new MenuItem(SER_IMPORT_MENU, Import_Click);
MenuItem[] fmItems = new MenuItem[2];
fmItems[0] = mi_export;
fmItems[1] = mi_import;
//to menu File và add vào menu bar;
MenuItem fmenu = new MenuItem("File", fmItems);
//to menu bar cho form
MenuItem[] mbItems = new MenuItem[1];
mbItems[0] = fmenu;
MainMenu mainMenu = new MainMenu(mbItems);
this.Menu = mainMenu;
}
//tác vụ v bộ mặt giao diện của Button
protectedoverridevoid OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
int xl = ClientSize.Width - 260;
int yl = 20;
//xuất các chuỗi hớng dẫn
//to ối tợng font chữ cần dùng
Font myFont = new Font("BKHelvetica", 10);
//to biến miêu t chế ộ canh giữa khi xuất chuỗi
StringFormat format1 = new StringFormat(StringFormatFlags.NoClip);
format1.Alignment = StringAlignment.Near;
Brush brush = System.Drawing.Brushes.Black;
//xuất chuỗi miêu t giờ/phút/giây
g.DrawString("Click chọn mẫu cell cần dùng", myFont, brush, xl, yl, format1);
yl += 20;
g.DrawString("Rồi Click vào cell cần son", myFont, brush, xl, yl, format1);
yl += 20;
g.DrawString("ể son cell theo mẫu chọn.", myFont, brush, xl, yl, format1);
Trang 4yl += 30;
//to các Button chức nng
g.DrawImage(spacebm, xl, yl);
g.DrawImage(dotbm, xl + CSIZE + 20, yl);
g.DrawImage(wallbm, xl + 2 * (CSIZE + 20), yl);
//lu vị trí các icon mẫu cell
this.xl = xl; this.yl = yl;
yl += 50;
g.DrawString("Mẫu cell ang chọn:", myFont, brush, xl, yl, format1);
yl += 25;
Bitmap bm = null;
switch (actionChoosed)
{
case LabyItem.NULL: bm = spacebm; break;
case LabyItem.POINT: bm = dotbm; break;
case LabyItem.WALL: bm = wallbm; break;
}
g.DrawImage(bm, xl, yl);
}
privatevoid Frm_MouseDown(object sender, MouseEventArgs e) {
//xác ịnh vị trí chuột hiện hành
//Point mousePos = Control.MousePosition;
if (e.X < xl) return;
if (e.Y < yl) return;
if (e.Y > yl + CSIZE) return;
//tính tọa ộ luận lý chuột ợc click
int c = (e.X - xl) / (CSIZE + 20);
if (c > 2) return;
switch (c)
{
case 0: actionChoosed = LabyItem.NULL; break;
case 1: actionChoosed = LabyItem.POINT; break;
case 2: actionChoosed = LabyItem.WALL; break;
}
centerPanel.ActionSelected = actionChoosed;
//v li panel mê cung
// Refresh();
Rectangle rc = new Rectangle();
rc.Location = new Point(xl, 20);
rc.Size = new Size(150, 500);
Invalidate(rc);
}
//hàm xử lý option Export
Trang 5privatevoid Export_Click(object sender, EventArgs e)
{
exportMazeData();
}
//hàm xử lý option Import
privatevoid Import_Click(object sender, EventArgs e)
{
chargerLabyrinthe();
}
//hàm to Panel chính
privatevoid CreateCenterPanel()
{
centerPanel = new LabyPanel(laby);
Controls.Add(centerPanel);
}
publicstatic DialogResult InputBox(string title, string promptText, refstring value) {
Form form = new Form();
Label label = new Label();
TextBox textBox = new TextBox();
Button buttonOk = new Button();
Button buttonCancel = new Button();
form.Text = title;
label.Text = promptText;
textBox.Text = value;
buttonOk.Text = "OK";
buttonCancel.Text = "Cancel";
buttonOk.DialogResult = DialogResult.OK;
buttonCancel.DialogResult = DialogResult.Cancel;
label.SetBounds(9, 20, 372, 13);
textBox.SetBounds(12, 36, 372, 20);
buttonOk.SetBounds(228, 72, 75, 23);
buttonCancel.SetBounds(309, 72, 75, 23);
label.AutoSize = true;
textBox.Anchor = textBox.Anchor | AnchorStyles.Right;
buttonOk.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
buttonCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
form.ClientSize = new Size(396, 107);
form.Controls.AddRange(new Control[] { label, textBox, buttonOk, buttonCancel }); form.ClientSize = new Size(Math.Max(300, label.Right + 10), form.ClientSize.Height);
Trang 6form.FormBorderStyle = FormBorderStyle.FixedDialog;
form.StartPosition = FormStartPosition.CenterScreen;
form.MinimizeBox = false;
form.MaximizeBox = false;
form.AcceptButton = buttonOk;
form.CancelButton = buttonCancel;
DialogResult dialogResult = form.ShowDialog();
value = textBox.Text;
return dialogResult;
}
//lu mê cung lên file
publicvoid exportMazeData()
{
//thiết lập chế ộ cập nhật
centerPanel.modifLaby();
String fileName = null;
InputBox("Nhập tên file : ", "Nhập tên file cần ghi", ref fileName); LabyrinthLoader.Save_Labyrinth(fileName, laby);
}
//np mê cung từ file
publicvoid chargerLabyrinthe()
{
//to form duyệt chọn file cần ọc
OpenFileDialog dlg = new OpenFileDialog();
//hiển thị form duyệt chọn file cần ọc
DialogResult ret = dlg.ShowDialog();
//kiểm tra quyết ịnh của ngời dùng, nếu ngời dùng chọn OK thì ọc
if (ret != DialogResult.OK) return;
try
{
laby = LabyrinthLoader.Load_Labyrinth(dlg.FileName);
}
catch (IOException e)
{
MessageBox.Show("Không ọc ợc file " + dlg.FileName);
return;
}
catch (LabyFaultEntourException e)
{
laby.EntourofWalls();
}
catch (BeginCellNotNullException e)
{
laby.setContenuCase(1, 1, LabyItem.NULL);
Trang 7}
catch (Exception e)
{
MessageBox.Show("Lỗi cha xác ịnh.");
return;
}
centerPanel.setLaby(laby);
}
//lu mê cung ra file
publicvoid sauverLabyrintheEnXML()
{
centerPanel.modifLaby();
LabyrinthLoader.chargerLabyrintheEnXML("maze_xml.txt", laby);
}
Lu ý thêm lệnh using sau vào ầu file mã nguồn ặc t Form1 ể nó có thể
sử dụng các file ợc to ra trong các bớc kế tiếp :
using BaiTH81.EditLaby;
phi chuột vào nó ể hiển thị menu lệnh, chọn chức nng Add.New Folder ể to 1 folder mới ặt tên cho folder này là EditLaby Trong th mục này, ta s chứa các file mã nguồn ợc to ra trong bài thực hành này
7 Dời chuột về folder EditLaby, ấn phi chuột vào nó ể hiển thị menu lệnh, chọn chức nng Add.Class ể hiển thị cửa sổ “Add New Item”, chọn mục
“Class”, hiệu chỉnh tên class là LabyErrorException.cs, chọn button Add ể máy to 1 class mới ây là class miêu t 1 loi lỗi Exception mà chng trình s dùng Viết code cho class này nh sau :
namespace BaiTH81.EditLaby {
classLabyErrorException : Exception {
//chỉ số version
privateconstlong serialVersionUID = 1L;
public LabyErrorException(String message)
: base(message)
{
}
}
}
7 Dời chuột về folder EditLaby, ấn phi chuột vào nó ể hiển thị menu lệnh, chọn chức nng Add.Class ể hiển thị cửa sổ “Add New Item”, chọn mục
“Class”, hiệu chỉnh tên class là BeginCellNotNullException.cs, chọn button Add ể máy to 1 class mới ây là class miêu t 1 loi lỗi Exception mà chng trình s dùng Viết code cho class này nh sau :
namespace BaiTH81.EditLaby {
classBeginCellNotNullException : LabyErrorException {
// chỉ số version
Trang 8privateconstlong serialVersionUID = 1L;
public BeginCellNotNullException(String message)
: base(message)
{
}
}
}
8 Dời chuột về folder EditLaby, ấn phi chuột vào nó ể hiển thị menu lệnh, chọn chức nng Add.Class ể hiển thị cửa sổ “Add New Item”, chọn mục
“Class”, hiệu chỉnh tên class là LabyFaultEntourException.cs, chọn button Add
ể máy to 1 class mới ây là class miêu t 1 loi lỗi Exception mà chng trình s dùng Viết code cho class này nh sau :
namespace BaiTH81.EditLaby {
classLabyFaultEntourException : LabyErrorException {
// chỉ số version
privateconstlong serialVersionUID = 1L;
public LabyFaultEntourException(String message)
: base(message)
{
}
}
}
9 Dời chuột về folder EditLaby, ấn phi chuột vào nó ể hiển thị menu lệnh, chọn chức nng Add.Class ể hiển thị cửa sổ “Add New Item”, chọn mục
“Class”, hiệu chỉnh tên class là LabyItem.cs, chọn button Add ể máy to 1 class mới Viết code cho kiểu liệt kê này nh sau :
namespace BaiTH81.EditLaby {
enumLabyItem {
ANY, //cell joker
NULL, //cell trống
POINT, //cell iểm
WALL, //cell tờng không i qua ợc
AGENT //cell chứa ngời i
}
publicenumDirection {
UP, DOWN, LEFT, RIGHT, STOP
}
}
10 Dời chuột về folder EditLaby, ấn phi chuột vào nó ể hiển thị menu lệnh, chọn chức nng Add.Class ể hiển thị cửa sổ “Add New Item”, chọn mục
“Class”, hiệu chỉnh tên class là LabyPanel.cs, chọn button Add ể máy to 1 class mới Viết code cho class này nh sau :
using System.Windows.Forms;
using System.Drawing;
using System.IO;
Trang 9namespace BaiTH81.EditLaby {
classLabyPanel : Panel {
privateconstint ROWS = 20, COLS = 20;
privateconstint CSIZE = 30;
// Serializable trivia
privateconstlong serialVersionUID = 1L;
//ma trận cell của mê cung ang hiệu chỉnh
privateLabyrinth laby;
privateLabyItem[,] Cells;
privateint hcnt, ccnt;
//loi cell ang chọn
privateLabyItem actionSelected = LabyItem.NULL;
privateBitmap agentbm, dotbm, spacebm, wallbm;
protectedbool edit_enable = true;
privateMyPoint npos, opos = newMyPoint(1, 1);
//hàm copy nội dung mê cung
publicvoid setLaby(Labyrinth laby)
{
this.laby = laby;
hcnt = laby.Ysize();
ccnt = laby.Xsize();
Cells = newLabyItem[hcnt, ccnt];
npos = null;
for (int h = 0; h < hcnt; h++)
for (int c = 0; c < ccnt; c++)
{
Cells[h, c] = laby.getContenuCase(h, c);
if (Cells[h, c] == LabyItem.AGENT) npos = newMyPoint(h, c); }
//v vị trí mới của agent
Refresh();
/*v li vị trí củ của agent trong mê cung
Rectangle rc = new Rectangle();
rc.Location = new Point(opos.x * CSIZE, opos.y * CSIZE);
rc.Size = new Size(CSIZE, CSIZE);
Invalidate(rc);
if (npos != null)
{
opos = npos;
rc.Location = new Point(opos.x * CSIZE, opos.y * CSIZE);
rc.Size = new Size(CSIZE, CSIZE);
Invalidate(rc);
//ngủ chờ 1s
//Thread.Sleep(500);
}*/
}
Trang 10//hàm cập nhật li mê cung
publicvoid modifLaby()
{
for (int h = 0; h < hcnt; h++)
{
for (int c = 0; c < ccnt; c++)
{
laby.setContenuCase(h, c, Cells[h, c]);
}
}
}
publicLabyItem ActionSelected
{
set { actionSelected = value; }
}
//hàm khởi to
public LabyPanel(Labyrinth laby)
{
this.MouseDown += newMouseEventHandler(Frm_MouseDown); //this.Paint += new PaintEventHandler(OnPaint);
//to ối tợng qun lý assembly
System.Reflection.Assembly myAssembly =
System.Reflection.Assembly.GetExecutingAssembly();
//to ối tợng Stream miêu t nh bitmap
Stream myStream =
myAssembly.GetManifestResourceStream("BaiTH91.Resources.dot.bmp"); //to ối tợng nh bitmap cho cell dot
dotbm = newBitmap(myStream);
//to ối tợng nh bitmap cho cell space
myStream =
myAssembly.GetManifestResourceStream("BaiTH91.Resources.space.bmp"); spacebm = newBitmap(myStream);
//to ối tợng nh bitmap cho cell space
myStream =
myAssembly.GetManifestResourceStream("BaiTH91.Resources.wall.bmp"); wallbm = newBitmap(myStream);
//to ối tợng nh bitmap cho cell space
myStream =
myAssembly.GetManifestResourceStream("BaiTH91.Resources.agent.jpg"); agentbm = newBitmap(myStream);
setLaby(laby);
this.ClientSize = newSize(ccnt * CSIZE, hcnt * CSIZE);
// v li mê cung
Refresh();