如果有可能,我可以缩短它吗?
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的函数,它传递用户选择的输入,其中包含已填充的位置数组
代码检查移动[位置]与获胜移动的所有其他组合,如果已检测到获胜移动则返回1.
最后一段代码检查网格上的所有空格,如果没有空格,则返回2以调用绘图。
希望这有帮助
答案 0 :(得分: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;
}
阵列获胜者描述了各种获胜组合以及每个组合的循环测试。
答案 1 :(得分:2)
并非所有数字都是随机的...对于行,公式为N*3+1, N*3+2, N*3+3
,列为N+1, N+4, N+7
,等等...... 0 <= N <= 2
。许多其他方式来表示它。您可以创建单独的函数来检查行,列和对角线。
答案 2 :(得分:1)
只需检查最后一次播放的行,列和可能的对角线。您无需检查整个网格。
由于您正在存储网格,因此也使用二维数组。然后循环遍历行以查找匹配项,并遍历列以查找匹配项。
答案 3 :(得分: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;
答案 4 :(得分:0)
我不确定这会有所帮助,但我会尝试一下: 我现在在你的代码中看到的一目了然是你的大多数条件都返回1, 只有在一种情况下你返回2.所以我只会写if条件返回2, 并且在所有其他情况下返回1,不是吗?
e.g。
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被退回的情况......
答案 5 :(得分:0)
这可以检查胜利......你可能会说它“更短”。
// Check rows and columns
for( int i = 0; i < 3; i++ ) {
char *row = &moves[3*i+1];
char *col = &moves[i+1];
if( row[0] == row[1] && row[0] == row[2] ) return 1;
if( col[0] == col[3] && col[0] == col[6] ) return 1;
}
// Check diagonals
if( moves[1] == moves[5] && moves[1] == moves[9] ) return 1;
if( moves[3] == moves[5] && moves[3] == moves[7] ) return 1;
还有很多其他方法可以做到这一点。一种方法是简单地为每行,列和对角线保持计数器。如果播放了十字,则将1添加到相关计数器。如果播放了naught,则从相关计数器中减去1。如果任何计数器达到3或-3,则赢得游戏。每次播放需要非常少量的操作。无需检查整个电路板。
答案 6 :(得分: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
您只能旋转一次,在第三行的另一个comp()
的展开处。