Я не очень хорошо знаю Java, но знаю C, поэтому я попробовал идею магического квадрата adk (наряду с ограничение поиска Hardwareguy ).
// tic-tac-toe.c
// to compile:
// % gcc -o tic-tac-toe tic-tac-toe.c
// to run:
// % ./tic-tac-toe
#include <stdio.h>
// the two types of marks available
typedef enum { Empty=2, X=0, O=1, NumMarks=2 } Mark;
char const MarkToChar[] = "XO ";
// a structure to hold the sums of each kind of mark
typedef struct { unsigned char of[NumMarks]; } Sum;
// a cell in the board, which has a particular value
#define MAGIC_NUMBER 15
typedef struct {
Mark mark;
unsigned char const value;
size_t const num_sums;
Sum * const sums[4];
} Cell;
#define NUM_ROWS 3
#define NUM_COLS 3
// create a sum for each possible tic-tac-toe
Sum row[NUM_ROWS] = {0};
Sum col[NUM_COLS] = {0};
Sum nw_diag = {0};
Sum ne_diag = {0};
// initialize the board values so any row, column, or diagonal adds to
// MAGIC_NUMBER, and so they each record their sums in the proper rows, columns,
// and diagonals
Cell board[NUM_ROWS][NUM_COLS] = {
{
{ Empty, 8, 3, { &row[0], &col[0], &nw_diag } },
{ Empty, 1, 2, { &row[0], &col[1] } },
{ Empty, 6, 3, { &row[0], &col[2], &ne_diag } },
},
{
{ Empty, 3, 2, { &row[1], &col[0] } },
{ Empty, 5, 4, { &row[1], &col[1], &nw_diag, &ne_diag } },
{ Empty, 7, 2, { &row[1], &col[2] } },
},
{
{ Empty, 4, 3, { &row[2], &col[0], &ne_diag } },
{ Empty, 9, 2, { &row[2], &col[1] } },
{ Empty, 2, 3, { &row[2], &col[2], &nw_diag } },
}
};
// print the board
void show_board(void)
{
size_t r, c;
for (r = 0; r < NUM_ROWS; r++)
{
if (r > 0) { printf("---+---+---\n"); }
for (c = 0; c < NUM_COLS; c++)
{
if (c > 0) { printf("|"); }
printf(" %c ", MarkToChar[board[r][c].mark]);
}
printf("\n");
}
}
// run the game, asking the player for inputs for each side
int main(int argc, char * argv[])
{
size_t m;
show_board();
printf("Enter moves as \"<row> <col>\" (no quotes, zero indexed)\n");
for( m = 0; m < NUM_ROWS * NUM_COLS; m++ )
{
Mark const mark = (Mark) (m % NumMarks);
size_t c, r;
// read the player's move
do
{
printf("%c's move: ", MarkToChar[mark]);
fflush(stdout);
scanf("%d %d", &r, &c);
if (r >= NUM_ROWS || c >= NUM_COLS)
{
printf("illegal move (off the board), try again\n");
}
else if (board[r][c].mark != Empty)
{
printf("illegal move (already taken), try again\n");
}
else
{
break;
}
}
while (1);
{
Cell * const cell = &(board[r][c]);
size_t s;
// update the board state
cell->mark = mark;
show_board();
// check for tic-tac-toe
for (s = 0; s < cell->num_sums; s++)
{
cell->sums[s]->of[mark] += cell->value;
if (cell->sums[s]->of[mark] == MAGIC_NUMBER)
{
printf("tic-tac-toe! %c wins!\n", MarkToChar[mark]);
goto done;
}
}
}
}
printf("stalemate... nobody wins :(\n");
done:
return 0;
}
Хорошо компилируется и тестируется.
% gcc -o tic-tac-toe tic-tac-toe.c
% ./tic-tac-toe
| |
---+---+---
| |
---+---+---
| |
Enter moves as " " (no quotes, zero indexed)
X's move: 1 2
| |
---+---+---
| | X
---+---+---
| |
O's move: 1 2
illegal move (already taken), try again
O's move: 3 3
illegal move (off the board), try again
O's move: 2 2
| |
---+---+---
| | X
---+---+---
| | O
X's move: 1 0
| |
---+---+---
X | | X
---+---+---
| | O
O's move: 1 1
| |
---+---+---
X | O | X
---+---+---
| | O
X's move: 0 0
X | |
---+---+---
X | O | X
---+---+---
| | O
O's move: 2 0
X | |
---+---+---
X | O | X
---+---+---
O | | O
X's move: 2 1
X | |
---+---+---
X | O | X
---+---+---
O | X | O
O's move: 0 2
X | | O
---+---+---
X | O | X
---+---+---
O | X | O
tic-tac-toe! O wins!
% ./tic-tac-toe
| |
---+---+---
| |
---+---+---
| |
Enter moves as " " (no quotes, zero indexed)
X's move: 0 0
X | |
---+---+---
| |
---+---+---
| |
O's move: 0 1
X | O |
---+---+---
| |
---+---+---
| |
X's move: 0 2
X | O | X
---+---+---
| |
---+---+---
| |
O's move: 1 0
X | O | X
---+---+---
O | |
---+---+---
| |
X's move: 1 1
X | O | X
---+---+---
O | X |
---+---+---
| |
O's move: 2 0
X | O | X
---+---+---
O | X |
---+---+---
O | |
X's move: 2 1
X | O | X
---+---+---
O | X |
---+---+---
O | X |
O's move: 2 2
X | O | X
---+---+---
O | X |
---+---+---
O | X | O
X's move: 1 2
X | O | X
---+---+---
O | X | X
---+---+---
O | X | O
stalemate... nobody wins :(
%
Это было весело, спасибо!
На самом деле, думая об этом, вам не нужен магический квадрат, просто счетчик для каждой строки / столбца / диагонали. Это немного проще, чем обобщение магического квадрата до n
& times; n
матрицы, так как вам просто нужно сосчитать до n
.