I've got this 3 x 3 array of char that's supposed to represent a tic-tac-toe board, and before, I would use a bunch of "if" statements to see if there were 3 in a row.
... if ((board[0][0] == board[0][1]) && (board[0][1] == board[0][2])) { ... } ...
I realized that this is a lot of typing, and quite error-prone, so is there a better way to do this?
You could change it to check from only where the last move was made.
//lr = lastMoveRow
//lc = lastMoveCol
// no need to check blank with last move known
if (board[0][lc] == board[1][lc] && board[0][lc] == board[2][lc] ||
board[lr][0] == board[lr][1] && board[lr][0] == board[lr][2]){
// Game over
}
// Check diagonals
if (board[1][1] != blank &&
(board[0][0] == board[1][1] && board[0][0] == board[2][2] ||
board[2][0] == board[1][1] && board[2][0] == board[0][2])){
// Game over
}
Or - Checking all states:
//Check horizontals and verticals at once
for (int i = 0; i < 3; ++i){
// Check column and row at once
if (board[0][i] != blank && board[0][i] == board[1][i] && board[0][i] == board[2][i] ||
board[i][0] != blank && board[i][0] == board[i][1] && board[i][0] == board[i][2]){
// Game over
}
}
// Check diagonals
if (board[1][1] != blank &&
(board[0][0] == board[1][1] && board[0][0] == board[2][2] ||
board[2][0] == board[1][1] && board[2][0] == board[0][2])){
// Game over
}
Or if you do turn it into a bit by bit system - keep separate X and O boards for ease of updating. Then you only need 9 bits for x, 9 bits for O, and your winning boards matches are much simpler. (To find open spaces in this case, just bitwise or the x and o boards)
// winning 9 bit boards
// int winningBoards[8]
000000111
000111000
111000000
001001001
010010010
100100100
100010001
001010100
//xBoard and yBoard can be ints
for (int i = 0; i < 8; ++i){
if (xBoard & winningBoards[i] == winningBoards[i]){
//Game over
}
}
You can remove the paranthesis because &&
has lower priority than ==
if (board[0][0] == board[0][1] && board[0][1] == board[0][2])
You can also define an inline function (or macro) to factor out equality
inline bool are_equal(int a, int b, int c) {
return a == b && b == c;
}
...
if (are_equal(board[0][0], board[0][1], board[0][2]))
Note that a==b==c
does not return what you need. For instance, 0==0==1
is true in many C-derived languages.
You could loop it. For instance to check all of the rows you might do:
for(int i = 0; i < 3; i++){
if((board[i][0]==board[i][1]) && (board[i][1]==board[i][2])){
....
}
}
And do something similar for the columns. Then you just need to check the diagonals separately.
I don't know about "better", but you could break things up serially:
//Set empty to whatever value you're using for an empty square.
#define empty '\0'
bool thereIsALine(char matrix[3][3])
{
char c;
//Check all columns:
for(int i = 0; i < 3; i++)
{
c = matrix[i][0];
if (c == empty)
break;
if (c == matrix[i][1] && c == matrix[i][2])
return true;
}
//Check all rows:
for(int i = 0; i < 3; i++)
{
c = matrix[0][i];
if (c == empty)
break;
if (c == matrix[1][i] && c == matrix[2][i])
return true;
}
//Check diagonals
c = matrix[1][1];
if (c == empty) return false;
if (c == matrix[0][2] && c == matrix[2][0] )
return true;
if (c == matrix[0][0] && c == matrix[2][2] )
return true;
return false;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With