资源描述
课 程 设 计 报 告
课程名称:面向对象程序设计C++
设计题目:贪吃蛇
专 业:计算机科学与技术
姓 名:
学 号:
指导教师:李 晓 虹
2015 年 1 月 10 日
1 需求分析
1.1系统需求
操作系统:由于贪吃蛇游戏运行在windows操作系统上,所以要求计算机硬件至少能够运行windows XP及以上的版本的windows操作系统。
软件需求:贪吃蛇游戏使用控制台以字符的方式来显示画面,控制已经集成于操作系统中,无需额外的软件支持。
硬件需求:贪吃蛇游戏需要键盘作为控制命令的输入,需要显示器作为结果输出,因此需要计算机至少具备一个包含光标键的键盘,一个显示分辨率在800*600以上的显示器。
1.2功能需求
根据游戏的一般玩法,游戏应该有如图1-1所示的功能:
图 1-1
界面绘制:包括显示游戏初始界面,显示游戏结束画面,显示游戏运行画面三个主要绘制的界面,其中以游戏运行画面显示得最为频繁。
按键响应:应该响应两个部分的按键。一是接受用户的按键操作来控制蛇的运动方向,包括上下左右四个光标键。二是游戏控制按键,包括ESC退出游戏,SPACE开始游戏。
吃食判定:是对随机在游戏区域内产生的食物与蛇头重合否的判断。如果蛇头位置与食物位置重合,则判断蛇吃到食物,其身体增长一格,继而食物消失并产生新的食物,如果没有吃掉当前已经存在的食物将不会有新的食物产生。
死亡判定:即游戏失败判定。按照一般规则,当蛇头碰到游戏区域的边界或是自身身体那么就判定游戏失败,整个游戏将结束。
2 总体设计
2.1逻辑设计
控制台设置:由于客户机在默认情况下的设置是不符合程序的一些假设的,所以需要进行一些必要的设置。为使界面显示正常,应该将控制台的编码页更换为437,这样才能使用ASCII码的扩展字符。同时应该设置显示的字符字号,减小字号有利于显示效果。在屏幕的频繁刷新中控制台显示会出现闪烁的情况,应该使用缓冲,一次性输出以避免闪烁的出现。
游戏界面:由于使用控制台输出界面,则界面必然只能使用字符来模拟位图的显示。游戏的初始界面与结束界面均使用字符拼成,游戏运行时的画面则通过使用扩展ASCII码表中的扩展字符来实现。
蛇体结构:使用一个自定义的结构体,其包含X,Y两个坐标位置,两个这个结构体的指针,分别指向前一节点与后一节点。通过链表来实现蛇体的存储。并在全局变量中存储蛇体的开始与结尾。绘制时依次遍历并按坐标绘制即可。
2.2系统流程
游戏的流程如图2-1所示,有以下几个步骤。
初始化:将全局变量初始化,初始化蛇体链表,初始化控制台。
等待开始:进入循环,等待用户按下开始键,如果用户没有按下开始建,那么就绘制游戏初始界面,提示用户需按下开始键才能游戏。如果用户按下了开始键,就绘制游戏区域边界并跳出当前的循环。
游戏循环:等待用户按下方向控制键,如果用户并没有按下方向控制键,那么当前的蛇体按照预设的方向前进一格。否者就按照用户按下的方向前进,同时将全局变量中的方向指示变量的值由原来的值更改为用户选定的方向的值;接着判断蛇头的坐标是否与边界或者是自己的身体坐标重合,如果重合则说明游戏失败,将跳出当前循环。如果没有重合则接着判断是否与食物坐标重合,如果重合代表吃到食物,计分加一,蛇长加一,否则为没有吃到食物,不进行任何操作。接着就应该将蛇画在界面上,然后进行下一次游戏循环。
游戏结束:如果上面死亡判定通过将会进入这一个步骤,先绘制游戏结束画面,然后显示游戏得分。游戏变结束了。
图 2-1
除了正常的游戏结束外,还能够通过按下ESC键退出游戏,流程如图2-2所示。
游戏退出:在游戏循环中如果用户按下了ESC键,那么游戏将直接从游戏中退出,不会显示游戏结束画面也不会显示得分。
游戏重置:用户以除按ESC退出游戏的方式外的正常结束将经过重置后重新进入等待开始步骤。
图 2-2
3详细设计
3.1类设计
整个游戏有三个主要的类与几个全局变量分别如图3-1,图3-2所示。
Control类:主要实现初始化控制台设置,构建缓冲,按键监听,死亡检测,吃食检测,生成食物,输出缓冲到屏幕,获取控制状态,清空屏幕,重置等等功能。
UI类:主要实现界面的绘制,包括游戏初始界面,游戏结束界面和边界的绘制使用DrawStart()、DrawEnd()、DrawBorder()三个函数实现。这里的绘制并不是直接向屏幕绘制,而是向缓冲绘制。
Snake类:主要实现蛇的运动,自身的初始化,重置的功能。
图 3-1
全局变量文件:如图3-2所示,它有定义的一个文件包含标志_GLO_,因为每个类文件都有一些变量在全局文件中被定义,但是多重引用会导致重定义,使用包含标志符可以确保文件只会被引用一次,从而避免重定义的冲突出现。
SetConsolFont是一个未在源文件中公开的Win API函数,使用它之前需要提前定义,之后再在使用的时候直接从系统dll中获取入口点。
四个方向的定义,分别是上下左右四个键值,用于响应用户按下键盘上的光标键后的赋值与比较。
Buffer是一个屏幕缓冲指针,它将指向一个和游戏显示区域大小一致的内存区域,所有对屏幕的写操作将先写入这个缓冲然后再一次性输出到屏幕。
Width和height指明屏幕大小,用来初始化buffer的大小,绘制图像时也需要通过这些数据由屏幕上的二维坐标转换到buffer中的一维线性位置。
Length是蛇长度,依据长度可决定绘制蛇的时候循环的次数。
Direction是方向变量,存储用户当前按下的方向键的键值。
Getfood是获得的分数,也可称作吃到食物的次数,最终得分是该数与一百的乘积。
waitEat是游戏区域内已有食物总数,只是0或者1.
Head、tail。Seq分别是指向蛇的头、尾和遍历变量的指针。
GameStart[]、GameOver[]分别是指向开始与结束画面字符的指针数组。
图 3-2
3.2关键代码实现
Control类在初始化中对控制台的设置:
buffer = new char[width*height];
memset(buffer, ' ', width*height*sizeof(char));
//开辟内存地址存放缓冲,并将缓冲内容全部置为空格
HMODULE hKernel32 = GetModuleHandle(L"kernel32");
SetConsoleFont = (PROCSETCONSOLEFONT)GetProcAddress(hKernel32, "SetConsoleFont");
//从kernel句柄处获得SetConsolFont函数的入口地址
SetConsoleOutputCP(437);
//设置控制台文字页为437
std::ostringstream sst;
std::string str = "";
sst << "mode con cols=" << width << " lines=" << height;
str = sst.str();
system(str.c_str());
//设置控制台的宽与高
system("Color F0");
//将控制台颜色更改为白底黑字
OutPut = GetStdHandle(STD_OUTPUT_HANDLE);
//获取控制台输出流句柄
CONSOLE_CURSOR_INFO cci;
cci.bVisible = 0;
cci.dwSize = 1;
//创建控制台光标大小为一且不可见
SetConsoleCursorInfo(OutPut, &cci);
//隐藏控制台的光标显示
SetConsoleFont(OutPut, 0);
//设置控制台字体为第一个字号
死亡判定检测,采取字符比对的方式,因为游戏区域大部分是空格字符,除食物外,只有边界字符与蛇的字符,所以可以简化判定:
if (buffer[head->y*width + head->x]==char(186)){ return true;}
//碰到左右边界,将死亡
else if(buffer[head->y*width + head->x]==char(187)){return true;}
//碰到右上角边界,将死亡
else if(buffer[head->y*width + head->x]==char(188)){return true;}
//碰到右下角边界,将死亡
else if (buffer[head->y*width + head->x]==char(200)){return true;}
//碰到左下角边界,将死亡
else if (buffer[head->y*width + head->x]==char(201)){return true;}
//碰到左上角边界,将死亡
else if (buffer[head->y*width + head->x]==char(205)){return true;}
//碰到上下边界,将死亡
else if (buffer[head->y*width + head->x]==char(254)){return true;}
//碰到蛇身体,将死亡
else { return false;}
//说明遇到的是空格字符,是安全的。
按键检测,由于蛇在向一个方向运动的时候是不能够再向反方向运动的,所以必须有一定的处理:
if (GetAsyncKeyState(VK_DOWN) && 0X8000){
if (direction != 2)direction = Down;
}
//按下了↓,且上一次按下的不是↑,那么就更改方向值为当前值
if (GetAsyncKeyState(VK_UP) && 0X8000){
if (direction != 3)direction = Up;
}
//按下了↑,且上一次按下的不是↓,那么就更改方向值为当前值
if (GetAsyncKeyState(VK_LEFT) && 0X8000){
if (direction != 1)direction = Left;
}
//按下了←,且上一次按下的不是→,那么就更改方向值为当前值
if (GetAsyncKeyState(VK_RIGHT) && 0X8000){
if (direction != 0)direction = Right;
}
//按下了→,且上一次按下的不是←,那么就更改方向值为当前值
Main函数中,在游戏结束的时候需要显示玩家的得分,这里使用对话框的形式给出。由于使用MessageBox函数显示分数需要显示由int转换成字符的分数,所以使用了CString类,这里需要#include "afxwin.h"。
char sc[4];
//转换的分数存放数组
_itoa_s(getFood, sc, 10);
//将int转换为char[]
CString ff(sc);
//由char[]转换为CString,方便后面作字符拼接
MessageBox(NULL,ds+ff+so,L"游戏结束!", MB_OK);
//显示拼接的分数字符结果
4系统调试
在调试的时候编译阶段就出现了错误,错误提示如图4-1所示。其原因是使用CString类所导入的afxwin.h文件引起的。它要求必须有_AFXDLL的定义或者是运行在MD模式下,这里在项目设置中更改调试模式为MD即可。
图 4-1
在没有对蛇头与蛇身体作检测的时候会出现问题,如图4-2所示,蛇能够穿过自己的身体,这与游戏规则是不相符的。所以需要对蛇头与蛇身的重合作检测。同样的在蛇与游戏区域边界没有作检测的时候,如图4-3所示,蛇的字符将会覆盖边界的字符,随着蛇离开后将会被变成空格符,所以也许要对蛇和边界作重合检测,如果重合后则直接判定为死亡,接着就退出游戏。
图 4-2
图 4-3
5结果分析
经调试后的运行结果如图5-1、图5-2、图5-3所示。
游戏开始画面如图5-1所示:
图 5-1
游戏画面如图5-2所示:
图 5-2
游戏结束画面如图5-3所示
图 5-3
6总结
经过几日的开发与调试,贪吃蛇游戏最终开发完成了,这次个游戏实现了在控制台上接受用户按键操纵蛇在游戏区域内移动,触碰到自己或是边界的时候结束游戏,吃到食物则增加蛇的长度和得分,直到游戏结束就显示得分。
虽然成功的实现了游戏的基本功能,但是由于时间的缘故,没有实现游戏相关参数的自定义设置,比如自定义窗口的宽与高,设定初始蛇的长度,设定最大同时出现食物的长度等等,还没有实现得分排行榜,游戏闯关模式,穿墙功能等等特殊的游戏特性。
即使有遗憾,但是通过亲手写代码,查资料,对C++的使用与Windows API的理解有了进一步的加深,收获颇丰。
附件 程序源码:
全局变量:
#include "windows.h"
#define _GLO_ ;
#define Left 0;
#define Right 1;
#define Up 2;
#define Down 3;
typedef BOOL(WINAPI *PROCSETCONSOLEFONT)(HANDLE, DWORD);
PROCSETCONSOLEFONT SetConsoleFont;
static char * buffer;
int width;
int height;
int length;
int direction;
int getFood;
int waitEat;
struct SnakeSection{
int x;
int y;
SnakeSection* pre;
SnakeSection* next;
};
SnakeSection * head;
SnakeSection * tail;
SnakeSection * seq;
char * GameOver[] ={
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
"@@@@@@@@@@@@@@@@@@@@@@@@#@@@@@@@@@@@@@@@@@@HH@@@@@@@@@#@@#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@GS9XB&B@@@@@@@",
"@@@@@@@@@@@@@##M#@@@@@@@@@@@@@@@#@@@@@#@@@&39X#@@@@@@@@@@@@@@@@@@@@#@@@@#@@#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#XXh581SSM@@@@@@",
"@@@@@@@@@@@#HGSG&#@@@@@@@@#@@#@@@@@@##@@@@AS91SH@@@@@@@@@@@#BMBB@#@#@#@@@@@@@#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&;SXGX3SA@@@@@@@",
"@@@@@@@@@@@@MX3G&G#@@@@@@@@@@@@@@@@@@@@@@#&3838XM@@@@@@@#@@#GX8XXA@@@@#@@@@@@@@@@@@@@@@@@@@@@@@@@@@#@@@@@@@@@B&A55X5sH@@@@@@@",
"@@@@@@@@@@@@@M&&&&B@@@@@@@#&HMB#@@@@#@@@@@BG8ABH#@@@@@@@@@@@8sr5&#@@@#@@@M&H@H&S##B#@@@@@@@@@@@@@B&BBBM@@@@@@@@@M##&M@@@@@@@@",
"@@@@@@@@@@@@@@H&@##@@@@@@@BG&BGG&HMHH@@@@@#HM@@@@@@@@@@@@@@#A3SG#@@@@@@@@#XBX391XBGM@@@@@@@@@@H&A93&AGXA@@@@@@@@@@@@@@@@@@@@@",
"@@@@@@@@@@@@@@@#@@@@@@Gss1shss1s9X1;ir&@@@@@@@@M1s1ssss1sX@@@@##@@Mhs111sA@MH33GH##hs111sA@@Gsiirsrii;iirssssssssrS@@@@@@@@@@",
"@@@@@@@@@@@@@@@@@@@BHB1 .:::::;SAh,:.G@@@@@#HBX ,:, 5BHB@@@@@B. 3HXMH&A&&X X@@5 ::::,:::,,,,,,.1@@@@@@@@@@",
"@@@@@@@@@@#@@@@@@@@1 . s@@@@@@#@@@@@@@@@@@A .. A@@r . h@@@@@B: ...... 3@@A........ &@@S ... i#@M&&&#@@###@@@@@@M&AHB#@@",
"@@@@@##MMM#@@@@#9SS; r93X@@@@#MBB@#BM@@@&5S1 ,S39#@@X39r ;SS9#@B: ..... iSS1 ...... X@@S ... r@@@H&B&&@@@@@@@@@@BX39XH@@",
"@@@@@#MHA&B#@@@#, . 9@@@@@@MA8SS5X8G#@@3 . ;@@B88S&@@3 . ;#@B: ....... ........ &@@S ... i##B95GXSA####@@@@@BHA&M@@@",
"@@@@@@BG989H@@@#; ... 3@@@@@A......:;:G@@9 ... ;@@8h99S&@3 ... i#@B: .... .. ..... &@@S .....,,...., ,. S@@@@@@@@#@@@@",
"@@@@@@MHXXAB#@@#; ... 3@@@#@B111. . 8@@9 ... ,8X39995SXs ... i#@B: ... rhhi :hhs..... &@@S ... ,11hh1111111s8@@@@@@@@@@@@@",
"@@@@@@@@M#@#@@@#: . 3@@@A99XMA: ... 8@@9 ..... .... i#@B: ... X@@9 s@@B, ... &@@S ... r@@AA@@@@@@@@@@@@@@@@@@@@@@",
"@@@@@@@@@@@@@@@@A&Ai :r;3B93X&H: ... 8@@9 ... :X&&&&&&&A1 ... i#@B: ... G@@B&&H@@H, ... &@@S ... r@MS1H#@@@@@@@@@@@@MH@@@@@@",
"@@@@@@@@@@@@@@@@@@@Sir, rX3GAGG: ... 8@@9 ... :#@@@@@@@@3 ... i#@B: ... 8@#@@@@@@H. ... &@@S ... iG89835&A&&&&&AAB@@#M@M#@@@",
"@@@@@@@@@@@@@@@@@@@@@@5 9@@3 ,M@######@5 ;#@B. 8@#####@@H X@@5 19HS5A@@M@@@",
"@@@@@@@@@M898B@@@@@@@@A8GG8G8888GGGG88H@@H88888G#########A88888X#@MG88888B@@@##@@@MG8GG88B@@A8GGGGGGGGG888888888GAH95iiG#@@@@",
"@@@@@@@@@A51GM@@@@@#@@@@@@@@@@@@@@@@@@@##@@@@@@@#########@@@@@@@###@@@@@@@#M#@@@@@@@@@@@@@@@@@###@@@@#@@@@@@@@@X9XG&BHHGB@@@@",
"@@@@@@@@M855GXM@@@@@@@#BBMH&B@@@@@@@################################@@#ABB&AHM@@@@@@@@@@@@@@@AGG&S&BA&&#@@@@@@@MAXh8XA@@@@@@@",
"@@@@@@@@@&S1SB@@@@@@@A899GXXM####@@@@####@@@@@@@#########@@@@@@@##@HAX&&X888XX#@@@@@@@@@@@@@#XG&88BBBBA@@@@@@@@@@@@#XX#@@@@@@",
"@@@@@@@@@@MGG&M@@@@3s18GHAHH31r5SS1B@@@#@Xs111shM@#####@@8s111sS#@M1i;r1ssrii;rsssssssssrA@@8irrir1sssssssss11sG@@@@@@@@@@@@@",
"@@@@@@@@@@@@#M#@BBBi :i1115;,,, GBBM@@3 ,M@##@@M9H5 ;#@B, .,,,:,,,,,,,,,,.&@@5 ,,,,,,,,, 1MBM@@@@@@@@@@",
"@@@@@@@@@@@@@@@#; ... S@MMMM##@M: ... 8@@9 ... :#@@MHH85&S ... i#@B: ... 8@#@@##@@@######@@@S ... i#@#@@##@@1 ... s@@@@@@@@@@",
"@@@@@@#@@@@@@@@#: .. 3@@@@@@@@#: . 8@@9 ... :##BHH&9X#S ... i#@B: ... G@@#M@@HH@@@@@@@@@@S ... r@@@@#@@@@1 .. s@@@@@@@@@@",
"@@@@@@@@@@@@@@@#; ... 3@@#MB#@@M: ... 8@@9 ... ;MA8H#####5 ... i#@B: ... GBX83XH&AB#M#@#@@@@S ... i@@@&GB@#@1 ... s@@@@@@@@@@",
"@@@@@@@@@@@@@@@#; ... 3@@#BAB#BM: ... 8@@3 ...;;iM@@5,:,.. ;#@B: .....,,,,,;:,:;;;H@@@@@S ... r@@@&XB1,;. r@@@M@@@@@@",
"@@@@@@@@@@@@@@@#; ... 3@@@&3GBH&: ... 8@@X1hr .. 3XG; . :h1S#@B: ... i11111s11sss1B@@@@@S ... ;GG8595: ihh1113@@#X8XHM@@",
"@@@@@@@@@@@@@@@#; ... 3@@XSS38AX: ... 8@@@@@& ... .. 1@@@@@B: ... X@@#@@@@@@@@@@@@@@@S .... . G@@@@@@@@MH8GAH@@",
"@@@@@@@@@@@@@@@#: . 9@AGBA8G#M: . 8@@@@@#&&8 ... 1&&H@@@@@B: ... X@HABM#HB@@@@@@@@@@S ... ;&&G. .. ;ri8@@@@@#@#M@@@@",
"@@@@@@@@@@@MM#@#1ii, 5&8&A&88A&, .;i;X@@BAAM@@Mrii...;i;G@@@@@@@@B: ... 3X8SG&XGXHAAAAAAM@@S ... r@@#sii,.. 1HAH@###@@@@@@",
"@@@@@M#@@@AXAA#@@@@r &@@@@#hrsh&@@@@#: X@@@#B#@##@@B. X@@5 ;@@@@@@; r@3hS#@@@@@",
"@@@@@H&A&XXXAHHM@@@X988888888888888M@#S3@XS5hH@@@@#G98B@@@&SMH3X@@#G888888888888888888889B@@A98889X@@@@@@X98888889X@&S5#@@@@@",
"@@@@@@HXAM##@@@@@@@@@@@@@@@@@@@@@@@@@#&&#@@@@@@@@@@@@@@#@@MG8;5&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@XXM@@@@@@",
"@@@@@MA@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#@@@@@@#@@@@@@@@@H3sr3&#@@@@@@##@@#@#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
"@@@@@#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#@@@@#@@@@@@@@@@#@@@@h 158H@@@#@@@@@####@MS9@@@@@#83993B#&9GG9A#3S8889HG59899M@@@@@@@@@@",
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#@@@M9sXMM@@#@@@@@##@##@@@B ;@@@@@S 8MA rA:iGG58B..8GG&#s XM9 s@@@@@@@@@@",
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#@@@@@@@#BB#@@@@@@@@@@@@#@@@@@@B :####@5 G@B ;M9SXXisH,.GXGH@s 5s.h&@####@@@@@",
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#@@@@@@@@@@@@@Mhh9993HM3S935HM95G819M5h8889H91H&1h&@X19#@@@@@",
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#@@@@@@@@@@@@@@@@@@@@@@@@@#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@##@@@@@@@@@@@@@@@@@#BAB#@@@@@",
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#@@@@@#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
};
char * GameStart[] = {
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
"@@@@@@@@@@MHAAHM@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@GSH@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
"@@@@@@@Xs;;irri;iX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@r 8@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
"@@@@@Hi 1&#@@@@#AB@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@s 8@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
"@@@@H. X@@@@@@@@@@@@@@31A3riX@@@H5riirSM@@@@@#8siii1&@@@@@@&hiirs8s 8@@MhhB@@@@@A13@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
"@@@@1 h@@@@@H&&AHB@@@@: :3AAB@@5 sXBBG:.&@@@A:,9HBAh h@@@#1 iGHHGs 8@@@S r@@@@#, &@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
"@@@@r S@@@@@hrr; i@@@@; 9@@@@@G ,X&XX&5 ;@@#: S&XXXX &@@3 s@@@@@@i 8@@@@1 3@@@s G@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
"@@@@8 :#@@@@@@@X i@@@@; A@@@@@S :hssss1h3@@M 11sss1hhH@@1 3@@@@@@s 8@@@@#; H@9 S@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
"@@@@@5 ,X@@@@@@G ;@@@@; &@@@@@A ,B@@@@@@@@@@r 9@@@@@@@@@@8 :H@@@@G. 8@@@@@B ;& r@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
"@@@@@@&s.:r1h1r:,5@@@@; &@@@@@@&;.i1h1irM@@@#h.:shhsi8@@@@9, ihhr1; 8@@@@@@X ,#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
"@@@@@@@@#AG998XH#@@@@@BH#@@@@@@@@HG99GA#@@@@@@M&898XB@@@@@@@A89GH@MH#@@@@@@@, A@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#@B; G@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@BB@B&X89GH@@@@@@@@@@@@@@@@@@@@@@@@@@@@1;:rA@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@AS1S911srhhs9M@@@@@@@@@@@@@@@@@@@@@@@@@@MBM@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@B8X19ASs: S@@5,9M@@@@@@@@@@@@@#BAAH#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@8SB@@@@@@@@@@@@@@@@@@@@@@@",
"@@@@@@@@@@@@@@@@@@@@@@@@@@8s1hsiS19H3:,,sXXhrii5H@@@@@@@@@Gr:iiii;S@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@; X@@@@@@@@@@@@@@@@@@@@@@@",
"@@@@@@@@@@@@@@@@@@@@@@@@#8i,s5ri::,,;rs1i,:iihh,:X@@@@@@@S ;B@@@@BA@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@i X@@@@@@@@@@@@@@@@@@@@@@@",
"@@@@@@@@@@@@@@@@@@@@@@@@#G5riri::::::::,,:::i1i: h#@@@@@@1 i#@@@@@@@@@@9hHGhr;r9#@@@@@X5siiiSB@@@@@i X@@@X15H@@@#9siir5A@@@@@",
"@@@@@@@@@@@@@@@@@@@@@@@@@@Xr;,,,,,,,,,;rrirri:.:iG@@@@@@@#5, i3A@@@@@@@; :SXHXr i#@@@#h9ABB9 .B@@@@i &@
展开阅读全文