Прошу критики кода, крестики-нолики - C (СИ)
Формулировка задачи:
Всем привет.
Только начал изучать язык программирования Си, да и программирование в общем.
Есть задача - написать игру крестики-нолики.
Предлагаю свой вариант, прошу критики.
Пока что без варианта игры против компьютера. Хотелось бы узнать как лучше всего написать для него хоть немножечко интеллекта.
Что не правильно я использовал, что лучше не использовать/использовать и так далее. Заранее спасибо.
#include <stdio.h> #include <locale.h> #include <stdlib.h> void menu(); void instruction(); bool winner(); void inputBoard(); void resetArray(); void computer(); void player(); int menuNum = 0; //выбор пункта в меню char board[9] = {49, 50, 51, 52, 53, 54, 55, 56, 57}; // заполнение массива от 1 до 9. int count = 0; // счетчик количества цикла, (ничья) char nameOne[15], nameTwo[15]; // массив символов для имен игроков int ex; // выйти из программы или продолжить main() { setlocale(LC_ALL, "Russian"); do{ system("cls"); menu(); if (menuNum == 1) computer(); else if (menuNum == 2) player(); else if (menuNum == 3) {instruction(); goto label;} else exit(1); inputBoard(); count = 0; printf("Хотите сыграть еще раз? (1 - да. 0 - нет) - "); scanf("%d", &ex); }while(ex == 1); label: printf("Спасибо, что воспользовались программой. Счастливого дня.\n"); } void menu() { puts("\t\tДобро пожаловать в игру крестики-нолики."); puts("Выберите пункт из меню:\n"); puts("1 - играть с компьютером"); puts("2 - играть с другим игроком"); puts("3 - показать инструкцию"); puts("0 - выход из программы"); printf("Ваш выбор - "); scanf("%d", &menuNum); } void instruction() { puts("1. Игрок A ходит крестиками 'X' игрок B ходит '0' по очереди."); puts("1. Побеждает тот, у кого выставленные им символы трижды пересекаются"); puts("1. либо по горизонтали, либо по вертикали, либо по диагонали."); } bool winner() { if(((board[0] == 'X') && (board[1] == 'X') && (board[2] == 'X' )) || ((board[3] == 'X') && (board[4] == 'X') && (board[5] == 'X' )) || ((board[6] == 'X') && (board[7] == 'X') && (board[8] == 'X' )) || ((board[0] == 'X') && (board[3] == 'X') && (board[6] == 'X' )) || ((board[1] == 'X') && (board[4] == 'X') && (board[7] == 'X' )) || ((board[2] == 'X') && (board[5] == 'X') && (board[8] == 'X' )) || ((board[0] == 'X') && (board[4] == 'X') && (board[8] == 'X' )) || ((board[2] == 'X') && (board[4] == 'X') && (board[6] == 'X' ))) return true; if(((board[0] == '0') && (board[1] == '0') && (board[2] == '0' )) || ((board[3] == '0') && (board[4] == '0') && (board[5] == '0' )) || ((board[6] == '0') && (board[7] == '0') && (board[8] == '0' )) || ((board[0] == '0') && (board[3] == '0') && (board[6] == '0' )) || ((board[1] == '0') && (board[4] == '0') && (board[7] == '0' )) || ((board[2] == '0') && (board[5] == '0') && (board[8] == '0' )) || ((board[0] == '0') && (board[4] == '0') && (board[8] == '0' )) || ((board[2] == '0') && (board[4] == '0') && (board[6] == '0' ))) return false; } void inputBoard() // заполнение и изменения доски { system("cls"); printf("\t\t\tИграют %s и %s\n", nameOne, nameTwo); for(int i = 0; i < 9; i++) { printf(" %c |", board[i]); if ((i == 2) || (i == 5)) { printf("\n"); printf("----+----+-----\n"); } } if (count == 9) printf("\n\nНичья. Попробуйте еще раз.\n"); if(winner() == true) printf("\n\n%s играл за крестики и победил, поздравляем!\n", nameOne); else if(winner() == false) printf("\n\n%s играл за нолики и победил, поздравляем!\n", nameTwo); } void resetArray() //заполнить массив к стандартным значениям. { if (ex == 1) { int j = 0; for(int i = 49; i <= 57; i++) { board[j] = i; j++; } } } void computer(){ // игра против компьютера printf("Computer"); } void player() // игра против игрока { int clickBoard = 0; count = 0; resetArray(); printf("Введите имя первого игрока - "); scanf("%s", &nameOne); printf("Введите имя второго игрока - "); scanf("%s", &nameTwo); for(int i = 1; i <= 9; i++) { inputBoard(); // Если i не четное. (i & 1) ? printf("\n\nСейчас ходит %s - ", nameOne) : printf("\n\nСейчас ходит %s - ", nameTwo); repeat: scanf("%d", &clickBoard); if(i & 1) // если i не парное, то ... { if ((board[clickBoard-1] == 'X') || (board[clickBoard-1] == '0')) { puts("Вы указали на занятую клетку, попробуйте ещё раз."); goto repeat; } board[clickBoard-1] = 'X'; } else if(!(i & 1)) // если i парное, то... { if ((board[clickBoard-1] == 'X') || (board[clickBoard-1] == '0')) { puts("Вы указали на занятую клетку, попробуйте ещё раз."); goto repeat; } board[clickBoard-1] = '0'; } if(winner() == true) // если условие с крестиками истинно, то закончить цикл. break; else if(winner() == false) break; count++; } }
Решение задачи: «Прошу критики кода, крестики-нолики»
textual
Листинг программы
Проблемы с анализом неправильного ввода в scanf хорошо известны... В таких случаях лучше все таки читать строку, а не число.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д