private async Task <GameStatus> ExecuteBoss(CancellableReceiver <GameProgress> channel) { var v = _random.NextDouble(); if (v < 0.5) { // 50% で平均10万ダメージの全体攻撃 var attacks = _players.Where(p => !p.IsDead).Select(p => BossAttack(p, 90000, 110000)).ToArray(); await channel.SendAsync(new BossAttack(attacks)); } else { // 50% で平均20万ダメージの単体攻撃 var alive = _players.Where(p => !p.IsDead).ToArray(); var i = _random.Next(alive.Length); var target = alive[i]; var attack = BossAttack(target, 190000, 210000); await channel.SendAsync(new BossAttack(new[] { attack })); } // コンティニュー処理 if (_players.Any(p => p.IsDead && !p.IsRetired)) { var messages = _players.Where(p => p.IsDead && !p.IsRetired).Select(p => new ContinuePrompt(p)).ToArray(); await channel.SendAsync(messages); var continuedPlayers = new List <PlayerSnapshop>(); foreach (var m in messages) { // とりあえず、コンティニューしなかった人はリタイア扱いにしとく。 if (m.Response) { m.Player.Resurrect(); continuedPlayers.Add(m.Player.Snapshot()); } else { m.Player.Retire(); } } if (continuedPlayers.Any()) { await channel.SendAsync(new Continue(continuedPlayers)); } } // 全滅判定 if (_players.All(p => p.IsDead)) { return(GameStatus.PlayerDestroyed); } return(GameStatus.Playing); }
private async Task <GameStatus> ExecutePlayer(Player player, CancellableReceiver <GameProgress> channel) { if (player.IsDead) { return(GameStatus.Playing); } _area.RedrawAll(player.Index); player.InvalidateHand(); var res = (await channel.SendAsync(new CommandPrompt(player))).GetResponse(); if (res?.RedrawCardIndexes is int[] indexes) { _area.Redraw(player.Index, indexes); } player.InvalidateHand(); var damage = Judge.Score(player); Boss.Hp -= damage; if (Boss.Hp < 0) { Boss.Hp = 0; } await channel.SendAsync(new PlayerAttack(player.Snapshot(), player.Hand, damage, Boss.Hp)); if (Boss.Hp == 0) { return(GameStatus.BossDefeated); } else { return(GameStatus.Playing); } }
private async Task <GameStatus> ExecuteTurn(int turn, CancellableReceiver <GameProgress> channel) { await channel.SendAsync(new TurnStarted(turn)); foreach (var actor in GetActors()) { var stat = await(actor != null ? ExecutePlayer(actor, channel): ExecuteBoss(channel)); if (stat != GameStatus.Playing) { return(stat); } } return(GameStatus.Playing); }
public async Task Execute(CancellableReceiver <GameProgress> channel) { var result = await ExecuteBody(channel); await channel.SendAsync(new FinishGame(result.status, result.turn, Boss.Hp, Players.Select(x => x.Snapshot()).ToArray())); }