Крестики-нолики на C++
Не работает как надо, не выводит ничего на доску и игра заканчивается после первого хода. Пробовала всё из play перекинуть в main, но тогда выводятся только нолики. Уже даже не знаю как мне быть
#include <iostream> #include <Windows.h> using namespace std; char board[9] = {'-','-', '-', '-', '-', '-', '-', '-', '-'};//массив поля bool has_won(char player)//условие выигрыша { int wins[][3] = { {0,1,2},{3,4,5},{6,7,8},{0,3,6},{1,4,7},{2,5,8},{0,4,8},{2,4,6} }; for (int i = 0; i < 8; i++) { int count = 0; for (int j = 0; j < 2; j++) { if (board[wins[i][j]] == player); count++; if (count==3) return true; else return false; } } } void print_board()//вывод поля { cout << "Игровое поле\n"; cout << "-" << board[6] << "-|-" << board[7] << "-|-" << board[8] << "-\n"; cout << "-" << board[3] << "-|-" << board[4] << "-|-" << board[5] << "-\n"; cout << "-" << board[0] << "-|-" << board[1] << "-|-" << board[2] << "-\n"; cout << "Ваш ход:\n"; } int get_move() { system("cls"); setlocale(0, "ru"); //подсказка cout << "Управление\n"; cout << "-7-|-8-|-9-\n"; cout << "-4-|-5-|-6-\n"; cout << "-1-|-2-|-3-\n"; cout << endl; print_board(); int move; cin >> move; while (move > 9 || move < 1 || board[move - 1] != '-') //проверка введённого числа { cout << "Ведите правильное число (1-9)\n"; cin >> move; } return move; } char play()//игра и проверка комбинаций { int turn = 0; while (!has_won('X') && !has_won('O')) { get_move(); int move = get_move(); for (int i = 0; i < 10; i++) { if (turn % 2 == 0) { board[move - 1] = 'X'; if (has_won('X')) { cout << "Выиграл игрок 'X'!\n"; return 'X'; } } else { board[move - 1] = 'O'; if (has_won('O')) { cout << "Выиграл игрок 'O'!\n"; return 'O'; } } turn++; if (turn == 9) { cout << "Ничья :(\n"; return 'D'; } } } } void main() { system("Title TicTacToe"); system("color 2"); play(); }
Ответ
turn++ делается в цикле который выполняется 10 раз после ввода, поэтому номер хода достигает числа 9 и т.к. проверка на win возвращает false выходит ничья
там где проверка на вин, всегда будет возвращать false потому что после первой же итерации (j=0) будет проверка что count==3, а он никак не может быть равен 3 на первой итерации. return false должен быть после обоих циклов for
#include <iostream> using namespace std; char board[9] = {'-','-', '-', '-', '-', '-', '-', '-', '-'};//массив поля bool has_won(char player)//условие выигрыша { int wins[][3] = { {0,1,2},{3,4,5},{6,7,8},{0,3,6},{1,4,7},{2,5,8},{0,4,8},{2,4,6} }; for (int i = 0; i < 8; i++) { int count = 0; for (int j = 0; j <= 2; j++) { if (board[wins[i][j]] == player) count++; if (count==3) return true; } } return false; } void print_board()//вывод поля { cout << "Игровое поле\n"; cout << "-" << board[6] << "-|-" << board[7] << "-|-" << board[8] << "-\n"; cout << "-" << board[3] << "-|-" << board[4] << "-|-" << board[5] << "-\n"; cout << "-" << board[0] << "-|-" << board[1] << "-|-" << board[2] << "-\n"; cout << "Ваш ход:\n"; } int get_move() { system("cls"); setlocale(0, "ru"); //подсказка cout << "Управление\n"; cout << "-7-|-8-|-9-\n"; cout << "-4-|-5-|-6-\n"; cout << "-1-|-2-|-3-\n"; cout << endl; print_board(); int move; cin >> move; while (move > 9 || move < 1 || board[move - 1] != '-') //проверка введённого числа { cout << "Ведите правильное число (1-9)\n"; cin >> move; } return move; } char play()//игра и проверка комбинаций { int turn = 0; while (!has_won('X') && !has_won('O') && turn < 9) { int move = get_move(); if (turn % 2 == 0) { board[move - 1] = 'X'; if (has_won('X')) { cout << "Выиграл игрок 'X'!\n"; return 'X'; } } else { board[move - 1] = 'O'; if (has_won('O')) { cout << "Выиграл игрок 'O'!\n"; return 'O'; } } turn++; } cout << "Ничья :(\n"; return 'D'; } int _tmain(int argc, _TCHAR* argv[]) { system("Title TicTacToe"); system("color 2"); play(); int a; cin >> a; return 0; }
вроде работает как надо
Смотрите также:
Комментарии
- 1 (Текущая страница)
- 2
первое что бросается в глаза: get_move(); вызывается один раз до цикла, без обработки результата, это ок?
if (has_won('O')) cout << "Выиграл игрок 'O'!\n"; return 'O';
Это точно должно быть так? тут return вне ифа получается т.к. скобок нет
Мышкоблудка, аналогичных мест в коде было больше одного... //да, уже вижу, что все поправлены
upd: нашел еще одну проблему - лишний цикл, из-за которого один ход считается за 10
можно сделать дебаг
лучше писать в лог и кинуть его сюда
и у тебя get_move(); вызывается дважды
вообще подобные проблемы изи решаются без лога. просто дебаг и листочек с ручкой. поэтому мне и не охота жестко учить джасс потому что там нет адекватного дебага в отличие от нормальных яп. Считаю что логи необходимы в действительно замысловатых случаях например в рекурсивных функциях с множеством действий и с действительно большим вызовом рекурсии.
turn++ делается в цикле который выполняется 10 раз после ввода, поэтому номер хода достигает числа 9 и т.к. проверка на win возвращает false выходит ничья
там где проверка на вин, всегда будет возвращать false потому что после первой же итерации (j=0) будет проверка что count==3, а он никак не может быть равен 3 на первой итерации. return false должен быть после обоих циклов for
#include <iostream> using namespace std; char board[9] = {'-','-', '-', '-', '-', '-', '-', '-', '-'};//массив поля bool has_won(char player)//условие выигрыша { int wins[][3] = { {0,1,2},{3,4,5},{6,7,8},{0,3,6},{1,4,7},{2,5,8},{0,4,8},{2,4,6} }; for (int i = 0; i < 8; i++) { int count = 0; for (int j = 0; j <= 2; j++) { if (board[wins[i][j]] == player) count++; if (count==3) return true; } } return false; } void print_board()//вывод поля { cout << "Игровое поле\n"; cout << "-" << board[6] << "-|-" << board[7] << "-|-" << board[8] << "-\n"; cout << "-" << board[3] << "-|-" << board[4] << "-|-" << board[5] << "-\n"; cout << "-" << board[0] << "-|-" << board[1] << "-|-" << board[2] << "-\n"; cout << "Ваш ход:\n"; } int get_move() { system("cls"); setlocale(0, "ru"); //подсказка cout << "Управление\n"; cout << "-7-|-8-|-9-\n"; cout << "-4-|-5-|-6-\n"; cout << "-1-|-2-|-3-\n"; cout << endl; print_board(); int move; cin >> move; while (move > 9 || move < 1 || board[move - 1] != '-') //проверка введённого числа { cout << "Ведите правильное число (1-9)\n"; cin >> move; } return move; } char play()//игра и проверка комбинаций { int turn = 0; while (!has_won('X') && !has_won('O') && turn < 9) { int move = get_move(); if (turn % 2 == 0) { board[move - 1] = 'X'; if (has_won('X')) { cout << "Выиграл игрок 'X'!\n"; return 'X'; } } else { board[move - 1] = 'O'; if (has_won('O')) { cout << "Выиграл игрок 'O'!\n"; return 'O'; } } turn++; } cout << "Ничья :(\n"; return 'D'; } int _tmain(int argc, _TCHAR* argv[]) { system("Title TicTacToe"); system("color 2"); play(); int a; cin >> a; return 0; }
вроде работает как надо
biridius, раздел QA это не раздел "сделайте все за меня", а ты взял и все сделал сам вместо автора вопроса, не надо приучать людей к плохим привычкам! Достаточно было бы указать на проблемы, причем желательно по одной-две за раз, чтобы не перегружать информацией и дать автору шанс самостоятельно найти следующую проблему после решения предыдущей, а готовый код выложить только если это что-то совсем срочное и нет другого выбора.
Meddin, разжигать огонь можно изи с помощью трения палки об палку
вот только всё же лучше использовать зажигалку или спички
вариант листочек с ручкой в основном используют студенты в лабах когда надо сдать и забыть ибо лень учиться как делать по нормальному
или если в языке нету нормальных средств отлова ошибок для записи их в лог (например jass)
у большинства прогеров по умолчанию в дебаг версии включена запись лога
да и в релизной тоже
По-моему он все же имел в виду работу с дебаггером, а ручку с листочком только как вспомогательное.
Doc, именно так и было. Мне лично удобнее сразу по ходу дебага записывать результаты и смотреть, проходит ли работа по задуманному мною сценарию. То есть по ходу работы программы я еще и сам просчитываю ее на листке, чтобы убедиться, что все в коде происходит верно. Если же нет, я помечаю для себя проблемное место, обдумываю как пофиксить, фикшу, снова дебажу и так до тех пор, пока моя программа не будет работать верно.
- 1 (Текущая страница)
- 2
Возможность добавлять комментарии была ограничена
CollectableItemData.cs
[CreateMenuItem(fileName = "newItem", menuName = "Data/Items/Collectable", order = 51]