首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >订阅工厂里的活动--更好的地方?

订阅工厂里的活动--更好的地方?
EN

Software Engineering用户
提问于 2019-11-18 15:44:58
回答 2查看 127关注 0票数 -1

我正在WPF中实现一个事件驱动的游戏,并有以下Blackjack类:

代码语言:javascript
运行
复制
public class Blackjack
{
    public Dealer Dealer { get; } = new Dealer();
    public Player Player { get; } = new Player();

    public IList<Player> AiPlayers { get; } = new List<Player>();

    public event EventHandler<EventArgs>? NewGameStarted;
    public event EventHandler<EventArgs>? HandStarted;
    public event EventHandler<GameOverEventArgs>? HandEnded;

    public Blackjack()
    {
        Dealer.Hand.Busted += DealerBusted;

        Player.BetPlaced += BetPlaced;
        Player.PlayerHit += PlayerHit;
        Player.PlayerStand += PlayerStand;
        Player.Hand.Blackjack += PlayerBlackjack;
        Player.Hand.Busted += PlayerBusted;
        _gameStates[Player] = GameStates.PLAYING;
    }

    public void StartNewGame(int numAiPlayers)
    {
        for (var i = 0; i < numAiPlayers; i++)
        {
            var ai = new Player();
            AiPlayers.Add(ai);
            ai.PlayerHit += PlayerHit;
            ai.PlayerStand += PlayerStand;
            ai.Hand.Blackjack += PlayerBlackjack;
            ai.Hand.Busted += PlayerBusted;

            _gameStates[ai] = GameStates.PLAYING;
        }

        OnNewGameStarted(new EventArgs());
    }

    // More methods
}

但是正如您所看到的,player/ai创建开始污染我的构造函数和StartNewGame方法。此外,我希望能够使用不同的认可机构来模拟不同的策略。

我想把它搬到一个工厂,但意识到我会订阅工厂内的Blackjack活动。我觉得很奇怪..。这是一件正常的事情吗?还是最好在我的Blackjack类中创建处理player/ai创建和连接事件的方法。

EN

回答 2

Software Engineering用户

发布于 2020-09-04 07:43:24

如果Blackjack对象可以构建不同的方式,那么工厂模式将是有用的。这里似乎不是这样的。您关心需要在构造函数中映射的事件处理程序的数量。那么,简化这些事件如何?

我看到的是好的,事件名称包含有关事件的上下文,每个事件被映射到它的处理程序一对一。

代码语言:javascript
运行
复制
ai.PlayerHit += PlayerHit

如果事件的名称变成了只代表感兴趣的对象的泛型事件的属性,那么会发生什么呢?

代码语言:javascript
运行
复制
ai.OnAction += OnAction

该事件可能包含有关所采取的操作的信息;可用于决定如何处理该事件的信息;您在事件处理程序中编码的内容将成为方法。

代码语言:javascript
运行
复制
class ActionEvent  // information about the event
   enum PlayerAction

enum PlayerAction  // an enumeration containing the player actions
   Bet
   Hit
   Stand

然后,可以在单个事件处理程序中使用if语句。

代码语言:javascript
运行
复制
if(e.PlayerAction = Bet)
   PlayBet();

这样,就可以将所有事件减少到一个事件,这样就更容易在构造函数中进行配置。这就像工厂的想法,你现在是决定做什么,而不是如何建设。

希望这是有帮助的。编码愉快。

票数 1
EN

Software Engineering用户

发布于 2020-04-06 18:04:35

我可能会做这样的事:

代码语言:javascript
运行
复制
   /// <summary>
   /// Immutable snapshot of a table that you
   /// can use to display to players or AIs.
   /// </summary>
   internal sealed class Table
   {
   }

   /// <summary>
   /// Represents a round of the game.
   /// </summary>
   internal sealed class Round
   {
       private readonly IEnumerable<Player> players;

       public Round(IEnumerable<Player> players)
       {
           this.players = players;
       }

       public void RunGame()
       {
           while (players.Any(t => !t.IsFinished))
           {
               foreach (var player in players.Where(t => !t.IsFinished).ToArray())
               {
                   var play = player.GetPlay(CurrentTable);
               }
           }
       }

       /// <summary>
       /// Returns a current snapshot of the table.
       /// </summary>
       private Table CurrentTable { get; }

       private void UpdateState(Player player, Play play)
       {
           //Update any state needed to make the table.
       }
   }

   /// <summary>
   /// Represents a player - implementations for different
   /// AIs and for the human player.
   /// </summary>
   internal abstract class Player
   {
       public abstract Play GetPlay(Table currentTableState);

       public abstract bool IsFinished { get; }
   }

   /// <summary>
   /// Represents the result of a play made by a player.
   /// </summary>
   internal sealed class Play
   {
       public bool IsBet { get; }
       public bool IsHit { get; }
       public bool IsStand { get; }
       public decimal Amount { get; }

       private Play(bool isBet, bool isHit, bool isStand, decimal amount)
       {
           IsBet = isBet;
           IsHit = isHit;
           IsStand = isStand;
           Amount = amount;
       }
   }

在这一点上,游戏指导球员,而不是相反的方式,所以没有必要让游戏听取事件。任何事件都将是人工玩家实现的实现细节。

票数 0
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/401250

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档