逆回りにするカード J
ドボンは最初はカードを出す順番は時計回りです。ところがJはこれを逆回りにさせることができるカードです。
ライバルターンはforeach文をつかっていました。ところがJが出されたらこれを逆にしなければなりません。
そこでfor文で書き直すことにしました。
順番が時計回りなのか反時計回りなのか
まず順番が時計回りなのか反時計回りなのかを管理すフィールド変数isFromBackをつくります。Jが出されたときにisFromBackがtrueならfalseに、falseならtrueに変更します。これでライバルのターンのときにカードを出す順番を変えることができます。
ライバルのターンが終わるまえに誰からJを出した場合、その瞬間逆回りになるのでこの場合はrivalsの並びをその場で変更しています。次にカードを出すのはrivalsをリバースした状態で、Jを出したプレイヤーのインデックスの次のプレイヤーです。
OnPutElevenメソッドの戻り値はつぎのライバルのインデックスの値で、戻り値が-1のときは次は自分自身の番となります。
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 |
public partial class Form1 : Form { bool isFromBack = false; // 順番が反時計回りならtrueである int OnPutEleven(List<Player> rivals, int index) { if(!isFromBack) isFromBack = true; else isFromBack = false; Player now = rivals[index]; // まずは順番を逆にする rivals.Reverse(); // Jを出したプレイヤーのインデックスを調べる int i = rivals.IndexOf(now); // Jが出された場合、次は誰になるのか? if(rivals.Count != i + 1) return i + 1; else return -1; // 自分 } } |
あとはこのメソッドを組み込むだけです。
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 97 98 99 100 101 102 |
public partial class Form1 : Form { bool RivalsTurn() { // 0 は自分なのでライバルではない List<Player> rivals = Players.Skip(1).ToList(); // もし順番が反時計回りであれば順番をリバースする if(isFromBack) rivals.Reverse(); int count = rivals.Count; for(int i = 0; i< count; i++) { // カードを出すときにプレイヤーごとに少し止める System.Threading.Thread.Sleep(500); // Aが出されていたらスキップ if(CenterCard.Number == 1 && isLastCardA) { isLastCardA = false; continue; } // 2が出されていたら2を出すか2のn乗枚のカードをとる if(CenterCard.Number == 2 && drawTwoCount > 0) { OnWasPutTwo(rivals[i]); continue; } CenterCard = rivals[i].PutCard(CenterCard, ShuffledCards); if(CenterCard.Number == 1) isLastCardA = true; if(CenterCard.Number == 2) drawTwoCount = 1; 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; // Jが出された場合 if(CenterCard.Number == 11) { // これまで時計回りであれば次回からは反時計回り // これまで反時計回りであれば次回からは時計回り Text = rivals[i].Name + "による逆回転"; int nextRival = OnPutEleven(rivals, i); if(nextRival == -1) return CheckPrevMyTurn(); i = nextRival - 1; // インクリメントの影響を防ぐ System.Threading.Thread.Sleep(500); } } // ループが終わったらあなたのターンになるのだが・・・ return CheckPrevMyTurn(); } // あなたのターンになったとき 前にカードを出したライバルが、A、2を出していないか? // あなたのターンになったのはいいが、本当に出せるカードはあるのか? bool CheckPrevMyTurn() { // Aが出ているときはスキップされる if(CenterCard.Number == 1 && isLastCardA) { Text = "スキップされました"; System.Threading.Thread.Sleep(500); isLastCardA = false; return RivalsTurn(); } // 2が出されていたら2を出すか2のn乗枚のカードをとる if(CenterCard.Number == 2 && drawTwoCount > 0) { OnWasPutTwo(Players[0]); return RivalsTurn(); } // 出せるカードがない場合は出せるカードを引くまでカードを取り続ける if(!AddCardIfCanNotPutCard()) return true; else return RivalsTurn(); } } |
自分がJを出したときの処理
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 |
public partial class Form1 : Form { private void panelSouth_MouseDown(object sender, MouseEventArgs e) { Card card = GetClickedCard(e); if(CheckUnjustClick(card)) return; Players[0].Cards.Remove(card); CenterCard = card; panelSouth.Invalidate(); if(CenterCard.Number == 1) isLastCardA = true; if(CenterCard.Number == 2) drawTwoCount = 1; if(CenterCard.Number == 11) { // フラグの効果でこれまで時計回りであれば反時計回りに // これまで反時計回りであれば時計回りになる if(!isFromBack) isFromBack = true; else isFromBack = false; } // ドボンされる可能性があるのでチェックする if(DobonIfCan(Players[0])) return; // カードがなくなったらあがり if(Players[0].Cards.Count == 0) { OnMyFinish(); return; } RivalsTurnAsync(); } } |
さいごに
新しくゲームを開始するときはフラグをもとに戻しておく必要があります。
1 2 3 4 5 6 7 8 9 10 11 |
public partial class Form1 : Form { void GameStart() { isFromBack = false; drawTwoCount = 0; // これより下は省略 } } |
お疲れ様です。
RivalsTurnメソッド内のCheckPrevMyTurn()メソッドが存在しないので、お手数ですが記述の方をお願いいたします。
ミスが多くてすみません。記事を書き直したときに記述漏れがでてしまいました。
CheckPrevMyTurn()メソッドは自分にカードを出す番がまわってきたけれども本当にカードを出せるのかをチェックするメソッドです。
前にカードを出したライバルが、A、2を出していないか?
本当に出せるカードはあるのか?
CheckPrevMyTurn()メソッドを記述するとともにRivalsTurn()メソッドを書き直しました。