这就是我现在所拥有的:单人类GameManager
,主要由ConcurrentDictionary
组成,其中包含所有正在进行的游戏(将游戏板和两个玩家的缺口绑定到游戏中) ID)。我还有一个SignalR中心,GameHub
,方法MakeAMove(ulong gameId, Move move)
从字典中检索相关的gameId
游戏,lock
上面的游戏,检查已调用的玩家该方法是现在应该采取行动的玩家,如果是,则对游戏的主板进行适当的更改,向此游戏的所有观察者广播此移动,并在必要时结束游戏,宣布它为玩家X的胜利或平局并将其从字典中移除。
我没有的是计时器。我认为计时器是必要的,因为没有它,许多游戏可能永远不会结束并永远留在这个词典中。计时器的工作方式应该是如果玩家未能在分配的时间内进行移动,游戏将自动结束并且这样的玩家被宣布为失败者。
我不知道如何实施这样的计时器。我有一些想法,但我不确定哪一个是正确的,如果有的话。
我必须解决这个对我来说似乎并不可怕的任务的唯一想法是这样的:ConcurrentDictionary
将gameId
绑定到Game
类的实例。然后每个这样的实例都有await
的方法,直到应该进行移动的玩家的计时器用完或直到GameHub
通知此方法已经发出移动顺序,以先发生者为准。但是,我无知如何实现这一点。
这是正确的方法吗?如果是,那我该如何让这个方法等到计时器用完或移动订单到达GameHub
?
编辑:我支持我应该写这样的东西:
await Task.WhenAny(
Task.Delay(players_available_time_left),
??something_to_mean_a_move_order_has_arrived??
);
答案 0 :(得分:1)
你可以简单地使用一个你在每个回合开始并在完成移动后停止的计时器:
private System.Timers.Timer Timer = null;
private double TimerDelay = 30d * 1000d; // 30 seconds
private void StartTimer()
{
Timer = new System.Timers.Timer() { Interval = TimerDelay , AutoReset = false};
Timer.Elapsed += Timer_Elapsed;
Timer.Start();
}
private void StopTimer()
{
Timer.Stop();
}
private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
// stop the timer
StopTimer();
// call the method to make the player lose and end the game
EndGame();
}
当您启动播放器时,请拨打StartTimer()
并将其释放。当玩家结束时,它会调用StopTimer()
并停止计时器调用游戏结束。如果计时器用完,它将自动调用游戏结束。