www.pudn.com > Five_QT_by_CT.rar > Main.cpp


#include "Main.h"


ChessBoard::ChessBoard(QWidget *parent,char *name)
        :QWidget(parent,name)
{  

     	mChessboardPixmap=new QPixmap("chessboard_xmp");
     	mWhiteChessPixmap= new QPixmap("white_xmp");
	mBlackChessPixmap= new QPixmap("black_xmp");
	
    	mChessSize=QSize((mSize.width()-mLeftMargin-mRightMargin)/15,(mSize.height()-mLeftMargin-mRightMargin)/15);
     	setBackgroundPixmap(*mChessboardPixmap);
 
     
	mStartButton=new QPushButton(this, 0);
	mStartButton->setText("Start");
	mStartButton->setGeometry(252, 579, 120, 50);


	mGameInfoLabel=new QLabel ( this,  0,  0 ); 
	mGameStatusLabel=new QLabel ( this,  0,  0 ); 
	mWhiteLabel=new QLabel ( this,  0,  0 ); 
	mBlackLabel=new QLabel ( this,  0,  0 ); 
	mMySideLabel=new QLabel( this, 0, 0);

	mGameStatusLabel->setGeometry(17,9,192,60);
	mGameStatusLabel->setText(QString("Idle"));
	mGameStatusLabel->setFont( QFont( "Helvetica", 16 ) );
	
	mMySideLabel->setGeometry(17,70,192,47);
	mMySideLabel->setText(QString("Your side:"));
	mMySideLabel->setFont( QFont( "Helvetica", 12 ) );
	
	
	mWhiteLabel->setGeometry(17,118,192,47);
	mWhiteLabel->setText(QString("White :"));
	mWhiteLabel->setFont( QFont( "Helvetica", 12 ) );

	mBlackLabel->setGeometry(17,166,192,46);
	mBlackLabel->setText(QString("Black :"));
	mBlackLabel->setFont( QFont( "Helvetica", 12 ) );

	
	mGameInfoLabel->setGeometry(17,213,192,45);
	mGameInfoLabel->setText(QString("Game info:"));
	mGameInfoLabel->setFont( QFont( "Helvetica", 12 ) );
	
	mLeftMargin=268;
	mRightMargin=17;
	mTopMargin=22;
	mBottomMargin=100;
	
	connect( mStartButton, SIGNAL(clicked ()), this, SLOT(sstartclicked()) );
	
}


void ChessBoard::init()
{
  	 setGeometry(mPosition.x(), mPosition.y(), mSize.width(), mSize.height());
     
}



void ChessBoard::paintEvent(QPaintEvent* )
{
	mGameInfoLabel->setText(QString("Now turn:")+mGameLogic.mCurrentTurn);
	
     QPainter paint( this );
     QRect temptRect;
	 mChessSize=QSize(34,34);
     temptRect=QRect(mPosition.x(),
                   mPosition.y(),
                   mSize.width(),
                   mSize.width());
	
	
	int i;
	//逐个画棋子	
	for( i=0; i<225; i++)
	{
		if(mGameLogic.mChessRecord.mRecord[i].mPoint.x()<0)
			break;

		temptRect=QRect(convertGridToMouse(mGameLogic.mChessRecord.mRecord[i].mPoint)
				,mChessSize);

		if(mGameLogic.mChessRecord.mRecord[i].mTurn==0)
		{
     			paint.drawPixmap(temptRect,*mWhiteChessPixmap);
		}
		else
		{
			paint.drawPixmap(temptRect,*mBlackChessPixmap);
		}
	
	}

	
}


void ChessBoard::mousePressEvent(QMouseEvent *e)
{
	//鼠标点下后表示落子
	//调用游戏逻辑判断合法性,舒赢等
	if(mGameLogic.mGameState!='p')//'p'-playing表示正在下棋
		return;
 	QPoint p=convertMouseToGrid(e->pos());
	if(p.x()<=0||p.y()<=0)
		return;
	
	if(!mGameLogic.PutNewChess( p.x(), p.y() , 1)  )//1表示是自己下的, 0表示是对方下的
	{
		printf("in mouse press Event cannot put chess\n");
		return;

	}
	//本地显示棋子,	
	PutChessToFace(p);
	
	
	//将坐标发送给对方,递交给HallMaster来完成发送
	char tempt[3];
	Message msg;
	msg.mRequest=QString("bchessput");

	snprintf(tempt,3,"%d", p.x());
	msg.mContent=QString(tempt);

	snprintf(tempt,3,"%d", p.y());
	msg.mContent2=QString(tempt);
	
	emit sendmsgtomain(msg);

	
	
	//
}



