0

可能であれば、これを短縮するにはどうすればよいですか?

if(moves[1] == moves[4] && moves[4] == moves[7]) { return 1;}
else if(moves[1] == moves[2] && moves[2] == moves[3]) { return 1;}
else if(moves[4] == moves[5] && moves[5] == moves[6]) { return 1;}
else if(moves[7] == moves[8] && moves[8] == moves[9]) { return 1;}
else if(moves[1] == moves[5] && moves[5] == moves[9]) { return 1;}
else if(moves[3] == moves[5] && moves[5] == moves[7]) { return 1;}
else if(moves[2] == moves[5] && moves[5] == moves[8]) { return 1;}
else if(moves[3] == moves[6] && moves[6] == moves[9]) { return 1;}
else if (moves[1] != '1' && moves[2] != '2' && moves[3] != '3' && moves[4] != '4' && moves[5] != '5' && moves[6] != '6' && moves[7] != '7' && moves[8] != '8' && moves[9] != '9') {
return 2;}

値の動きには、ゲームの勝者を得るために比較される X または 0 が格納されます。これをできるだけ短くする必要があります。

数字のランダムな組み合わせのため、これを行う他の方法は考えられません

上記のコードは CheckWinner と呼ばれる関数で、ユーザーが選択した入力を、埋められた位置の配列とともに渡します。

コードは、move[position] を勝ち手の他のすべての組み合わせに対してチェックし、勝ち手が検出された場合は 1 を返します。

コードの最後のビットは、グリッド上のすべてのスペースをチェックし、スペースが残っていない場合は 2 を返して引き分けを呼び出します。

お役に立てれば

4

7 に答える 7

3

このようなものはどうですか:

#include <stdio.h>

int winners[8][3] = { {1, 2, 3},
            {4, 5, 6},
            {7, 8, 9},
            {1, 4, 7},
            {2, 5, 8},
            {7, 8, 9},
            {1, 5, 9},
            {3, 5, 7}};

int moves[10] = { 0,
          1, 2, 0,
          0, 2, 0,
          0, 2, 1};

int main()
{
    int i;
    for (i=0;i<8;++i)
    {
        if (moves[winners[i][0]] == moves[winners[i][1]] &&
            moves[winners[i][1]] == moves[winners[i][2]])
            printf("Player %d wins!\n",moves[winners[i][0]]);
    }
    return 0;
}

配列の勝者は、さまざまな勝利の組み合わせと、それぞれのループ テストについて説明します。

于 2013-05-06T23:33:27.183 に答える
2

すべての数字がランダムというわけではありません...行の場合、式はN*3+1, N*3+2, N*3+3、列N+1, N+4, N+7などの場合...どこで0 <= N <= 2. それを表す他の多くの方法。行、列、および対角線をチェックする個別の関数を作成できます。

于 2013-05-06T23:19:50.883 に答える
1
template <typename T> bool equal(T a, T b, T c) { return (a==b) && (b==c); }

int foo(char (&moves)[10])
{
    auto eqset = [&](int i1, int i2, int i3) { return equal(moves[i1], moves[i2], moves[i3]); };
    if (eqset(1,4,7) || eqset(1,2,3) || eqset(4,5,6) || eqset(7,8,9) || eqset(1,5,9) || eqset(3,5,7) || eqset(2,5,8) || eqset(3,6,9))
        return 1;
    else if (moves[1] != '1' && moves[2] != '2' && moves[3] != '3' && moves[4] != '4' && moves[5] != '5' && moves[6] != '6' && moves[7] != '7' && moves[8] != '8' && moves[9] != '9') {
        return 2;
    }
}

リテラルの投稿されたコードにかなり近いままです。すべてのコード パスが値を返すわけではないことに注意してください。

それ以外の場合は、次のように進めることができます。

for (int i = 1; i<10; i++)
    if (moves[i] == ('0'+i))
        return 0; // ???

return 2;
于 2013-05-06T23:33:02.013 に答える
1

最後に行われたプレーの行、列、および場合によっては対角線を確認してください。グリッド全体をチェックする必要はありません。

gridを格納しているため、2次元配列も使用してください。次に、行をループして一致を探し、列をループして一致を探します。

于 2013-05-06T23:24:17.550 に答える
0

マクロを使用してコードを簡単に短縮できます。

#define comp(i,j,k) (moves[i]==moves[j] && moves[j]==moves[k])
return comp(1,2,3) || comp(4,5,6) || comp(7,8,9)
    || comp(1,5,9) || comp(3,5,7) || comp(2,5,8);

それ以外の場合は、ボードを回転できます。

#define comp(i,j,k) (moves[i]==moves[j] && moves[j]==moves[k])

int rot[6][2] = { {1, 3}, {7, 9}, {9, 1}, {2, 6}, {4, 8}, {2, 8} };
for (int x = 0; x < 4; x++) {
    if (comp(1,2,3) || comp(4,5,6) || comp(1,5,9)))
        return 1;
    for (int i = 0; i < 6; i++)
        std::swap(moves[rot[i][0]], moves[rot[i][1]]);
}
return 0;

説明付きの完全な C++ コードを次に示します (C++ ではなく、簡単な C にすることもできますが、私は好きですstd::swap)。ボードには意味のない数字が含まれているため、回転を確認できます。

#include <iostream>

void print_tic(int moves[]) {
    for (int i = 1; i < 10; i += 3)
        std::cout << moves[i] << moves[i + 1] << moves[i + 2] << std::endl;
    std::cout << std::endl;
}

void rotate(int moves[]) {
    static const int rot[6][2] = {{1, 3}, {7, 9}, {9, 1}, {2, 6}, {4, 8}, {2, 8} };
    for (int i = 0; i < 6; i++)
        std::swap(moves[rot[i][0]], moves[rot[i][1]]);
}

int comp(int moves[], int i, int j, int k) {
    return moves[i]==moves[j] && moves[j]==moves[k];
}

int main() {
    int moves[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; //meaningless.

    print_tic(moves);
    for (int x = 0; x < 4; x++) {
        rotate(moves);
        print_tic(moves);
        if (comp(moves, 1,2,3)  // first row
             || comp(moves, 4,5,6)  // second row - forget that earlier
             || comp(moves, 1,5,9)) // main diagon
            return 1;
    }
    return 0;
}

印刷物を使用すると、回転を確認できます。

123
456
789

741
852
963

987
654
321

369
258
147

123
456
789

回転できるのは 1 回だけcomp()で、3 行目はもう 1 回回転します。

于 2013-05-07T01:55:24.403 に答える
0

これが役立つかどうかはわかりませんが、試してみます。コードで一目でわかるのは、ほとんどの条件が 1 を返し、2 を返すのは 1 つのケースだけです。したがって、if 条件を書くだけです。 2 を返し、それ以外の場合はすべて1 を返しますね。

例えば

if (moves[1] != '1' && moves[2] != '2' && moves[3] != '3' && moves[4] != '4' && moves[5] != '5' && moves[6] != '6' && moves[7] != '7' && moves[8] != '8' && moves[9] != '9') {
return 2;}
else
{
// return 1 probably
}

うーん...いいえ、上記のコードで私の言葉を取り戻しますが、他のすべてのケースでは1が返されますが、あなたのケースでは1が返されたくない状況があるかもしれません...

于 2013-05-06T23:19:13.520 に答える