2009-04-11 5 views
4

Tic Tac Toeの(2人のプレーヤーで)試合を見ている最善の方法は何ですか?今、私は次のような何かを使用しています:TicTacToeで勝者を確認していますか?

if (btnOne.Text == "X" && btnTwo.Text == "X" && btnThree.Text == "X") 
{ 
    MessageBox.Show("X has won!", "X won!"); 
    return; 
} 
else 
// I'm not going to write the rest but it's really just a bunch 
// if statements. 

どうすれば複数のifを取り除くことができますか?

答えて

11

何かアロング:

rowSum == 3 || columnSum == 3 || diagnolSum == 3 

..?

+0

非常Mathyさん、私はそれが好き! – Kredns

+0

素敵なアップデート、私はこの方法で行くかもしれないと思うが、他の誰かが何か良いものを思いつくことができるかどうかを知るために質問を答えないで残す。 – Kredns

+0

別の回答ポストに抽出されます。 – chakrit

2

アウトは配列内のデータとして勝算位置を保存して、基本的には代わりに、複数のIFS文

// winnable positions 
var winnables = new[] { 
    "012", 
    "345", 
    "678", 
    "036", 
    "147", 
    "258", 
    "048", 
    "246" 
}; 

// extracted from btnOne Two Three.... 
var gameState = new[] { "X", "O", "X", "whatever" }; 


string winner = null; 

// check each winnable positions 
foreach (var position in winnables) { 

    var pos1 = int.Parse(position[0].ToString()); 
    var pos2 = int.Parse(position[1].ToString()); 
    var pos3 = int.Parse(position[2].ToString()); 

    if (gameState[pos1] == gameState[pos2] && 
     gameState[pos2] == gameState[pos3]) 
     winner = gameState[pos1]; 

} 

// do we have a winner? 
if (!string.IsNullOrEmpty(winner)) 
    /* we've got a winner */ 

のすべての可能な勝利条件を確認するためにループを使用し、btnOneを使用していないことであろうもう一つの簡単な方法btnTwo btnThree、適切な配列のボタンまたはゲームの状態をよりアクセス可能な形式で保存する配列を使用すれば、計算が簡単になります。

+0

int.Parseは少し醜いですが、それは読みやすい位置を維持しやすくします。 – chakrit

3

マルチディメンション配列にボタンを格納する場合は、行、列、および対角線を取得するための拡張メソッドを記述できます。

public static class MultiDimensionalArrayExtensions 
{ 
    public static IEnumerable<T> Row<T>(this T[,] array, int row) 
    { 
    var columnLower = array.GetLowerBound(1); 
    var columnUpper = array.GetUpperBound(1); 

    for (int i = columnLower; i <= columnUpper; i++) 
    { 
     yield return array[row, i]; 
    } 
    } 

    public static IEnumerable<T> Column<T>(this T[,] array, int column) 
    { 
    var rowLower = array.GetLowerBound(0); 
    var rowUpper = array.GetUpperBound(0); 

    for (int i = rowLower; i <= rowUpper; i++) 
    { 
     yield return array[i, column]; 
    } 
    } 

    public static IEnumerable<T> Diagonal<T>(this T[,] array, 
              DiagonalDirection direction) 
    { 
    var rowLower = array.GetLowerBound(0); 
    var rowUpper = array.GetUpperBound(0); 
    var columnLower = array.GetLowerBound(1); 
    var columnUpper = array.GetUpperBound(1); 

    for (int row = rowLower, column = columnLower; 
     row <= rowUpper && column <= columnUpper; 
     row++, column++) 
    { 
     int realColumn = column; 
     if (direction == DiagonalDirection.DownLeft) 
     realColumn = columnUpper - columnLower - column; 

     yield return array[row, realColumn]; 
    } 
    } 

    public enum DiagonalDirection 
    { 
    DownRight, 
    DownLeft 
    } 
} 

そして、あなたは3行3列でTableLayoutPanelを使用している場合、あなたは簡単にプログラム可能にあなたのボタンを作成し、Button[3, 3]配列にそれを保存することができます。

Button[,] gameButtons = new Button[3, 3]; 

for (int row = 0; column <= 3; row++) 
    for (int column = 0; column <= 3; column++) 
    { 
    Button button = new Button(); 
    // button... 
    gameLayoutPanel.Items.Add(button); 
    gameButtons[row, column] = button; 
    } 

そして勝者をチェックする:

string player = "X"; 
Func<Button, bool> playerWin = b => b.Value == player; 
gameButtons.Row(0).All(playerWin) || 
// ... 
gameButtons.Column(0).All(playerWin) || 
// ... 
gameButtons.Diagonal(DiagonalDirection.DownRight).All(playerWin) || 
// ... 
関連する問題