//根据棋盘大小,将p点坐标转换为15*15棋盘的坐标
QPoint ChessBoard::convertMouseToGrid(const QPoint p)
{
	int x=p.x()-mLeftMargin;
	int y=p.y()-mTopMargin;
	if( (x<=0)
		||(y<=0)
		||(x>=(mSize.width()-mLeftMargin-mRightMargin))
		||(y>=(mSize.height()-mTopMargin-mBottomMargin)))
		return(QPoint(-1,-1));
	QPoint g;    
        int sizex=mChessSize.width();
	int sizey=mChessSize.height();
        g.setX(x/sizex+1); 
        g.setY(y/sizey+1);
       	//if(g.x()<=0||g.y()<=0)
	//	printf( "int convertMouseToGrid size:(%d, %d) mouse x, y: (%d, %d) grid x,y: (%d , %d)\n ",sizex, sizey, p.x(), p.y(), g.x(), g.y());
        return g;  
}



QPoint ChessBoard::convertGridToMouse(const QPoint g)
{
	QPoint p;
	if(g.x()<=0||g.y()<=0)
		return QPoint(-1,-1);
	 int sizex=mChessSize.width();
	int sizey=mChessSize.height();
      	int x=g.x()*sizex-sizex;
	int y=g.y()*sizey-sizey;
	x+=mLeftMargin;
	y+=mTopMargin;
        p.setX(x); //转换后减一个偏移把棋子中心处鼠标坐标转换为矩形左上角坐标
        p.setY(y);
	
	if(g.x()<=0||g.y()<=0)
	printf("int convertGridToMouse size:(%d ,%d) grid x,y : %d,%d mouse x, y:%d,%d \n",sizex, sizey, g.x(), g.y(), p.x(), p.y());
        
        return p;	
}



void ChessBoard::sstartclicked()
{
	

	//游戏界面Start按钮被按下,更新label
	if(mGameLogic.mGameState!='f')
		return;
	mGameStatusLabel->setText("Waiting");
	mGameLogic.mGameState='w';    //w表示等待
	clearBoard();
	//send invitation to the other side;
	if(mMyDesk.mWhiteID.compare("-1")==0||mMyDesk.mBlackID.compare("-1")==0)
		return;
	Message msg;
	msg.mRequest=QString("bsendinvite");
	emit sendmsgtomain( msg );
	
	
}

void ChessBoard:: clearBoard()
{
	mGameLogic.clearChessInfo();	
}
 void ChessBoard:: setPos(QPoint p)
{
             mPosition=p;
}
void ChessBoard:: setSize(QSize s)
{
             mSize=s;
}
void ChessBoard::setMyside(QString side)
{
	mMyside=side;
}


void ChessBoard::PutChessToFace(QPoint p)
{
	QPoint chessp=convertGridToMouse(p);
	if(chessp.x()=8)
	{
		int x=mGameLogic.mChessRecord.mRecord[i-2].mPoint.x();
		int y=mGameLogic.mChessRecord.mRecord[i-2].mPoint.y();
		int turn=mGameLogic.mChessRecord.mRecord[i-2].mTurn;
		if(mGameLogic.JudgeWin(x, y, turn))
		{
			printf("win! side %d\n",turn);
			//更新label
			if(turn==1&&mGameLogic.mMyside.compare("black")==0)
				mGameStatusLabel->setText("You Win!");
			else if(turn==0&&mGameLogic.mMyside.compare("white")==0)
				mGameStatusLabel->setText("You Win!");
			else 
				mGameStatusLabel->setText("You Lose!");
			mGameLogic.mGameState='f';
		}
		
	
		
	}
	mGameInfoLabel->setText(QString("Now turn:")+mGameLogic.mCurrentTurn);
	
}



