如何将其他类的方法整合到Blackjack游戏的Windows Forms P1类中?
Blackjack游戏Windows Forms整合实现方案
首先先修正基础类里的几个关键bug,否则后续整合会出问题:
基础类bug修正
1. Card类Image属性递归调用问题
原代码中Image属性的getter会无限递归,修改为:
public Image Image { get { return image; // 原代码是return this.Image,会触发无限递归 } }
2. Deck类ShuffleNewDeck方法漏加卡片
创建卡片后未加入牌组列表,修改为:
public void ShuffleNewDeck() { cards.Clear(); for (int i = 1; i < 5; i++) { for (int f = 1; f < 14; f++) { Card card = new Card(); card.Value = (Card.CardValue)f; card.Suit = (Card.CardSuit)i; cards.Add(card); // 新增此行,将创建的卡片加入牌组 } } Random r = new Random(); cards = cards.OrderBy(x => r.Next()).ToList(); }
3. Hand类AddValue枚举引用问题
嵌套枚举需指定所属类,修改为:
public void AddValue(Card drw, ref int curScore) { if (drw.Value == Card.CardValue.Ace) // 原代码直接写CardValue,需指定Card类 { if (curScore <= 10) { curScore += 11; } else { curScore += 1; } } else if (drw.Value == Card.CardValue.Jack || drw.Value == Card.CardValue.Queen || drw.Value == Card.CardValue.King) { curScore += 10; } else { curScore += (int)drw.Value; } }
Windows Forms P1类整合实现
假设你已在窗体上添加以下控件:
panelPlayer:显示玩家手牌panelComputer:显示电脑手牌lblStatus:显示游戏状态信息card_back:资源文件中的卡片背面图片
1. 游戏初始化逻辑
private void P1_Load(object sender, EventArgs e) { StartNewGame(); } // 抽取初始化逻辑为独立方法,方便复用 private void StartNewGame() { // 清空面板与状态 panelPlayer.Controls.Clear(); panelComputer.Controls.Clear(); lblStatus.Text = ""; // 初始化牌组、玩家与电脑手牌 deck = new deck(); player = new Hand(StartingHand, deck); computer = new Hand(StartingHand, deck); // 计算初始分数 playerSum = 0; foreach (var card in player.Cards) { player.AddValue(card, ref playerSum); } computerSum = 0; foreach (var card in computer.Cards) { computer.AddValue(card, ref computerSum); } // 绘制手牌(电脑默认隐藏第二张) DrawHandToPanel(player, panelPlayer, true); DrawHandToPanel(computer, panelComputer, false); // 启用操作按钮 BtnTwist.Enabled = true; BtnStick.Enabled = true; }
2. 手牌绘制辅助方法
通用方法将手牌绘制到指定面板:
private void DrawHandToPanel(Hand hand, Panel panel, bool showAllCards) { panel.Controls.Clear(); int cardSpacing = 10; // 卡片间距 int xPos = cardSpacing; for (int i = 0; i < hand.Cards.Count; i++) { Card card = hand.Cards[i]; PictureBox pb = new PictureBox(); pb.Size = new Size(73, 97); pb.Location = new Point(xPos, cardSpacing); // 电脑手牌默认隐藏第二张 if (!showAllCards && i == 1) { pb.Image = Resources.card_back; } else { pb.Image = card.Image; } panel.Controls.Add(pb); xPos += pb.Width + cardSpacing; } }
3. Twist(Hit)按钮逻辑
玩家请求抽牌:
private void BtnTwist_Click(object sender, EventArgs e) { if (player.Cards.Count >= MaxCards) { lblStatus.Text = "手牌已满,无法继续抽牌!"; return; } // 抽卡并更新玩家手牌与分数 Card drawnCard = deck.DrawCard(player); player.AddValue(drawnCard, ref playerSum); DrawHandToPanel(player, panelPlayer, true); // 检查是否爆牌 if (playerSum > 21) { lblStatus.Text = "你爆牌了!电脑获胜!"; DrawHandToPanel(computer, panelComputer, true); BtnTwist.Enabled = false; BtnStick.Enabled = false; } }
4. Stick(Stand)按钮逻辑
玩家停止抽牌,电脑执行逻辑:
private void BtnStick_Click(object sender, EventArgs e) { // 禁用玩家操作按钮 BtnTwist.Enabled = false; BtnStick.Enabled = false; // 电脑抽牌直到分数≥17或手牌满 while (computerSum < 17 && computer.Cards.Count < MaxCards) { Card drawnCard = deck.DrawCard(computer); computer.AddValue(drawnCard, ref computerSum); } // 显示电脑所有手牌并判断胜负 DrawHandToPanel(computer, panelComputer, true); string result = ""; if (computerSum > 21) { result = "电脑爆牌!你获胜!"; } else if (playerSum > computerSum) { result = "你获胜!"; } else if (playerSum < computerSum) { result = "电脑获胜!"; } else { result = "平局!"; } lblStatus.Text = result; }
5. 菜单按钮实现
重置游戏
private void resetGameToolStripMenuItem_Click(object sender, EventArgs e) { StartNewGame(); }
清空桌面
private void clearTableToolStripMenuItem_Click(object sender, EventArgs e) { panelPlayer.Controls.Clear(); panelComputer.Controls.Clear(); lblStatus.Text = ""; playerSum = 0; computerSum = 0; BtnTwist.Enabled = false; BtnStick.Enabled = false; }
查看当前分数
private void requestScoreToolStripMenuItem_Click(object sender, EventArgs e) { MessageBox.Show($"你的分数:{playerSum}\n电脑分数:{computerSum}", "当前分数"); }
内容的提问来源于stack exchange,提问作者danrutley
相关产品推荐
相关产品推荐

