最初にカードを出すプレーヤーを変更する
新しいゲームが始まったら最初にカードを出せるプレーヤーも変えたいものです。そこでライバルのターンに関するメソッドを一部変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public partial class Form1 : Form { void ResetGame() { GameCount = 0; foreach(Player player in Players) { player.Score = 0; player.TotalScore = 0; } } private void GameStartMenuItem_Click(object sender, EventArgs e) { ResetGame(); GameStart(); } } |
RivalsTurnAsyncメソッドの変更
新しいゲームがスタートするとき、以下の処理が行なわれます。最後のRivalsTurnAsyncメソッドを少し変えます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
public partial class Form1 : Form { void GameStart() { isFromBack = false; CenterCard = null; ShuffleCard(); HandoutCards(); panelSouth.Invalidate(); panelWest.Invalidate(); panelNorth.Invalidate(); panelEast.Invalidate(); PutFirstCard(); isNotFirstCard = false; // RivalsTurnAsync(); RivalsTurnAsync(GameCount); // 変更 } } |
これまで使用してきたRivalsTurnAsyncメソッドには引数がありませんでした。これを変更します。ゲームの最初にカードを出すプレイヤーを変更するためには引数firstRivalをRivalsTurnメソッドに渡します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public partial class Form1 : Form { async void RivalsTurnAsync(int firstRival) { IsMyTurn = false; Task<bool> task = Task.Run<bool>(() => RivalsTurn(firstRival)); bool result = await task; // result == true ならゲーム続行 if(result == true) IsMyTurn = true; else OnFinishOneOfGames(); } } |
それからRivalsTurnAsyncメソッドを引数ありに変更した以上、panelSouth_MouseDownメソッドも最後の部分が変更になります。
1 2 3 4 5 6 7 8 9 10 |
public partial class Form1 : Form { private void panelSouth_MouseDown(object sender, MouseEventArgs e) { // 最後の部分以外は同じなので省略 // RivalsTurnAsync();を変更 RivalsTurnAsync(1); } } |
RivalsTurnメソッドの変更
これは引数ありのRivalsTurnメソッドです。最初にカードを出す人を変更するには
for(int i = 0; i < count; i++) { // 省略 } としている部分の0を適切な値に変更すればよいということになります。 引数が1のときはこれまでどおりの処理が行なわれます。また最初に自分がカードを出す場合は引数を0にします。
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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
public partial class Form1 : Form { bool isNotFirstCard = true; bool RivalsTurn(int firstRival) { firstRival = firstRival % Players.Count; if(firstRival == 0) return CheckPrevMyTurn(); // 0 は自分なのでライバルではない List<Player> rivals = Players.Skip(1).ToList(); // もし順番が反時計回りであれば順番をリバースする if(isFromBack) rivals.Reverse(); int count = rivals.Count; int start = firstRival - 1; // ループのはじまりの値を適切な値に変更する for(int i = start; i < count; i++) { MessageBox.Show(rivals[i].Name + "の番です"); Text = rivals[i].Name + "の番です"; // カードを出すときにプレイヤーごとに少し止める System.Threading.Thread.Sleep(500); // Aが出されていたらスキップ(最初のカードの場合は無視) if(isNotFirstCard && CenterCard.Number == 1 && isLastCardA) { isLastCardA = false; continue; } // 2が出されていたら2を出すか2のn乗枚のカードをとる(最初のカードの場合は無視) if(isNotFirstCard && CenterCard.Number == 2 && drawTwoCount > 0) { OnWasPutTwo(rivals[i]); continue; } isNotFirstCard = true; CenterCard = rivals[i].PutCard(CenterCard, ShuffledCards); // Queenが出されたときはいっしょに他のQueenも出すかどうか? if(CenterCard.Number == 12) { List<Card> queens = rivals[i].GetPutQueens(); if(queens.Count > 0) CenterCard = queens[0]; } // 上がり判定 bool isFinish = false; if(rivals[i].Cards.Count == 0) { isFinish = true; MessageBox.Show(rivals[i].Name + "が あがりました"); // あがったときもドボンされる可能性がある } // 出されたカードに他のプレイヤーはドボンできるか? // ドボンまたはドボン返し成立の場合はゲーム終了 if(DobonIfCan(rivals[i])) return false; // あがった人に誰もドボンしなかったらゲーム終了 if(isFinish) return false; if(CenterCard.Number == 1) isLastCardA = true; if(CenterCard.Number == 2) drawTwoCount = 1; // Jが出された場合 if(CenterCard.Number == 11) { Text = rivals[i].Name + "による逆回転"; System.Threading.Thread.Sleep(500); int nextRival = OnPutEleven(rivals, i); if(nextRival == -1) return CheckPrevMyTurn(); i = nextRival - 1; // インクリメントの影響を防ぐ } } // ループが終わったらあなたのターンになるのだが・・・ return CheckPrevMyTurn(); } } |
ライバルターンが終わったときに自分のターンになるのですが、最後にカードを出したライバルがAを出している場合はスキップさせられますし、2を出していた場合は2を出すかカードを取らされることになるのでその判定が必要です。 また出せるカードがない場合は自動的に処理がおこなわれます。
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 |
public partial class Form1 : Form { bool CheckPrevMyTurn() { // Aが出ているときはスキップされる if(CenterCard.Number == 1 && isLastCardA) { Text = "スキップされました"; System.Threading.Thread.Sleep(500); isLastCardA = false; return RivalsTurn(1); } // 2が出されていたら2を出すか2のn乗枚のカードをとる if(CenterCard.Number == 2 && drawTwoCount > 0) { OnWasPutTwo(Players[0]); return RivalsTurn(1); } // 自分の番だが出せるカードはあるのか? // ない場合は出せるカードを引くまでカードを取り続ける if(!AddCardIfCanNotPutCard()) return true; else return RivalsTurn(1); } } |