基于C#的斗地主实现方案

一、基础数据结构设计

1. 扑克牌类定义

public enum Suit
{
    Spades,    // 黑桃
    Hearts,    // 红桃
    Diamonds,  // 方块
    Clubs,     // 梅花,
    Joker      // 大小王
}

public class Card : IComparable<Card>
{
    public Suit Suit { get; }
    public int Rank { get; }  // 2=15, A=14, 小王=18, 大王=17

    public Card(Suit suit, int rank)
    {
        Suit = suit;
        Rank = rank;
    }

    public int CompareTo(Card other)
    {
        if (Rank != other.Rank) return Rank.CompareTo(other.Rank);
        return Suit.CompareTo(other.Suit);
    }

    public override string ToString() => $"{Rank} of {Suit}";
}

2. 牌堆管理类

public class Deck
{
    private List<Card> _cards = new();
    
    public void Initialize()
    {
        foreach (Suit suit in Enum.GetValues(typeof(Suit)))
        {
            for (int rank = 2; rank <= 14; rank++) // 2-14(A)
            {
                _cards.Add(new Card(suit, rank));
            }
        }
        _cards.Add(new Card(Suit.Joker, 17)); // 小王
        _cards.Add(new Card(Suit.Joker, 18)); // 大王
    }

    public void Shuffle() => _cards = _cards.OrderBy(c => Guid.NewGuid()).ToList();
    
    public List<Card> Deal(int count) => _cards.Take(count).ToList();
}

二、核心游戏逻辑实现

1. 游戏阶段管理

public enum GamePhase
{
    Dealing,    // 发牌阶段
    Bidding,    // 抢地主阶段
    Playing,    // 出牌阶段
    Ended       // 游戏结束
}

public class GameController
{
    private GamePhase _currentPhase;
    private List<Player> _players = new();
    private Deck _deck = new();
    private List<Card> _landlordCards = new();
    
    public GameController()
    {
        _players.Add(new Player("Player1"));
        _players.Add(new Player("Player2"));
        _players.Add(new Player("Player3"));
    }
}

2. 发牌逻辑实现

public void DealCards()
{
    _deck.Initialize();
    _deck.Shuffle();
    
    for (int i = 0; i < 17; i++)
    {
        foreach (var player in _players)
        {
            player.ReceiveCard(_deck.Deal(1));
        }
    }
    _landlordCards = _deck.Deal(3);
}

三、抢地主阶段实现

1. 玩家状态管理

public class Player
{
    public string Name { get; }
    public List<Card> Hand { get; } = new();
    public bool IsLandlord { get; private set; }
    public int BidScore { get; private set; }

    public Player(string name) => Name = name;

    public void ReceiveCard(Card card) => Hand.Add(card);
    
    public void Bid(int score)
    {
        BidScore = score;
        IsLandlord = true;
    }
}

2. 抢地主流程

public void StartBidding()
{
    int currentPlayer = 0;
    while (true)
    {
        var player = _players[currentPlayer];
        Console.WriteLine($"{player.Name}, 选择叫分 (0-3): ");
        int bid = int.Parse(Console.ReadLine());
        
        if (bid > player.BidScore)
        {
            player.Bid(bid);
            lastBidder = currentPlayer;
        }
        
        currentPlayer = (currentPlayer + 1) % 3;
        if (currentPlayer == lastBidder) break;
    }
    
    AssignLandlordRole();
}

private void AssignLandlordRole()
{
    var landlord = _players[lastBidder];
    landlord.ReceiveCards(_landlordCards);
    _landlordCards.Clear();
}

四、出牌逻辑实现

1. 牌型判断核心算法

public class PokerValidator
{
    public static bool IsValidPlay(List<Card> cards, List<Card> lastPlay)
    {
        if (lastPlay == null) return cards.Count > 0;

        var currentType = GetPokerType(cards);
        var lastType = GetPokerType(lastPlay);

        if (currentType == PokerType.None) return false;
        if (currentType != lastType) return false;

        return CompareCards(cards, lastPlay) > 0;
    }

    private static int CompareCards(List<Card> a, List<Card> b)
    {
        // 实现牌型大小比较逻辑
        // 包含单牌、对子、三带等比较规则
    }
}

2. 典型牌型判断

public enum PokerType
{
    None,
    Single,
    Pair,
    Triplet,
    Straight,
    Bomb,
    Rocket
}

public static PokerType GetPokerType(List<Card> cards)
{
    if (cards.Count == 1) return PokerType.Single;
    if (cards.Count == 2 && cards[0].Rank == cards[1].Rank) return PokerType.Pair;
    
    // 实现其他牌型判断逻辑
    // 参考:https://github.com/Avalon712/ProkerUtils-For-FightingTheLandlord
}

五、完整游戏流程

public void StartGame()
{
    _currentPhase = GamePhase.Dealing;
    DealCards();
    
    while (_currentPhase != GamePhase.Ended)
    {
        switch (_currentPhase)
        {
            case GamePhase.Dealing:
                DealCards();
                _currentPhase = GamePhase.Bidding;
                break;
                
            case GamePhase.Bidding:
                StartBidding();
                _currentPhase = GamePhase.Playing;
                break;
                
            case GamePhase.Playing:
                HandlePlayerTurn();
                CheckGameOver();
                break;
        }
    }
}

private void HandlePlayerTurn()
{
    var currentPlayer = _players[(int)DateTime.Now.Ticks % 3];
    var hand = currentPlayer.Hand.OrderBy(c => c).ToList();
    
    // 实现出牌逻辑
    // 参考:https://blog.csdn.net/qq_35353334/article/details/123456789
}

参考代码 C# 火拼 斗地主 游戏源码 www.youwenfan.com/contentcno/92563.html

六、扩展功能实现

  1. 网络对战支持

    使用Socket实现多人联机:

    public class NetworkManager
    {
        private Socket _serverSocket;
        private List<Socket> _clients = new();
    
        public void StartServer() { /* 实现TCP服务端 */ }
        public void SendGameState() { /* 发送游戏状态 */ }
    }
    
  2. AI对战系统

    实现基于蒙特卡洛树搜索的AI:

    public class AIPlayer : Player
    {
        public override List<Card> MakeMove()
        {
            // 实现决策树搜索算法
        }
    }
    

七、测试用例示例

[TestClass]
public class GameLogicTests
{
    [TestMethod]
    public void TestRocketValidation()
    {
        var cards = new List<Card>
        {
            new Card(Suit.Joker, 17),
            new Card(Suit.Joker, 18)
        };
        Assert.AreEqual(PokerType.Rocket, PokerValidator.GetPokerType(cards));
    }
}
posted @ 2025-12-25 16:36  老夫写代码  阅读(3)  评论(0)    收藏  举报