win32 纸牌

本文介绍了一个桌面纸牌游戏的实现,包括牌的随机排列、鼠标操作(拿起、拖动和放置)以及游戏逻辑。玩家可以拿起并拖动牌到不同区域,遵循特定规则。当所有牌被正确放置到上方时,游戏获胜。文章详细展示了代码实现,涉及鼠标事件处理和牌的链表管理。
摘要由CSDN通过智能技术生成

实现效果

在这里插入图片描述

具体实现

牌分为三个部分,鼠标可以拿起若干牌,可以拖动,按照一定规则放置到其他位置,当所有的牌都放在上方时游戏就赢了。

牌的随机排列

使用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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 相关的纸牌游戏项目可以是一个基于命令行界面或图形用户界面的扑克牌游戏,比如常见的斗地主、21点、德州扑克等。以下是一个简单的纸牌游戏项目的代码示例,供您参考: ```java import java.util.ArrayList; import java.util.Collections; import java.util.Scanner; public class PokerGame { private ArrayList<Card> deck; private ArrayList<Card> playerHand; private ArrayList<Card> dealerHand; private int playerTotal; private int dealerTotal; private Scanner scanner; public PokerGame() { deck = new ArrayList<>(); playerHand = new ArrayList<>(); dealerHand = new ArrayList<>(); scanner = new Scanner(System.in); createDeck(); } private void createDeck() { String[] suits = {"Clubs", "Diamonds", "Hearts", "Spades"}; String[] ranks = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"}; for (String suit : suits) { for (String rank : ranks) { Card card = new Card(suit, rank); deck.add(card); } } } private void shuffleDeck() { Collections.shuffle(deck); } private void dealCards() { for (int i = 0; i < 2; i++) { playerHand.add(deck.get(0)); deck.remove(0); dealerHand.add(deck.get(0)); deck.remove(0); } } private void printCards() { System.out.println("Your hand: "); for (Card card : playerHand) { System.out.println(card.getSuit() + " " + card.getRank()); } System.out.println("Dealer's hand: "); System.out.println(dealerHand.get(0).getSuit() + " " + dealerHand.get(0).getRank()); } private void calculateTotal() { playerTotal = 0; dealerTotal = 0; for (Card card : playerHand) { playerTotal += card.getValue(); } for (Card card : dealerHand) { dealerTotal += card.getValue(); } } private void playerTurn() { while (playerTotal < 21) { System.out.println("Do you want to hit or stand? (h/s)"); String choice = scanner.nextLine(); if (choice.equalsIgnoreCase("h")) { playerHand.add(deck.get(0)); deck.remove(0); calculateTotal(); printCards(); } else { break; } } } private void dealerTurn() { while (dealerTotal < 17) { dealerHand.add(deck.get(0)); deck.remove(0); calculateTotal(); printCards(); } } private void checkWinner() { if (playerTotal > 21) { System.out.println("You busted! Dealer wins."); } else if (dealerTotal > 21) { System.out.println("Dealer busted! You win."); } else if (playerTotal > dealerTotal) { System.out.println("You win!"); } else if (dealerTotal > playerTotal) { System.out.println("Dealer wins."); } else { System.out.println("It's a tie!"); } } public void playGame() { shuffleDeck(); dealCards(); calculateTotal(); printCards(); playerTurn(); dealerTurn(); checkWinner(); } public static void main(String[] args) { PokerGame game = new PokerGame(); game.playGame(); } } class Card { private String suit; private String rank; public Card(String suit, String rank) { this.suit = suit; this.rank = rank; } public String getSuit() { return suit; } public String getRank() { return rank; } public int getValue() { if (rank.equals("Ace")) { return 11; } else if (rank.equals("King") || rank.equals("Queen") || rank.equals("Jack") || rank.equals("10")) { return 10; } else { return Integer.parseInt(rank); } } } ``` 此代码演示了一个基于命令行界面的21点游戏。您可以按照自己的需求修改代码以创建您自己的纸牌游戏。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值