Contents
点数はどうするのか?
ドボンは1回で終わりではなく、時間や回数を決めて何回か繰り返してプレイします。そこで必要になるのが「点数計算」です。これはさまざまなルールがあるのですが、今回はこれを採用することにします。
これによると各カードは
役札(A, 2, 8, J)は20点
絵札(Q, K)は10点
その他(3, 4, 5, 6, 7, 9, 10)は数字通りの点数
となっています。
ゲームが終了したときに上がったプレイヤー以外は手札のカードの得点を合計した分だけマイナスとなり、上がったプレイヤーには他のプレイヤーのマイナスの合計分がプラスとして与えられるわけです。
ではそのように作りかえましょう。
Scoreプロパティ
まず点数を管理するためにはPlayerクラスに新しいプロパティを追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public class Player { public int Score { set; get; } = 0; public int TotalScore { set; get; } = 0; } |
点数計算のタイミング
誰かが上がる、またはドボン(ドボン返しを含む)をしたときはRivalsTurnメソッドがfalseを返します。そこで
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public partial class Form1 : Form { async void RivalsTurnAsync() { IsMyTurn = false; Task<bool> task = Task.Run<bool>(() => RivalsTurn()); bool result = await task; // result == true ならゲーム続行 if(result == true) IsMyTurn = true; else { DialogResult dr = MessageBox.Show("ゲーム終了\nもう一度やりますか?", "確認", MessageBoxButtons.YesNo); if(dr == DialogResult.Yes) GameStart(); } } } |
となっているのを
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public partial class Form1 : Form { async void RivalsTurnAsync() { IsMyTurn = false; Task<bool> task = Task.Run<bool>(() => RivalsTurn()); bool result = await task; // result == true ならゲーム続行 if(result == true) { IsMyTurn = true; } else { // 点数計算をする } } } |
と変更します。
また自分が上がったときのことも考える必要があります。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public partial class Form1 : Form { void OnMyFinish() { MessageBox.Show(Players[0].Name + "が あがりました"); // 出されたカードに他のプレイヤーはドボンできるか? if(!DobonIfCan(Players[0])) MessageBox.Show(Players[0].Name + "の勝ちです"); // ここでも点数計算をする } } |
GameCountプロパティ
また何回続けるのかも指定する必要があります。
1 2 3 4 5 6 7 8 9 10 |
public partial class Form1 : Form { int GameCountMax = 5; int GameCount { get; set; } = 0; } |
ひとつのゲームが終わったときの処理
ひとつのゲームが終わったら自作メソッドのOnFinishOneOfGamesを実行します。ここで点数計算とその結果の表示をおこないます。またGameCountMaxとGameCountが等しくなったらゲームは終わりです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public partial class Form1 : Form { void OnFinishOneOfGames() { GameCount++; CalcScore(); ShowScore(); if(GameCountMax == GameCount) { OnFinishAllGames(); } else { GameStart(); } } } |
OnFinishAllGamesはすべてのゲームが終了したときに呼ばれます。テーブルの上にあるカードを消去してメッセージボックスを表示させます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public partial class Form1 : Form { void OnFinishAllGames() { foreach(Player player in Players) { player.Cards.Clear(); player.PlayerPanel.Invalidate(); CenterCard = null; } MessageBox.Show("すべてのゲームが終了しました"); } } |
点数計算と結果の表示
ゲームが終了したときにカードをもっている人が敗者、もっていない人が勝者です。
まず敗者がもっているカードを調べます。そしてその合計を勝者の得点とします。点数計算が終わったらShowScoreメソッドを呼んで結果を表示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
public partial class Form1 : Form { void CalcScore() { Player winner = Players.First(x => x.Cards.Count == 0); Player[] losers = Players.Where(x => x.Cards.Count > 0).ToArray(); int winnerScore = 0; foreach(Player loser in losers) { // 役札(A, 2, 8, J)は20点 // 絵札(Q, K)は10点 // その他(3, 4, 5, 6, 7, 9, 10)は数字通りの点数 int minusScore = 0; foreach(Card card in loser.Cards) { int num = card.Number; if(num == 1 || num == 2 || num == 8 || num == 11) minusScore += 20; else if(num == 12 || num == 13) minusScore += 10; else minusScore += num; } // 1ゲームにおける変動 loser.Score = -minusScore; // トータルスコア loser.TotalScore -= minusScore; // 勝者以外の負け点の合計が勝者の得点となる winnerScore += minusScore; } winner.Score = winnerScore; winner.TotalScore += winnerScore; } void ShowScore() { Form2 form2 = new Form2(); form2.Players = Players; form2.ShowDialog(); } } |
これは結果を表示するフォームです。
点数が一番高い人と低い人がわかるように表示色を変えています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
public partial class Form2 : Form { public List<Player> Players = null; public Form2() { InitializeComponent(); StartPosition = FormStartPosition.CenterParent; Paint += Form2_Paint; } private void Form2_Paint(object sender, PaintEventArgs e) { Font font = new Font("MS ゴシック", 12, FontStyle.Bold); Point pt = new Point(40, 20); e.Graphics.DrawString("ゲームの結果", font, Brushes.Black, pt); pt.Y += 30; int loserScore = Players.Min(x => x.Score); foreach(Player player in Players) { string str; if(player.Score > 0) { str = String.Format("{0}: +{1}\n", player.Name, player.Score); e.Graphics.DrawString(str, font, Brushes.Red, pt); } else { if(loserScore == player.Score) { str = String.Format("{0}: {1}\n", player.Name, player.Score); e.Graphics.DrawString(str, font, Brushes.Blue, pt); } else { str = String.Format("{0}: {1}\n", player.Name, player.Score); e.Graphics.DrawString(str, font, Brushes.Black, pt); } } pt.Y += 20; } pt.Y += 30; e.Graphics.DrawString("トータル", font, Brushes.Black, pt); pt.Y += 30; int topScore = Players.Max(x => x.TotalScore); foreach(Player player in Players) { string str; if(player.Score > 0) { if(player.TotalScore == topScore) { str = String.Format("{0}: +{1}\n", player.Name, player.TotalScore); e.Graphics.DrawString(str, font, Brushes.Red, pt); } else { str = String.Format("{0}: +{1}\n", player.Name, player.TotalScore); e.Graphics.DrawString(str, font, Brushes.Black, pt); } } else { str = String.Format("{0}: {1}\n", player.Name, player.TotalScore); e.Graphics.DrawString(str, font, Brushes.Black, pt); } pt.Y += 20; } } } |