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 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 tố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 :
-
menu bar chứa 1 menu pop-up. Menu pop-up chứa 2 option chính yếu : Load
file mê cung và Lu file mê cung.
-
Panel chứa mê cung cần son tho, ể n gin ta qui ịnh kích thớc mê
cung theo chuẩn 20 x 20 cell.
-
Danh sách 3 loi cell cần son : cell trống, cell iểm, cell tờng ể ngời dùng
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
1.
Dùng chng trình Paint ể son 4 hình bitmap miêu t 4 loi cell ợc dùng
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.
2.
Chy VS .Net, chọn menu File.New.Project ể hiển thị cửa sổ New Project.
3.
Mở rộng mục Visual C# trong TreeView "Project Types", chọn mục Window,
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 2
textbox "Name:" (td. BaiTH81), click button OK ể to Project theo các thông
số ã khai báo.
3.
Form ầu tiên của ứng dụng ã hiển thị trong cửa sổ thiết kế, việc thiết kế
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.
4.
Do nội dung của form chỉ ợc hiển thị ộng nên ta không thiết kế trực quan
ợ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 = new Bitmap(myStream);
//to ối tợng nh bitmap cho cell space
myStream =
myAssembly.GetManifestResourceStream("BaiTH91.Resources.space.bmp");
spacebm = new Bitmap(myStream);
//to ối tợng nh bitmap cho cell space
myStream =
myAssembly.GetManifestResourceStream("BaiTH91.Resources.wall.bmp");
wallbm = new Bitmap(myStream);
this.ClientSize = new Size(COLS * CSIZE+300,ROWS * CSIZE);
this.MouseDown += new MouseEventHandler(Frm_MouseDown);
//tiêu ề form
this.Text = "Laby Builder";
//to mê cung
laby = new Labyrinth(ROWS, COLS);
//to Panel và menu
CreateCenterPanel();
CreateMenus();
}
5.
Dời chuột về ầu class Form1 rồi thêm các lệnh ịnh nghĩa sau :
//ịnh nghĩa các hằng cần dùng
private const long serialVersionUID = 1L;
private const String SER_EXPORT_MENU = "Save labyrinth";
private const String SER_IMPORT_MENU = "Load labyrinth";
private const int ROWS = 20, COLS = 20;
private const int CSIZE = 30;
private Bitmap dotbm, spacebm, wallbm;
//vùng chứa các buttons
Trang 3
private 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;
private int xl, yl;
//hàm to menu
private void 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
protected override void 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 4
yl += 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);
}
private void 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 5
private void Export_Click(object sender, EventArgs e)
{
exportMazeData();
}
//hàm xử lý option Import
private void Import_Click(object sender, EventArgs e)
{
chargerLabyrinthe();
}
//hàm to Panel chính
private void CreateCenterPanel()
{
centerPanel = new LabyPanel(laby);
Controls.Add(centerPanel);
}
public static DialogResult InputBox(string title, string promptText, ref string 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 6
form.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
public void 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
public void 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
public void 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;
6.
Dời chuột về phần tử gốc của cây Project trong cửa sổ “Solution Explorer”, ấn
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 {
class LabyErrorException : Exception {
//chỉ số version
private const long 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 {
class BeginCellNotNullException : LabyErrorException {
// chỉ số version
Trang 8
private const long 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 {
class LabyFaultEntourException : LabyErrorException {
// chỉ số version
private const long 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 {
enum LabyItem {
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
}
public enum Direction {
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 9
namespace BaiTH81.EditLaby {
class LabyPanel : Panel {
private const int ROWS = 20, COLS = 20;
private const int CSIZE = 30;
// Serializable trivia
private const long serialVersionUID = 1L;
//ma trận cell của mê cung ang hiệu chỉnh
private Labyrinth laby;
private LabyItem[,] Cells;
private int hcnt, ccnt;
//loi cell ang chọn
private LabyItem actionSelected = LabyItem.NULL;
private Bitmap agentbm, dotbm, spacebm, wallbm;
protected bool edit_enable = true;
private MyPoint npos, opos = new MyPoint(1, 1);
//hàm copy nội dung mê cung
public void setLaby(Labyrinth laby)
{
this.laby = laby;
hcnt = laby.Ysize();
ccnt = laby.Xsize();
Cells = new LabyItem[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 = new MyPoint(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
public void modifLaby()
{
for (int h = 0; h < hcnt; h++)
{
for (int c = 0; c < ccnt; c++)
{
laby.setContenuCase(h, c, Cells[h, c]);
}
}
}
public LabyItem ActionSelected
{
set { actionSelected = value; }
}
//hàm khởi to
public LabyPanel(Labyrinth laby)
{
this.MouseDown += new MouseEventHandler(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 = new Bitmap(myStream);
//to ối tợng nh bitmap cho cell space
myStream =
myAssembly.GetManifestResourceStream("BaiTH91.Resources.space.bmp");
spacebm = new Bitmap(myStream);
//to ối tợng nh bitmap cho cell space
myStream =
myAssembly.GetManifestResourceStream("BaiTH91.Resources.wall.bmp");
wallbm = new Bitmap(myStream);
//to ối tợng nh bitmap cho cell space
myStream =
myAssembly.GetManifestResourceStream("BaiTH91.Resources.agent.jpg");
agentbm = new Bitmap(myStream);
setLaby(laby);
this.ClientSize = new Size(ccnt * CSIZE, hcnt * CSIZE);
// v li mê cung
Refresh();
Trang 11
}
//tác vụ v bộ mặt giao diện của Button
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
int h, c;
for (h = 0; h < hcnt; h++)
for (c = 0; c < ccnt; c++)
{
Bitmap bm = null;
switch (Cells[h, c])
{
case LabyItem.NULL: bm = spacebm; break;
case LabyItem.POINT: bm = dotbm; break;
case LabyItem.WALL: bm = wallbm; break;
case LabyItem.AGENT: bm = agentbm; break;
}
g.DrawImage(bm, c * CSIZE, h * CSIZE);
}
}
private void Frm_MouseDown(object sender, MouseEventArgs e)
{
if (!edit_enable) return;
//tính tọa ộ cell mà user vừa chọn
int c = e.X / CSIZE;
int h = e.Y / CSIZE;
//thiết lập nội dung cho cell
Cells[h, c] = actionSelected;
//v li panel mê cung
//v li panel mê cung
Rectangle rc = new Rectangle();
rc.Location = new Point(c * CSIZE, h * CSIZE);
rc.Size = new Size(CSIZE, CSIZE);
Invalidate(rc);
}
}
}
11. 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à Labyrinth.cs, chọn button Add ể máy to 1
class mới. Viết code cho class này nh sau :
...
namespace BaiTH81.EditLaby {
[Serializable]
Trang 12
class Labyrinth {
//chỉ số version ể phục vụ việc ọc/ghi mê cung
private const long serialVersionUID = 1L;
//kích thớc mê cung
int width, height;
//ma trận các cell của mê cung
private LabyItem[,] carte;
//hàm khởi to mê cung 1 cách ngẫu nhiên
public Labyrinth(int width, int height)
{
this.width = width;
this.height = height;
carte = new LabyItem[width, height];
for (int h = 0; h < height; h++)
{
for (int c = 0; c < width; c++)
carte[h, c] = LabyItem.WALL;
/*{
if (i == 0 || j == 0 || i == width - 1 || j == height - 1)
carte[i,j] = LabyItem.MUR;
else
carte[i,j] = LabyItem.POINT;
}*/
}
}
//hàm khởi to mê cung theo nội dung ã có
private Labyrinth(LabyItem[,] copy)
{
carte = copy;
height = copy.GetLength(0);
width = copy.GetLength(1);
}
//hàm tr về ộ rộng
public int Xsize()
{
return width;
}
//hàm tr về ộ cao
public int Ysize()
{
return height;
}
Trang 13
//hàm tr về cell p
public LabyItem getContenuCase(MyPoint p)
{
return getContenuCase(p.y, p.x);
}
//hàm tr về cell ở vị trí x,y
public LabyItem getContenuCase(int y, int x)
{
return carte[y, x];
}
//hàm thiết lập nội dung của cell p
public void setContenuCase(MyPoint p, LabyItem element)
{
setContenuCase(p.y, p.x, element);
}
//hàm thiết lập nội dung của cell ở vị trí x,y
public void setContenuCase(int y, int x, LabyItem element)
{
carte[y, x] = element;
}
//hàm tính số cell point
public int getNbPoints()
{
int nbPoints = 0;
int h, c;
//lặp từng hàng
for (h = 0; h < height; h++)
{
//lặp từng cột
for (c = 0; c < width; c++)
{
if (carte[h, c] == LabyItem.POINT)
nbPoints++;
}
}
return nbPoints;
}
//hàm gii mã mê cung thành chuỗi vn bn
public override String ToString()
{
return "Mê cung chứa " + getNbPoints() + " cell Point";
}
Trang 14
//kiểm tra xem mê cung ợc tờng bao quanh hết không
public bool isEntourofWalls()
{
//duyệt từng hàng
for (int h = 0; h < height; h++)
{
if (carte[h, width - 1] != LabyItem.WALL) return false;
if (carte[h, 0] != LabyItem.WALL) return false;
}
for (int c = 0; c < width; c++)
{
if (carte[0, c] != LabyItem.WALL) return false;
if (carte[height - 1, c] != LabyItem.WALL) return false;
}
return true;
}
//hàm bao tờng khép kín cho mê cung
public void EntourofWalls()
{
int h, c;
for (h = 0; h < height; h++)
{
carte[h, width - 1] = LabyItem.WALL;
carte[h, 0] = LabyItem.WALL;
}
for (c = 0; c < width; c++)
{
carte[0, c] = LabyItem.WALL;
carte[height - 1, c] = LabyItem.WALL;
}
}
//hàm nhân bn vơ tính ối tợng
public Labyrinth clone()
{
LabyItem[,] copy = new LabyItem[height, width];
for (int h = 0; h < height; h++)
for (int c = 0; c < width; c++)
copy[h, c] = carte[h, c];
return new Labyrinth(copy);
}
}
}
Trang 15
12. 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à Labyrinth.cs, chọn button Add ể máy to 1
class mới. Viết code cho class này nh sau :
...
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace BaiTH81.EditLaby {
class LabyrinthLoader {
//hàm ọc mê cung từ file nhị phân
public static Labyrinth Load_Labyrinth(String fileName)
{
//ịnh nghĩa ối tợng FileStream miêu t file chứa dữ liệu ã có
FileStream fs = new FileStream(fileName, FileMode.Open);
//to ối tợng BinaryFormatter phục vụ ọc ối tợng
BinaryFormatter formatter = new BinaryFormatter();
//gọi tác vụ Deserialize ể ọc ối tợng từ file vào
try
{
Labyrinth laby = (Labyrinth)formatter.Deserialize(fs);
if (!laby.isEntourofWalls()) throw new LabyFaultEntourException("Thiếu tờng bao.");
if (laby.getContenuCase(1, 1) == LabyItem.WALL) throw new
BeginCellNotNullException("Tờng nằm ở vị trí xuất phát.");
fs.Close();
return laby;
}
catch (InvalidCastException e)
{
throw new IOException(
"File chứa nội dung không hợp lệ : phi là mê cung ã ợc ghi trớc từ máy
tính", e);
}
catch (TypeLoadException e)
{
throw new IOException(
".NET khơng biết kiểu mê cung", e);
}
}
//hàm ghi mê cung ra file nhị phân
public static void Save_Labyrinth(String fileName, Labyrinth maze)
{
//ịnh nghĩa ối tợng FileStream miêu t file chứa kết qu
FileStream fs = new FileStream(fileName, FileMode.Create);
//to ối tợng BinaryFormatter phục vụ ghi ối tợng
Trang 16
BinaryFormatter formatter = new BinaryFormatter();
//gọi tác vụ Serialize của formatter ể ghi ối tợng lên file tng ứng
formatter.Serialize(fs, maze);
fs.Close();
}
//hàm ọc mê cung từ file XML
public static void chargerLabyrintheEnXML()
{
throw new Exception();
}
//hàm ghi mê cung ra file XML
public static void chargerLabyrintheEnXML(String fileName, Labyrinth maze)
{
// to ối tợng phục vụ ghi file vn bn
StreamWriter writer = new StreamWriter(fileName, false, Encoding.Unicode);
writer.WriteLine("<Maze>");
for (int i = 0; i < maze.Xsize(); i++)
{
writer.Write("<Row>");
for (int j = 0; j < maze.Ysize(); j++)
{
writer.WriteLine(" <Element>" + maze.getContenuCase(i, j)
+ "</Element>");
}
writer.WriteLine("</Row>");
}
writer.WriteLine("</Maze>");
writer.Close();
}
}
}
13. 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à MyPoint.cs, chọn button Add ể máy to 1
class mới. Viết code cho class này nh sau :
...
namespace BaiTH81.EditLaby {
class MyPoint {
public int x;
public int y;
public MyPoint(int y, int x)
{
this.x = x;
this.y = y;
Trang 17
}
}
}
14. Ấn phi chuột vào phần tử gốc của cây Project trong cửa sổ Solution Explorer,
chọn option Add.New Folder ể thêm folder với tên là Resources, ta s dùng
folder này chứa các file bitmap ợc dùng trong chng trình.
15. Ấn phi chuột vào folder Resources, chọn option Existing Items, duyệt chọn 4
file bitmap son ở bớc 1 ể add chúng vào folder Resources.
16. Chọn 4 mục vừa add vào folder Resources ể hiển thị cửa sổ thuộc tính của
chúng, hiệu chỉnh li thuộc tính Build Action về giá trị mới là "Embedded
Resource".
17. Dịch và chy chng trình. Nếu có lỗi thì sửa, nếu hết lỗi thì chng trình s
chy. Hãy son thử từng mê cung theo sở thích và lu lên file ể dùng li cho
bài 9.1.