void ChessBoard:: sdisposemsg(Message msg)
{
	QString req=msg.mRequest;
	
	if(!req.compare("hagreeinvite"))
	{
		//收到对方同意下棋的回复
		HandleAgree();
	}
	else if(!req.compare("hputchess"))
	{
		//收到对方落子坐标
		HandlePutchess(msg);
	}
	else if(!req.compare("hchangeseat"))
	{
		//座位更换
		
		HandleChangeseat(msg);
	}
	else if(!req.compare("hupdatedesk"))
	{
		//座位更换
		HandleUpdatedesk(msg);
	}
	else if(!req.compare("hreplyinvite"))
	{
		//
		HandleInvite();
	}
	else if(!req.compare("hmyid"))
	{
		mMyID=msg.mContent;
	}
	else 
		printf("in chessboard::sdisposemsg, unknown request!\n");
	
	
	
		
}

//收到对方同意下棋的回复
void ChessBoard::HandleAgree()
{
	
	//设置mGameLogic 的参数
	mGameLogic.mGameState='p';
	
	//修改游戏状态label
	mGameStatusLabel->setText(QString("Playing"));	
	
	repaint();
}


//处理本方落子消息
void ChessBoard::HandlePutchess( Message msg)
{
	//将msg.mContent转换为棋盘坐标
	QString qstr;
	QPoint point;
	int n=0;
	char tempt[100];
	snprintf(tempt, msg.mContent.length()+1, "%s", msg.mContent.ascii());//snprintf 第二个表示长度的参数,似乎包含了字符串结束字符'\0'
	char *ptr;

	ptr=strstr(&tempt[0], "#");
	if(ptr==NULL)
	{
		printf("getting x chess grid error!\n");
		return;
	}
	*ptr='\0';
	qstr=QString(&tempt[n]);
	n+=ptr-&tempt[n]+1;
	point.setX(qstr.toInt());
	


	ptr=strstr(&tempt[n], "#");
	if(ptr==NULL)
	{
		printf("getting y chess grid error!\n");
		return;
	}
	*ptr='\0';
	qstr=QString(&tempt[n]);
	n+=ptr-&tempt[n]+1;
	point.setY(qstr.toInt());


	//重绘,并添加新棋子,游戏逻辑,比如轮到谁等在putnewchess里修改
	mGameLogic.PutNewChess(point.x(), point.y(), 0);
	PutChessToFace(point);
}  



//处理换座(坐下)成功消息
void ChessBoard::HandleChangeseat(Message msg)
{
	mGameLogic.mMyside=msg.mContent;
	mGameLogic.mCurrentTurn=QString("black");
	mGameLogic.mGameState='f';
	mMySideLabel->setText(QString("Your side:") + msg.mContent);
	
}


//更新本桌信息
void ChessBoard::HandleUpdatedesk(Message msg)
{
	//找到左右两边ID
	QString whiteid=msg.mContent;
	QString blackid=msg.mContent2;

	//设置Label属性及mydesk
	mMyDesk.mWhiteID=whiteid;
	mMyDesk.mBlackID=blackid;
	mWhiteLabel->setText(QString("White:")+whiteid);
	mBlackLabel->setText(QString("Black:")+blackid);	
}



void ChessBoard :: HandleInvite()
{
	Message msg;

	//reply by judging from current game state;
	//the logic is: only when the current state is waiting can the chessboard send agree feedback 
	//under other circumstances, no reply would be sended (reply only if agree, agree only if i'm waiting)
	
	if(mGameLogic.mGameState=='w')
	{
		msg.mRequest=QString("bagreeinvite");
		mGameLogic.mGameState='p';
		mGameStatusLabel->setText("Playing");
		emit sendmsgtomain(msg);
	}
}



ChatBox::ChatBox(QWidget *parent,char *name)
      :QWidget(parent,name)
{  
}

void ChatBox::init()
{
  
  
  
  	mChatLineEdit=new QLineEdit(this,0);
  	mChatListBox=new QListBox(this,0,0);
  	mChatListBox->setGeometry(0,0,mSize.width(),mSize.height()-40);
  	mChatLineEdit->setGeometry(0,mSize.height()-30,mSize.width(),30);
  
 	 setGeometry(mPosition.x(),mPosition.y(),mSize.width(),mSize.height()); 

  	connect( mChatLineEdit, SIGNAL(returnPressed ()),this, SLOT(schatlinereturned()) );
  	
	
	 

}

void ChatBox::ShowMessage(QString str)
{
  	mChatListBox->insertItem(str,-1);
}  



void ChatBox::schatlinereturned()
{
	QString str=mChatLineEdit->text();
	ShowMessage(str);

	mChatLineEdit->clear();

	Message msg;
	msg.mRequest=QString("cchat");
	msg.mContent=str;
	emit sendmsgtomain(msg);
}


void ChatBox:: sshowchat(Message msg)
{
	 ShowMessage(msg.mContent);
}





Main::Main(QWidget *parent,char *name)
       :QWidget(parent,name)       
{
	//设置个部件位置,大小
 	 mSize=QSize(800,641);
 	 mChessBoardPos=QPoint(0,0);
 	 mChessBoardSize=QSize(800,641);
 	 mChatBoxPos=QPoint(13,292);
 	 mChatBoxSize=QSize(195,333);

 	
  	 mChessBoard=new ChessBoard(this,0);
	 mChatBox=new ChatBox(this,0);

	//将位置,大小传递给部件    
  	mChatBox->setPos(mChatBoxPos);
  	mChatBox->setSize(mChatBoxSize);
  	mChessBoard->setPos(mChessBoardPos);
  	mChessBoard->setSize(mChessBoardSize);

	//调用各个部件的init()以完成部件的位置等设置	
	
  	mChessBoard->init();
	mChatBox->init();

  	QWidget::setMaximumSize(mSize);
  	QWidget::setMinimumSize(mSize);

  	

	

//以下设置个label的属性
	

	connect( this, SIGNAL(sendmsgtoboard( Message ) ), mChessBoard, SLOT( sdisposemsg( Message ) ) );
	connect( this, SIGNAL(sendmsgtochat( Message ) ), mChatBox, SLOT( sshowchat( Message ) ) );
	connect( mChessBoard ,SIGNAL(sendmsgtomain (Message )), this, SLOT(sdisposemsg( Message )) );
	connect( mChatBox, SIGNAL(sendmsgtomain( Message ) ), this, SLOT( sdisposemsg( Message ) ) );
	
	
 
}


void Main :: sdisposemsg(Message msg)
{
	QString req=msg.mRequest;
	Message mymsg;
	if(!req.compare("hagreeinvite"))
	{
		//收到对方同意下棋的回复或者有人邀请等待中的自己叫给ChessBoard处理
		sendmsgtoboard(msg);
	}
	else if(!req.compare("hputchess"))
	{
		//收到对方落子坐标叫给ChessBoard处理
		sendmsgtoboard(msg);
	}
	else if(!req.compare("hchangeseat"))
	{
		//换座成功,统一重新显示棋盘画面
		
		sendmsgtoboard(msg);
	}
	else if(!req.compare("hupdatedesk"))
	{
		//座位信息更新,叫给Chessboard
		sendmsgtoboard(msg);
	}
	else if(!req.compare("hreplyinvite"))
	{
		//hall master inquiries if main agrees to play, game relevant, pass it to chessboard
		sendmsgtoboard(msg);
	}
	else if(!req.compare("bagreeinvite"))
	{
		//chessboard agrees the invitation, send it to the inviter;
		emit sendmsgtohall(msg);
	}
	else if(!req.compare("bsendinvite"))
	{
		//send invite to the other side;

		emit sendmsgtohall(msg);
	}
	else if(!req.compare("bchessput"))
	{
		emit sendmsgtohall(msg);
	}
	else if(!req.compare("hmyid"))
	{
		emit sendmsgtoboard(msg);
	}
	else if(!req.compare("cchat"))
	{
		emit sendmsgtohall(msg);
	}
	else if(!req.compare("recvchat"))
	{
		emit sendmsgtochat(msg);
	}
	else 
		printf("main::sdisposemsg, unknown request!\n");
	
	
}