Крестики нолики Java - написать функцию для определения победителя или ничьей
Игра крестики - нолики на Java учимся определять победителя.
Для этого напишем универсальную функцию, которая принимает матрицу целых чисел N*N (1 <= N <= 300), значения могут быть:
0 — клетка свободна 1 — клетка занята первым игроком 2 — клетка занята вторым игроком Функция должна возвращать:
1, если есть выигрышная комбинация для первого игрока 2, если есть выигрышная комбинация для второго игрока -1, если уже никто победить не сможет (присутствуют 1 и 2 на любой строке, столбце, диагоналях) 0, если победителя еще нельзя определить Выигрышная комбинация — вся строка или столбец, или диагональ заняты одним игроком.
Сигнатура функции Название функции: determineWinner.
Параметры: int[][] grid.
Возвращаемый тип: int.
Примеры Входные данные grid = [ [ 1, 0, 2 ], [ 0, 1, 2 ], [ 0, 0, 1 ] ]; Выходные данные result = 1;
Решила эту задачу. но не до конца. Очень прошу помочь разобраться, где именно я ошиблась Мой Вопрос: Моя программа не верно выводит результат нечьей. Согласно моего кода работают все 8 кобминаций выигрыша. но результат 0 и -1 определяет не верно. Пожалуйста помогите разобраться. Вот мой код:
public class TicTacToe_103 {
public static int determineWinner(int[][] grid) {
int result = -1;
int n = grid.length;
int maxId = n - 1; // последний элемент массива( строки)
// проверяем комбинацию главная диагональ
int[] arrayD = new int[n];
for (int i = 0; i < n; i++) {
arrayD[i] = grid[i][i];
}
result = winner(arrayD);
if (result == 1 || result == 2) {
return result;
}
//проверяем комбинации строк
int [] arrayRow = new int[n];
for (int i = 0, j = 0; i < n && j < n; j++){
arrayRow[j] = grid[i][j];
if (j == maxId){
j = -1;
result = winner(arrayRow);
if (result == 1 || result == 2) {
return result;
}
i++;
}
}
// проверяем комбинации стобцов
int [] arrayCol = new int[n];
for (int i = 0, j = 0; i < n && j < n; i++){
arrayCol[i] = grid[i][j];
if (i == maxId){
i = -1;
result = winner(arrayCol);
if (result == 1 || result == 2){
return result;
}
j++;
}
}
// проверяем комбинацию побочная диагональ
int[] arrayDr = new int[n];
for (int i = maxId; i >= 0; i--){
arrayDr[i] = grid[i][maxId - i];
}
result = winner(arrayDr);
if (result == 1 || result == 2){
return result;
}
return result;
}
// дополнительный метод на выигрыш
public static int winner(int[] bestPlayer) {
int result = 0;
int n = bestPlayer.length;
int count = 0;
int count1 = 0;
int count2 = 0;
// в цикле проходимся по ячейкам массива
for (int i = 0; i < n; i++) {
// если первая ячейка равна 1, то проверяем всю строку с помощью счетчика1
if (bestPlayer[i] == 1) {
count1++;
}
if (bestPlayer[i] == 0 && bestPlayer[1] == 1 && bestPlayer[i] == 2){
count++;
// иначе если ячейка массива равна 2, то проходим до конца всю строку счетчиком 2
} else if(bestPlayer[i] == 2){
count2++;
}
}
if (count1 == n) {
result = 1;
return result;
}if (count == n){
result = 0;
return result;
}else if(count2 == n) {
result = 2;
return result;
}else{
result = -1;
}
return result;
}
public static void main(String[] args) {
int[][] grid = {{1, 0, 2},{1, 2, 0}, {0, 1, 2}};
determineWinner(grid);
System.out.println(determineWinner(grid));
}
}
Вот мой код с методом на проверку ничьей Если кто-то может разобраться, то помогите пожалуйста, получается при вызове этого метода в функции, у меня блокируется дальнейшая проверка комбинаций выигрыша, например застревает код на главной диагонали и дальше не проверяет
public class TicTacToe_103 {
public static int determineWinner(int[][] grid) {
int isDraw = 0;
int result = -1;
int n = grid.length;
int maxId = n - 1; // последний элемент массива( строки)
// ----- проверяем на победителя комбинацию главная диагональ
int[] arrayD = new int[n];
for (int i = 0; i < n; i++) {
arrayD[i] = grid[i][i];
}
result = winner(arrayD);
if (result == 1 || result == 2) {
return result;
}
// ------- проверяем на победителя комбинацию побочная диагональ
int[] arrayDr = new int[n];
for (int i = maxId; i >= 0; i--){
arrayDr[i] = grid[i][maxId - i];
}
result = winner(arrayDr);
if (result == 1 || result == 2){
return result;
}
//-------------- проверяем на победителя комбинации строк
int [] arrayRow = new int[n];
for (int i = 0, j = 0; i < n && j < n; j++){
arrayRow[j] = grid[i][j];
if (j == maxId){
j = -1;
result = winner(arrayRow);
if (result == 1 || result == 2) {
return result;
}
i++;
}
}
// ---------------проверяем на победителя комбинации стобцов
int [] arrayCol = new int[n];
for (int i = 0, j = 0; i < n && j < n; i++) {
arrayCol[i] = grid[i][j];
if (i == maxId) {
i = -1;
result = winner(arrayCol);
if (result == 1 || result == 2) {
return result;
}
j++;
}
}
// проверка на ничью строк
for (int i = 0, j = 0; i < n && j < n; j++){
arrayRow[j] = grid[i][j];
if (result == draw(arrayD)) {
result = -1;
return result;
}
i++;
}
// проверка на ничью столбцов
for (int i = 0, j = 0; i < n && j < n; i++) {
arrayCol[i] = grid[i][j];
if (result == draw(arrayD)) {
result = -1;
return result;
}
j++;
}
///// проверка на ничью второстепенной диагонали
for (int i = maxId; i >= 0; i--){
arrayDr[i] = grid[i][maxId - i];
}
if (result == draw(arrayD)) {
result = -1;
return result;
}
/// проверка на ничью главной диагонали
for (int i = 0; i < n; i++) {
arrayD[i] = grid[i][i];
}
if (result == draw(arrayD)) {
result = -1;
return result;
}
if (result != draw(arrayRow) && result != winner(arrayRow)
&& result != draw(arrayCol) && result != winner(arrayCol)
&& result != draw(arrayD) && result != winner(arrayD)
&& result != draw(arrayDr) && result != winner(arrayDr)){
result = 0;
}
return result;
}
// дополнительный метод на выигрыш
public static int winner(int[] bestPlayer) {
int result = 0;
int n = bestPlayer.length;
int count1 = 0;
int count2 = 0;
// в цикле проходимся по ячейкам массива
for (int i = 0; i < n; i++) {
// если первая ячейка равна 1, то проверяем всю строку с помощью счетчика1
if (bestPlayer[i] == 1) {
count1++;
}
// иначе если ячейка массива равна 2, то проходим до конца всю строку счетчиком 2
else if(bestPlayer[i] == 2){
count2++;
}
}
if (count1 == n) {
result = 1;
return result;
}if(count2 == n) {
result = 2;
return result;
}else{
result = 0;
}
return result;
}
// метод для определения ничьей
public static int draw(int [] nullWinner){
int isDraw = 0;
int count1 = 0;
int count2 = 0;
int n = nullWinner.length;
for (int i = 0; i < n; i++){
if (nullWinner[i] != 2){
count2++;
}
}if (count1 != 0 && count2 != 0){
isDraw = -1;
}else{
isDraw = 0;
}
return isDraw;
}
public static void main(String[] args) {
int[][] grid = {{1, 2, 2},{2, 0, 0}, {2, 0, 1}};
determineWinner(grid);
System.out.println(determineWinner(grid));
}
}
Здесь весь код, чтобы можно было разобраться знающему человеку где ошибка
Ответы (2 шт):
Изменил метод winner следующим образом:
public static int winner(int[] bestPlayer) {
if (bestPlayer.equals(1) && bestPlayer.equals(2))
{
return -1;
}
else if (bestPlayer.equals(1) && !bestPlayer.equals(2))
{
return 1;
}
else if (bestPlayer.equals(2) && !bestPlayer.equals(1))
{
return 2;
}
else
{
return 0;
}
}
Но на всякий случай советую перепроверить вычисления.
похоже проблема начинается с этого места:
// проверка на ничью строк
for (int i = 0, j = 0; i < n && j < n; j++){
arrayRow[j] = grid[i][j];
if (result == draw(arrayD)) {
result = -1;
return result;
}
i++;
}
- Вы в цикле собираете строку и тут же в каждой итерации проверяете draw(arrayD). очень похоже на копи/пэйст-ошибку. к тому же цикл проходит не по строкам, а по главной диагонали, т.к. i++ и j++ выполняются рядом.
- Обратите внимание на то, что в отличии от условия победителя, где достаточно было найти одну комбинацию, для ничьей необходимо проверит все комбинации прежде чем возвращать результат. т.о. return тут тоже лишний.
- не понятна логика сравнения result == draw(...) : если победитель не найден, то result=0, а draw возвращает -1 если ничья иначе 0, тогда почему такое сравнение?
- обратите внимание на то, что в draw() переменная count1 всегда 0, возможно Вы забыли инкрементировать ее аналогично count2.
спойлер
// проверка на ничью
int drawResult = draw(arrayD) * draw(arrayDr);
// если drawResult==0, то партия не определена
for(int i = 0; drawResult != 0 && i < n; i++) {
drawResult *= draw(row(grid, i));
drawResult *= draw(col(grid, i));
}
if (drawResult != 0)
return -1;
return 0;
методы row и col возвращают соответственно строку и столбец массива.