实现效果
具体实现
牌分为三个部分,鼠标可以拿起若干牌,可以拖动,按照一定规则放置到其他位置,当所有的牌都放在上方时游戏就赢了。
牌的随机排列
使用random_shuffle
乱序之后,把m_vtr
当做索引就行了。
CCardCtrl::CCardCtrl(): m_vtr(52)
{
。。。
for (int i = 0; i < 52; i++)
{
m_vtr[i] = i;
}
srand((unsigned int)time(NULL));
random_shuffle(m_vtr.begin(), m_vtr.end()); // 向量随机排列
。。。
}
鼠标拿牌
鼠标左键按下,判断鼠标的位置,确定是拿哪边的牌
void CCardCtrl::OnLButtonDown(POINT pt)
{
// 记录鼠标按下的点
m_LeftMouseDownPos = pt;
// 下方的牌
if (pt.y >= 156)
{
if (m_oDownCards.CanMouseGetCards(pt))
{
// 拿牌
m_oDownCards.MouseGetCards(m_pMouseLinkHead, m_pMouseLinkEnd);
this->OnPaintWnd();
return;
}
}
// 上方的牌
if (pt.y <= 126 && pt.x >= 330)
{
if (m_oUpCards.CanMouseGetUpCards(pt))
{
m_oUpCards.MouseGetUpCards(m_pMouseLinkHead, m_pMouseLinkEnd);
this->OnPaintWnd();
return;
}
}
// 左边的牌
if (m_oLeftCards.CanMouseGetLeftCards(pt))
{
m_oLeftCards.MouseGetLeftCards(m_pMouseLinkHead, m_pMouseLinkEnd);
this->OnPaintWnd();
return;
}
// 能不能开牌
if (m_oLeftCards.CanOpenCards(pt))
{
m_oLeftCards.OpenCards();
}
else
{
if (m_oLeftCards.m_bFalg == true)
{
m_oLeftCards.m_bFalg = false;
m_oLeftCards.CloseCards();
}
}
this->OnPaintWnd();
return;
}
比如想拿上面的牌,鼠标位置正确,并且有牌,就能拿起一张牌记录到鼠标链表中
bool CUpCards::CanMouseGetUpCards(POINT pt)
{
// 大概确ID
int nLinkID = (pt.x - 330)/100;
if ((pt.x >= (330 + nLinkID*100) && pt.x <= (330 + nLinkID*100 + 71)) && (pt.y >= 30 && pt.y <= 30 + 96))
{
if (m_pUpHead[nLinkID] != NULL)
{
m_nGetCardsID = nLinkID;
return true;
}
return false;
}
return false;
}
void CUpCards::MouseGetUpCards(List* &pMouseLinkHead, List* &pMouseLinkEnd)
{
if (m_pUpHead[m_nGetCardsID] == m_pUpEnd[m_nGetCardsID])
{
pMouseLinkHead = m_pUpHead[m_nGetCardsID];
pMouseLinkEnd = m_pUpEnd[m_nGetCardsID];
m_pUpHead[m_nGetCardsID] = NULL;
m_pUpEnd[m_nGetCardsID] = NULL;
}
else
{
// 先连
pMouseLinkHead = m_pUpEnd[m_nGetCardsID];
pMouseLinkEnd = m_pUpEnd[m_nGetCardsID];
// 后断
m_pUpEnd[m_nGetCardsID] = m_pUpEnd[m_nGetCardsID]->m_pPre;
m_pUpEnd[m_nGetCardsID]->m_pNext = NULL;
pMouseLinkHead->m_pPre = NULL;
}
}
接受牌
条件都正确的情况下,把鼠标链表上的牌链接到上方牌链表中
bool CUpCards::CanUpRecieveCards(POINT pt, List* pMouseLinkHead)
{
// 是不是一张牌
if (pMouseLinkHead->m_pNext != NULL)
{
return false;
}
// 大致定位链表ID
int nLinkID = (pt.x - 330)/100;
if ((pt.x >= (330 + nLinkID*100) && pt.x <= (330 + nLinkID*100 + 71)) && (pt.y >= 30 && pt.y <= 30 + 96))
{
if (m_pUpHead[nLinkID] == NULL)
{
if (pMouseLinkHead->m_Cards.m_nCardsNum == 1)
{
m_nLinkID = nLinkID;
return true;
}
return false;
}
else
{
if ((m_pUpEnd[nLinkID]->m_Cards.m_nCardsNum + 1 == pMouseLinkHead->m_Cards.m_nCardsNum)
&& (m_pUpEnd[nLinkID]->m_Cards.m_nCardsColor == pMouseLinkHead->m_Cards.m_nCardsColor))
{
m_nLinkID = nLinkID;
return true;
}
return false;
}
}
return false;
}
void CUpCards::UpRecieveCards(List* &pMouseLinkHead, List* &pMouseLinkEnd)
{
if (m_pUpHead[m_nLinkID] == NULL)
{
m_pUpHead[m_nLinkID] = pMouseLinkHead;
m_pUpEnd[m_nLinkID] = pMouseLinkEnd;
}
else
{
m_pUpEnd[m_nLinkID]->m_pNext = pMouseLinkHead;
pMouseLinkHead->m_pPre = m_pUpEnd[m_nLinkID];
m_pUpEnd[m_nLinkID] = pMouseLinkEnd;
}
pMouseLinkHead = NULL;
pMouseLinkEnd = NULL;
// 修改坐标
m_pUpEnd[m_nLinkID]->m_x = 330 + 100*m_nLinkID;
m_pUpEnd[m_nLinkID]->m_y = 30;
}
恢复牌
如果没有放置到其他地方,牌就应该回到原来的地方
void CCardCtrl::OnLButtonUP(POINT pt)
{
if (m_pMouseLinkHead != NULL)
{
// 下方牌接收
if (m_oDownCards.CanDownRecieveCards(pt, m_pMouseLinkHead))
{
m_oDownCards.DownRecieveCards(m_pMouseLinkHead, m_pMouseLinkEnd);
ClearValue();
this->OnPaintWnd();
return;
}
// 上方牌接收
if (m_oUpCards.CanUpRecieveCards(pt, m_pMouseLinkHead))
{
m_oUpCards.UpRecieveCards(m_pMouseLinkHead, m_pMouseLinkEnd);
// 翻牌
m_oDownCards.FlipCard();
// 是否赢了
if (m_oUpCards.CanWin())
{
MessageBox(m_hWnd, TEXT("恭喜!"), TEXT("提示"), MB_OK);
}
ClearValue();
this->OnPaintWnd();
return;
}
// 鼠标的牌恢复
if (m_oUpCards.CanRevertCards())
{
m_oUpCards.RevertCards(m_pMouseLinkHead, m_pMouseLinkEnd);
ClearValue();
this->OnPaintWnd();
return;
}
if (m_oDownCards.CanRevertCards())
{
m_oDownCards.RevertCards(m_pMouseLinkHead, m_pMouseLinkEnd);
ClearValue();
this->OnPaintWnd();
return;
}
m_oLeftCards.ResertLeft(m_pMouseLinkHead, m_pMouseLinkEnd);
ClearValue();
this->OnPaintWnd();
return;
}
}
bool CUpCards::CanRevertCards()
{
return m_nGetCardsID != -1;
}
void CUpCards::RevertCards(List* &pMouseLinkHead, List* &pMouseLinkEnd)
{
if (m_pUpHead[m_nGetCardsID] == NULL)
{
m_pUpHead[m_nGetCardsID] = pMouseLinkHead;
m_pUpEnd[m_nGetCardsID] = pMouseLinkEnd;
}
else
{
m_pUpEnd[m_nGetCardsID]->m_pNext = pMouseLinkHead;
pMouseLinkHead->m_pPre = m_pUpEnd[m_nGetCardsID];
m_pUpEnd[m_nGetCardsID] = pMouseLinkEnd;
}
pMouseLinkHead = NULL;
pMouseLinkEnd = NULL;
}
链接
百度云链接:https://pan.baidu.com/s/11vHei4AqDw7ZohUuvmTfdw
提取码:pb62