TCP-IP协议与网络编程课程设计
一、软件背景介绍
双升游戏又称拖拉机升级和双倍升级,是升级(一副牌)游戏的衍生版本,现在全国范围内非常流行。 双升采取四个玩家组成两对进行比赛的游戏模式。在原来升级游戏规则的基础上,将牌数由原来的54张(一副牌)增加到108张(两副牌),采取以每盘获取分数的多少来决定升级级数的游戏方式,增加了“对子”“连对”“反主”等新游戏规则,让游戏中的牌型组合更丰富,游戏结果也更加变化莫测。
双升,俗称拖拉机,是一项在京城乃至全国广为流传的扑克竞技运动,它健脑益智、活跃身心,是对选手的判断、决断、记忆、逻辑推理乃至团队合作等多方面能力的综合考验。 超级版双升以普通版双升的游戏规则为基础,将主打方最多可升级级数由原来的3级增加到6级,并增加了反主金币翻番的新规则,使游戏过程变的更加紧张刺激。
游戏由四人进行,利用两副牌共108张进行游戏。游戏时,位置相对的玩家为同组(对家),第一局时报主的那方为当前庄家,另一方为捡分方。第一局游戏结束时,按照当轮游戏结果确定下一局的庄家继续进行游戏。以次类推。四个玩家按照逆时针方向依次摸牌,每人每次摸一张,直到最后剩下8张牌为止。此时每人手上有25张牌,最后剩下的8张做为底牌交由庄家手中进行盖底牌。
第一局四个玩家在起牌过程中,谁先起到任意花色的当前级牌(默认时为2)附带一个张王(大王只能报红色主牌(红杏和方片)小王只能报黑色主牌(黑桃和梅花))并亮出,即成为该局的庄家,和自己的对家成为当前的主打方。另一方则成为捡分方。 此花色即成为该局的主花色。(抢报规则仅限于第一局游戏时)
当起牌过程和报主结束后,该局的庄家拿起剩下的8张底牌和自己手上的25张牌组合在一起进行整理,然后再选取8张进行盖底牌。盖底牌过程中,底牌只有当前盖底牌的玩家可见。底牌在游戏出牌过程中不可更换,待一局游戏结束后才可亮出给所有玩家查看。 反主和盖底牌结束后,由庄家开始,按照逆时针方向依次出牌。每轮出牌完毕后,按照每个玩家牌的大小,决定第二轮由谁先出牌。
单张:每轮先出牌玩家打出一种花色的副牌单张时,其他玩家必须也跟出该花色的单牌,在没有该花色副牌时可出其他花色副牌代替或用主牌单张杀。对子:每轮先出牌玩家打出一种花色的副牌对子时,其他玩家必须也跟出该花色的对子,在没有该花色对子时必须跟出该花色单张,没有该花色牌时可选择出其他花色副牌代替或用主牌对子杀,但若是两张主牌单张是无法杀掉对子的。连对:每轮先出牌玩家打出一种花色的副牌连对时,其他玩家必须也
- 1 -
TCP-IP协议与网络编程课程设计
跟出该花色的连对,在没有连对的情况下必须跟该花色的对子,没有对子的情况下跟该花色单张,依次类推(出牌数量总和需和连对牌数一致)。若用主牌杀连对时,主牌也必须是相同对数的连对才可。
下面是我的游戏画面的一些截图:
(1)首先是游戏服务器的运行,开启服务器后就可以登录进行游戏
图1 游戏服务器截图
(2)接下来是游戏登录界面,输入用户和密码后就可以登录到游戏
图2 游戏登录界面截图
- 2 -
TCP-IP协议与网络编程课程设计
(3)接下来是游戏主界面,输入连接成功后就可以与玩家对战或者自己单机
图3 游戏玩家连接界面截图
(3)接下来是游戏进行中的主界面,最后可以比较分数分出胜负
图4 游戏进行界面截图
- 3 -
TCP-IP协议与网络编程课程设计
二、核心算法思想
首先是功能需求,定义一个牌类,封装一张牌的一些信息,对单个牌的一些操作。所以这是最基础的。后面定义的一些对象都是在这个基础上进行操作的。
另外就是游戏中一些规则的制定。出牌是否符合规则,这里主要包括两点,一个是没有前家出牌的情况下的出牌,一个是有前家出的牌,本家与前家出牌大小规则的制定。
主要是通过牌的张数来判断出牌的可能牌型,然后再看是否符合规则。比牌大小是在出牌符合规则情况下,对应牌型的大小。
发牌,双升发牌,定义一个集合,用两个循环,一个控制牌的权值,一个控制牌的花色,一张牌就确定下来了,把每张牌加入到集合中,另外再加上大小王。但是这样生成的牌集合是基本有序的。对这个集合进行操作,随机生成两个数,这两个数表示要交换集合里面的两张牌的位置,交换一百次。然后再把这个集合划分四份。三份相等的,另外一份三张,分别分给四个数组。
双升有四方牌,四个用户,他们都有一些共性,像都包含一个集合啊,都包括出牌,还有如果是地主的话,就要进牌。
操作的需求,在地主点选牌的算法中,我们只要点击每张牌的可见区域,它的状态就会随之变化。我们通过上图可以发现,每张牌选中之后它会遮盖前面几张牌的可见区域,而后面几张牌会影响自身的可见区域,所以每张牌点选之后与前面几张和后面几张牌有关系。第一张牌除外,第一张牌选中之后只有它自己的可见区域会发生变化,因为第一张牌前面没有任何牌。这样当我们选中牌的时候既要改变自身得可见区域也要改变前面几张被选牌的可见区域。这样在你点选牌的时候根据鼠标坐标,来判断和牌队列中的哪张牌的可见区域碰撞,然后确定牌的索引更改与之对应牌的可见区域就能实现选牌操作。
第一种:在牌的队列中只有自己被选中,会响应自己的可见区域,和前面一张牌的下部分可见区域。
这种是最简单的,自己被选中的时候,首先改变的正常的可见区域然后+选中之后的可见区域。
第二种:在牌的队列中会影响其他牌的可见区域
前面三张牌有被选中的(选中之后前面牌的可见区域会被影响)
当前面几张牌中有选中状态的牌,它们的可见区域会被影响,正常的可见区域不会被影响。而影响的可见区域也只是被改变了,影响的可见区域我们可以用一个公式来表示,当我
- 4 -
TCP-IP协议与网络编程课程设计
们选中牌的时候,后面三张牌有有被选中的时候。我们首先用第一种:在牌的队列中只有自己被选中的方法来计算出正常的可见区域和可见区域。
这样当我们选中牌的时候既要改变自身得可见区域也要改变前面几张被选牌的可见区域。这样在你点选牌的时候根据鼠标坐标,来判断和牌队列中的哪张牌的可见区域碰撞,然后确定牌的索引更改与之对应牌的可见区域就能实现选牌操作。
三、核心算法流程图
下面给出的是核心算法流程图, 根据分析后的程序结构图设计出相应的流程图。双升的内容主要包括游戏开始,画背景,显示分数和要出的牌;同时可以响应Esc按键,提示是否退出程序。
当前用户出牌 其它用户出牌 判断出牌方 开 始
显示手中的牌 显示选择打出的牌 显示选择打出的牌 显示剩余的牌 显示剩余的牌
- 5 -
结束
TCP-IP协议与网络编程课程设计
图5 核心算法流程图
开始 是否优先出牌 否 否 判断是否比上 家的牌大 是 不合法 出牌
结束
图6 核心算法流程图
四、源代码
下面给出的是本次开发的源代码:
Managers模块:这是本游戏的核心模块之一。 void GameStart();//游戏初始化,发牌。 void SendCard(); //发牌
- 6 -
是 TCP-IP协议与网络编程课程设计
void CardsInfo(Card ca[],int &num,int &min,int &type);//用来得到牌的信息。到底是炸弹,连牌,还是什么的。 void PlayS(int min2,int type2,int num2);//设置与发出声音,用来通知玩家所打的牌的大小与种类。 void Updata();//根据游戏状态的改变,从而设置游戏界面的状态。
Card模块:记录了一张牌的所有信息,包括大小、类型、是否被玩家选中。
CProgramView模块:编辑游戏界面 函数:
void DrawCardOut(int k);
void DrawLeft();//绘出剩下的地主的牌,当地主还没决定的时候画的是牌的背面,决定地主
//后画出地主的牌
void DrawPlayername();//根据传入的字符串,绘出玩家的名称 void OnPass();//点击过牌按钮后的响应函数 void OnSendCard();//画出当前玩家所出的牌
int SelectNum(int num,int mx,int my);//判断玩家点牌后具体点的是哪一张 void DrawOtherCard();//画出另外两个玩家还剩下的牌,以及
//他们刚刚出牌
void DrawMyCard();//画出当前玩家手中牌 void OnCancel();//点击退出按钮后的响应函数 void OnOK();//点击确定按钮后的响应函数 virtual ~CProgramView();
CString PlayerName[3];//用来存放三个玩家姓名的字符串 void PrintAll();//整体重画
CChat模块:基本对话框的聊天模块. CNet模块:网络控制 CServer模块:网络主机配置
NetControl模块:用于设置网络各方面的问题。 函数:
void StartCards();
void SendGetReady();
void SendCards(Card *c,int action); NetControl(CProgramView *p); void Broadcast(char * pMsg); void OnSorc();//网络配置 void OnSet();//设置问题
void OnOpen();//已经打开网络配置
void FetchMsg(CNet *pRequest);//网络信息处理
//Managers模块:
// Added by ClassView
//Managers.h文件
void SendMsg(CNet *pSend, char const *pMsg);//发送消息
CNet* ConnectServer();//网络连接 #include \
#include \class Managers
//#include \
- 7 -
TCP-IP协议与网络编程课程设计
{ public: { {
Card *Ca=PlayCards[pl];//用Ca 指针来代替Player[pl],使程序简单容易理解 if(j!=20) { }
Ca=PreOut;//现在把CA指到这里 CardsInfo(Ca,num2,min2,type2);
if(OutCards[0].Num==16)//上次没有人走牌 {
PreOut[j].Num=16;//表示此后的都没有牌了
// -1游戏准备中,选地主
int Power;//计算当前游戏如果农民胜利则每人得的分 bool m_CardSound; void ClearCard(); int t;
//重新计时
// 0-2 游戏玩家出牌
NetControl *pControl;
void PlayS(int min2,int type2,int num2); bool DoMsg(int num,int action); void GameStart(); virtual ~Managers();
Card PlayCards[3][20];//最多20张牌 int PlayerAc;//这台机器上的玩家 int PlayerMain;//地主
Card OutCards[20];//走的牌,一次也最多出20张牌 int OutPlayer;//走牌的玩家
Card Sendleft[4];//记录剩下的3张牌 int Game_State; void Updata();
// -2游戏没开始
//游戏初始化,发牌。
//主机
Managers();
bool MainComputer;
//是主机则是true 不是则为false;
CProgramView * m_pView;
int PlayerMaininfo;//记录有几个玩家选择放弃地主 如果都放弃则游戏结束 void SendCard(); //发牌 void SortCard(Card ca[]); int p[3];
// 3-5 对应0-2玩家胜利
void CardsInfo(Card ca[],int &num,int &min,int &type);
bool Managers::CheckCard(int pl)
void Managers::SendCard()
- 8 -
TCP-IP协议与网络编程课程设计
{ }
void Managers::CardsInfo(Card ca[],int &num,int &min,int &type) {
void DrawLeft();//绘出剩下的地主的牌,当地主还没决定的时候画的是牌的背面,决定地主
//后画出地主的牌
void DrawPlayername();//根据传入的字符串,绘出玩家的名称 void OnPass();//点击过牌按钮后的响应函数 void OnSendCard();//画出当前玩家所出的牌
int SelectNum(int num,int mx,int my);//判断玩家点牌后具体点的是哪一张 void DrawOtherCard();//画出另外两个玩家还剩下的牌,以及
//他们刚刚出牌
void DrawMyCard();//画出当前玩家手中牌 void OnCancel();//点击退出按钮后的响应函数 void OnOK();//点击确定按钮后的响应函数 virtual ~CProgramView();
CString PlayerName[3];//用来存放三个玩家姓名的字符串 return false;
if(action==1)//唯一用得到前面1个参数的地方 { } { }
t=30;
Game_State=(Game_State+1)%3;//直接更改游戏玩家
PlaySound(\不要.wav\return true;
Card &Ca=PlayCards[PlayerAc][num]; return true; int i,j,k;
bool Cards[55]={false};
{
Card &Ca=PlayCards[i][j];
k=54;//保证必进入While循环进行随机
for(i=0;i<3;i++)
//对应54张扑克,其中Cards[54]做初始化用 必须为true;
//其中0-51为4个1-13 52是小王 53是大王
bool Managers::DoMsg(int num, int action)
else if(action==3 && OutPlayer!=PlayerAc)
- 9 -
TCP-IP协议与网络编程课程设计
protected: };
CProgramView.cpp文件 { }
CProgramView::~CProgramView() { }
CBUTTON.Creat(_T(\确定\按钮的caption属性,按钮的显示 { //
MessageBox(\你点击了确定按钮\改变 m_isReady = true;
if(!pControl->m_Isserver)pControl->m_ready[1] = true; //判断是否为真
WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, // 按钮也是一种窗体,同样有不同
//风格,通过对常量或运算进行组合,达到一定的效果,这些常量的含义可以参考MSDN CRect(660,410,765,450), //这个参数指出按钮在视图中左上角和右下角坐标,在 //确定了按钮位置的同时也确定了其大小 this,//这个指针指向按钮这个窗体的父窗体
ID_OK);//这是刚才为按钮定义的常量,按钮的控制ID if(!pControl->m_Isserver) else
pControl->Broadcast(\退出游戏\delete pControl;
pControl->SendMsg(pControl->m_pSocket,\退出游戏\// TODO: add construction code here
pControl= new NetControl(this);//创建一个指向NetControl的指针 isDrawed =false;//画发牌了没有,发牌完成了没有
//将按钮点击事件同响应函数联系起来
ON_BN_CLICKED(ID_OK, OnOK)//让ID_OK所指的对象响应单击(ON_BN_CLICKED)事件,事件 void CardReady();//用来画还没发牌时牌的情况 void PrintAll();//整体重画 friend class NetControl; virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#ifdef _DEBUG
#endif
CProgramView::CProgramView()
void CProgramView::OnOK()
- 10 -
TCP-IP协议与网络编程课程设计
}
void CProgramView::OnCancel()//OnCancel()//响应取消按钮的点击 { // }
void CProgramView::PrintAll() {
CDC *pdc=GetDC();
pdc->BitBlt(0,0,800,600,&Background,0,0,SRCCOPY);//开始贴图处理 if(manager.Game_State==-2 || manager.Game_State >=3) { } { // }
if(manager.Game_State >-1 && manager.Game_State <3)DrawLeft(); if(isDrawed)DrawCardOut(3); if(isDrawed)DrawMyCard();
pdc->SetBkMode(TRANSPARENT); //设置背景模式 pdc->TextOut(545,435,\准备\CardReady();
pdc->SetBkMode(TRANSPARENT);
if(m_isReady)pdc->TextOut(350,394,\准备\ //输出准备
if(pControl->m_ready[0])pdc->TextOut(220,260,\准备\在220,260,\输出准备 if(pControl->m_ready[2])pdc->TextOut(530,268,\准备\
MessageBox(\你点击了取消按钮\if(!pControl->m_Isserver) else
pControl->Broadcast(\退出游戏\exit(0);
//是否退出游戏
pControl->SendMsg(pControl->m_pSocket,\退出游戏\
if(!pControl->m_Isserver && pControl->m_ready[0] && pControl->m_ready[1] &&pControl->m_ready[2]) { }
if(manager.Game_State>=0 && manager.Game_State<3) //判断状态 { }
manager.Game_State=-2; //如果为2的时候要进行相应的处理 isgoon=true; return;
if(manager.Game_State>=3 )
pControl->m_ready[0] = false; //为假的时候要进行判断测试 pControl->m_ready[1] = false; //为假的时候要进行判断测试 pControl->m_ready[2] = false;
//为假的时候要进行判断测试
if(manager.Game_State==-1)
- 11 -
TCP-IP协议与网络编程课程设计
// }
函数名称:CardReady() 函数介绍:画发牌前牌的摆放 void CProgramView::CardReady() { }
//函数介绍:画出当前玩家手中的牌 void CProgramView::DrawMyCard() {
CDC *pdc=GetDC(); int {
if(manager.PlayCards[manager.PlayerAc][i].Num<14) {
if(manager.PlayCards[manager.PlayerAc][i].Click) i;
for(i=0;i<20&&manager.PlayCards[manager.PlayerAc][i].Num<=15;i++) CDC *pdc=GetDC(); for(int
i=0;i<54;i++)
pdc->BitBlt(300+i*2,220,72,97,&Mcard,142,384,SRCCOPY); ReleaseDC(pdc);
ReleaseDC(pdc);
if(!m_isReady)m_ok.Invalidate(); m_cancel.Invalidate(); m_sendcard.Invalidate(); m_pass.Invalidate(); PrintState();
if(isDrawed)DrawOtherCard();
pdc->BitBlt(100+i*15,480-40,71,96,&Mcard,(manager.PlayCards[manager.PlayerAc][i].Num-1)*71,manage
else
r.PlayCards[manager.PlayerAc][i].Type*96,SRCCOPY);
pdc->BitBlt(100+i*15,480,71,96,&Mcard,(manager.PlayCards[manager.PlayerAc][i].Num-1)*71,manager.Pl
}
else if(manager.PlayCards[manager.PlayerAc][i].Num<=15) {
if(manager.PlayCards[manager.PlayerAc][i].Click)
ayCards[manager.PlayerAc][i].Type*96,SRCCOPY);
pdc->BitBlt(100+i*15,480-40,71,96,&Mcard,(manager.PlayCards[manager.PlayerAc][i].Num-14)*71,384,S
else
RCCOPY);
- 12 -
TCP-IP协议与网络编程课程设计
}
void CProgramView::DrawOtherCard() { }
void CProgramView::OnLButtonDown(UINT nFlags, CPoint point) {
// TODO: Add your message handler code here and/or call default int int int
mx=point.x; my=point.y; i;
//点到中间若轮到主机发牌则发牌(暂无动画)
{ }
if(cardright)
for(i=0;i<20&&cardright[i].Num<=15;i++) { }
ReleaseDC(pdc);
pdc->BitBlt(630,55+i*10,97,75,&Mcard,214,408,SRCCOPY);
pdc->BitBlt(55,55+i*10,97,75,&Mcard,214,408,SRCCOPY);
{ }
if(cardleft)
for(i=0;i<20&&cardleft[i].Num<=15;i++)/
/Card *card 为传入的对方出的牌即OutCards
CardReady();
//原来这里是没有注释的
//画其他玩家剩下的牌/反面
if(manager.Game_State==-1) int
i; return;
if(manager.Game_State==-2)
CDC *pdc=GetDC();//画出其他玩家的牌(包括其还剩下多少张牌及当前出的牌)
pdc->BitBlt(100+i*15,480,71,96,&Mcard,(manager.PlayCards[manager.PlayerAc][i].Num-14)*71,384,SRC }
}
COPY);
ReleaseDC(pdc);
- 13 -
TCP-IP协议与网络编程课程设计
//将牌点起来
}
int CProgramView::SelectNum(int num,int { }
void CProgramView::OnSendCard()//int num,int {
if(isgoon && manager.DoMsg(15,4)) { }
int
k;
OutCards[1][k]=manager.OutCards[k];
for(k=0;k<20&&manager.OutCards[k].Num<=15;k++) if(k!=20)
OutCards[1][k].Num=16;//时钟停止计时
mx,int
my(当前玩家手中牌的数量
//光标横坐标,光标纵坐标)
if(mx>=100+(num-1)*15) else
return
(mx-100)/15;
return
num-1;
mx,int
my)
CView::OnLButtonDown(nFlags, point);//判断点中的是第几张牌 if(isgoon && mx>=100&&my>=440 && mx<=455&&my<=575) { }
CDC *pdc=GetDC();
for(i=0;manager.PlayCards[manager.PlayerAc][i].Num<=15;i++); if(mx<=100+(i-1)*15+71&&my<=576&&mx>=100&&my>=440) { }
ReleaseDC(pdc);
i=SelectNum(i,mx,my);//判断点中的是第几张牌 if(manager.DoMsg(i,1))
PrintAll();
if(isgo&&mx>=300&&my>=220&&mx<=476&&my<=312&&(pControl->m_Isserver)&&manager.Game_{ }
MessageBox(\主机发牌\pControl->StartCards();
State==-1)
- 14 -
TCP-IP协议与网络编程课程设计
}
void CProgramView::DrawPlayername() { {
} i=0;
&Background,x+(630-x)/10*(i-1),y+(55+timer*10-y)/10*(i-1),SRCCOPY);/重画
if(cardright[timer].Num<=15) {
pdc->BitBlt(x+(630-x)/10*(i-1),y+(55+timer*10-y)/10*(i-1),97,75,//重画被背景覆盖的牌
}
else if(manager.PlayCards[manager.PlayerAc][timer].Num<=15)//画大小鬼
pdc->BitBlt(x+(100+timer*15-x)/10*(i-1),y+(480-y)/10*(i-1),71,96,&Background,
x+(100+timer*15-x)/10*(i-1),y+(480-y)/10*(i-1),SRCCOPY);
//画当前显示的牌
{
if(i-1>0)
//擦除上次画的牌,用背景覆盖
if(manager.PlayCards[manager.PlayerAc][timer].Num<14)//发牌动画 CDC *pdc=GetDC();
pdc->SetBkMode(TRANSPARENT); //设置背景为透明 //pdc->SetTextColor(RGB(255,255,255));//设置字体颜色
void CProgramView::OnTimer(UINT nIDEvent)
pdc->BitBlt(x+(100+timer*15-x)/10*i,y+(480-y)/10*i,71,96,&Mcard,
(manager.PlayCards[manager.PlayerAc][timer].Num-1)*71, manager.PlayCards[manager.PlayerAc][timer].Type*96,SRCCOPY);
Card模块: class Card { public: };
Card(); virtual ~Card();
int Num;//牌面数目 2-10 J=11 Q=12 K=13 A=1 Jok(小)=14 Jok(大)=15 大与15表示此牌不存在 int Pow;//牌的实际大小,比如斗地主中2就比A大
//3-10 J Q K A 2 Jo小 Jo大 //1-8 9 10 11 12 13 14 15
int Type;//牌的类型 黑桃=0 红桃=1 梅花=2 方块=3 bool Click;//被玩家选种的牌将是true,没被选种是false
- 15 -
TCP-IP协议与网络编程课程设计
五、开发中遇到的问题
下面给出的是我开发中遇到关键技术问题以及解决方案:
问题一:双升游戏怎么样才能在不同状态下,收到客户端的错误消息不导致状态混乱? 解决方案:使用状态模式,不同的状态的逻辑处理不一样,要响应的消息也不一样。所以,每个状态机重载的时候要实现各自不同的消息处理函数。这样可以避免在不同状态下,收到客户端的错误消息(或者因为网络延时造成的超时消息)而导致的状态混乱。 问题二:怎样才能判断双升游戏中甩牌时判断是否能够甩?
解决方案:在第一手出牌时,还需要判断当前的牌是否能出的出去:甩牌时每一部分的牌都需要比别人手中同花色最大的牌还要大。虚函数getIllegalCards实现了这个功能。它能获取一堆牌中,比其他人手中的牌小的那部分牌。判断的逻辑主要用到了前面说到的strip操作。当甩牌后,会由CCardFactory创建一个CBlendCards对象,其中有若干个CSingleCard和CPairCards对象。此时,将其他玩家的手牌散列到哈希表中,然后依次调用CBlendCards中各个牌对象的stripCards方法,剥离出对应的牌对象。如果某一次剥离出的牌对象比当前CBlendCards中的对象大,说明甩牌失败,需要强制出小。 问题三:怎样才能实现双升发牌算法?
解决方案:当每个玩家都准备完毕后,那么第一步就是要发牌。需要做到一个完全随机的发牌,就要保证每张牌发到每个玩家手里的概率都是一样的,而且牌的顺序是等概率随机打乱的。程序中采用的是如下的发牌算法,假如有两幅牌,编号从1到108,首先随机选出一个,并且将牌发给玩家,然后将这个编号的牌与108号牌交换编号,那么剩下的牌就是从1到107号。于是再从中选出一个,重复以上的过程。
六、心得体会
通过这次课程设计,我收获了很多。首先把所学知识加以利用和巩固,其次在实践中遇到问题去探索和学习,更增加了新知识。在程序设计编写过程中两个类的数据交换是个比较麻烦的过程,这个类的定义过程中要用到另一个类做参数类型,而在后一个类中亦需要第一个类做参数类型,出现了互相调用的情况。编译提示未定义,只好在两个类外定义函数负责两个类函数的数据交换。实践证明达到了预期的目的,积累了经验。由于程序是用文本窗口模拟的图形,界面比较简陋,那么界面将会非常好,只是由于所学知识有限,只有下一步去探索了。
- 16 -
TCP-IP协议与网络编程课程设计
通过这次的学习设计,我发现我还有许许多多的不足的地方,源代码的书写等等,刚开始我发现我的问题后,十分紧张,自己动手设计曾经自己想都没想过的东西,虽然很兴奋,但想想自己无从下手,原来的兴奋劲一下子都没了,很忙然,于是我通过上网查找资料,进图书馆查找书籍等,终于知道了双升游戏的设计概念,终于知道了设计的方法,于是,渐渐地我的游戏设计理念诞生了。
- 17 -
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库河北联合大学信息学院联网游戏双升课设在线全文阅读。
相关推荐: