SaveText.Ru

аа
  1. /*
  2. "Крестики - Нолики"
  3. автор: Матвей Фордулясов
  4.  
  5.  
  6. ПАЧНОУТЫ:
  7. 20.11.2018 - старт проекта и продумывание плана проекта
  8.  
  9. 21.11.2018 - интерфейс и режим игры против человека
  10.  
  11. 24.11.2018 - добавленна возможность играть партии подряд без перезапуска приложения, добавлен легкий и средний бот,
  12.                         можно выбрать кто ходит первым.
  13.  
  14. 25.11.2018 - добавлен сложный бот. начато продумывание реализации игры по локальной сети, дебаг и допиливание визуализации
  15.                         дописаны недостающие "n" и system("pause")
  16.                         так же мне помогли исправить ошибку которая происходила в случае ввода символов вместо интежер
  17.  
  18. 27.11.2018 - допил сложного бота (функция mnogohodovochka которая проверяет один из сценариев и не дает игроку выграть по нему)
  19. */
  20. /*
  21. ------ШПОРГААААЛКИ, ШПОРГААААЛОЧКИ!--------
  22.  
  23. рандом
  24. {
  25. #include <cstdlib> (библиотека для rand() и srand() )
  26. srand(time(nullptr)); (запихать в начало функции мейн, для нормального рандома)
  27. x=(rand() % *длинна промежутка* + *сдвиг относительно нуля*);
  28. }
  29.  
  30. консолечка
  31. {
  32. system("cls"); (отчистка консоли)
  33. system("pause"); (нажмите кнопку чтоб продолжить)
  34. }
  35.  
  36. описание логики ботов:
  37. бот всегда нолик
  38. игрок всегда крестик
  39. для атаки и защиты считывается состояние поля, и формируются строки 3 по горизонтали и вертикали, 2 накрест.
  40. крестик равен 10, нолик равен единице, если строка равняется 2- производится атака, если строка равняется 20 - производится защита
  41. в остальных случаях делается рандомный ход (средний бот) либо запускается алгоритм выйгршной стратегии - занять центр и углы
  42.  
  43. после того как я доделал код, стало ясно что можно было сделать несколько функций (атаки, защиты, случайного хода, очереди игрока)
  44. в таком случае код был бы в два раза короче.
  45. */
  46.  
  47. #include <iostream>
  48. #include <cstdlib> //для random
  49. #include <ctime> //опять-же для random (используем системное время для генерации действительно случайных чисел)
  50. using namespace std;
  51. short int fieldUp[9]; //информация о состоянии строк для ботов бот=1, человек= 10(да, это костыль, мне лень делать компактнее)
  52. char field[9]; //информация о игровом поле ('_'- пусто; 'x'- крестик; 'o'- нолик) эта переменная обязанна быть глобальной
  53. bool turn; //чья очередь ходить (в botGM;  bot - 1, человек - 0) а остальные переменные мне было лень прописывать каждый раз в функциях GM )))0)0)
  54. short int gameStatus; //статус игры (победа одной из сторон-0/1, ничья-2, игра в процессе-3)
  55. short int choice; //клетка которую выбрал игрок/бот для хода
  56. bool botAD; //произведенна ли атака/защита
  57.  
  58. short safe_input() {
  59.         short val = 0;
  60.         while (!(cin >> val)) {
  61.                 cin.clear();
  62.                 cin.ignore(numeric_limits<streamsize>::max(), 'n');
  63.                 cout << "Wrong input, only integers are expected!" << endl;
  64.         }
  65.         cin.clear();
  66.         cin.ignore(numeric_limits<streamsize>::max(), 'n');
  67.         return val;
  68.         //эту функцию я попросил написать отчима, она нужна для того чтоб в случае ввода не int программа не ошибалась.
  69.         // если вместо функции писать просто cin >> i; то в случае не пожохдящего ввода программа не правильно работала,
  70.         // а эта функция в случаее неверного ввода говорит об этом пользователю и запрашивает ввод вновь, пока он не введет int.
  71.         // это единственные семь строчек написанные не мной во всем коде.
  72. }
  73.  
  74. void fieldUpdate()
  75. //визуализация поля
  76. {
  77.         cout << field[6] << "|" << field[7] << "|" << field[8] << "      6|7|8" << "n"
  78.                 << field[3] << "|" << field[4] << "|" << field[5] << "      3|4|5" << "n"
  79.                 << field[0] << "|" << field[1] << "|" << field[2] << "      0|1|2" << "n" << endl;
  80. }
  81.  
  82. short int winner()
  83. //проверка условий победы (0- нолики, 1-крестики, 2-ничья, 3-игра еще не окончена) ужаснейший костыль, можно было-бы уместить это все в botMain() но мне лень                             
  84. {
  85.         if (((field[0] == 'x') && (field[1] == 'x') && (field[2] == 'x')) || ((field[3] == 'x') && (field[4] == 'x') && (field[5] == 'x'))
  86.                 || ((field[6] == 'x') && (field[7] == 'x') && (field[8] == 'x')) || ((field[0] == 'x') && (field[3] == 'x') && (field[6] == 'x'))
  87.                 || ((field[1] == 'x') && (field[4] == 'x') && (field[7] == 'x')) || ((field[2] == 'x') && (field[5] == 'x') && (field[8] == 'x'))
  88.                 || ((field[6] == 'x') && (field[4] == 'x') && (field[2] == 'x')) || ((field[8] == 'x') && (field[4] == 'x') && (field[0] == 'x')))
  89.         {
  90.                 return 1;//победа крестиков
  91.         }
  92.  
  93.         if (((field[0] == 'o') && (field[1] == 'o') && (field[2] == 'o')) || ((field[3] == 'o') && (field[4] == 'o') && (field[5] == 'o'))
  94.                 || ((field[6] == 'o') && (field[7] == 'o') && (field[8] == 'o')) || ((field[0] == 'o') && (field[3] == 'o') && (field[6] == 'o'))
  95.                 || ((field[1] == 'o') && (field[4] == 'o') && (field[7] == 'o')) || ((field[2] == 'o') && (field[5] == 'o') && (field[8] == 'o'))
  96.                 || ((field[6] == 'o') && (field[4] == 'o') && (field[2] == 'o')) || ((field[8] == 'o') && (field[4] == 'o') && (field[0] == 'o')))
  97.         {
  98.                 return 0;//победа ноликов
  99.         }
  100.  
  101.         short int checkup = 0;
  102.         for (short int i = 0; i < 9; i++)
  103.                 if (field[i] != '_')
  104.                 {
  105.                         checkup++;
  106.                 }
  107.         if (checkup == 9)
  108.         {
  109.                 return 2; //ничья
  110.         }
  111.         else
  112.         {
  113.                 return 3;//не все поля заполнены и пока никто не выйграл
  114.         }
  115. }
  116.  
  117. void fieldCheckUp()
  118. //"визуализация" поля для botMain() (да, это костыль... и что?  :D  )
  119. {
  120.         for (short int i = 0; i < 9; i++)
  121.         {
  122.                 switch (field[i])
  123.                 {
  124.                 case 'o': fieldUp[i] = 1;
  125.                         break;
  126.                 case 'x': fieldUp[i] = 10;
  127.                         break;
  128.                 case '_': fieldUp[i] = 0;
  129.                 }
  130.         }
  131.  
  132. }
  133.  
  134. void botAction(short int a, short int b, short int c)
  135. //вспомогательная функция вызывающаяся главной функцией бота для оказания защиты или атаки
  136. //в качетсве параметров вводится три клетки(две из которых заняты), функция находит свободную и заполняет ее
  137. {
  138.         if (field[a] == '_')
  139.         {
  140.                 field[a] = 'o';
  141.         }
  142.         if (field[b] == '_')
  143.         {
  144.                 field[b] = 'o';
  145.         }
  146.         if (field[c] == '_')
  147.         {
  148.                 field[c] = 'o';
  149.         }
  150. }
  151.  
  152. bool botMain(short int action)
  153. //производит защиту(2), атаку(20), игру по стратегии (100)
  154. {
  155.         if (action == 100) //действия умного бота
  156.         {
  157.                 if (field[4] == '_')
  158.                 {
  159.                         field[4] = 'o';
  160.                         return 1;
  161.                 }
  162.                 else
  163.                 {
  164.                         if (field[0] == '_')
  165.                         {
  166.                                 field[0] = 'o';
  167.                                 return 1;
  168.                         }
  169.                         if (field[6] == '_')
  170.                         {
  171.                                 field[6] = 'o';
  172.                                 return 1;
  173.                         }
  174.                         if (field[2] == '_')
  175.                         {
  176.                                 field[2] = 'o';
  177.                                 return 1;
  178.                         }
  179.                         if (field[8] == '_')
  180.                         {
  181.                                 field[8] = 'o';
  182.                                 return 1;
  183.                         }
  184.                 }
  185.         }
  186.  
  187.         if ((fieldUp[0] + fieldUp[1] + fieldUp[2]) == action)
  188.         {
  189.                 botAction(0, 1, 2);
  190.                 return 1;
  191.         }
  192.         if ((fieldUp[3] + fieldUp[4] + fieldUp[5]) == action)
  193.         {
  194.                 botAction(3, 4, 5);
  195.                 return 1;
  196.         }
  197.         if ((fieldUp[6] + fieldUp[7] + fieldUp[8]) == action)
  198.         {
  199.                 botAction(6, 7, 8);
  200.                 return 1;
  201.         }
  202.         if ((fieldUp[6] + fieldUp[3] + fieldUp[0]) == action)
  203.         {
  204.                 botAction(6, 3, 0);
  205.                 return 1;
  206.         }
  207.         if ((fieldUp[7] + fieldUp[4] + fieldUp[1]) == action)
  208.         {
  209.                 botAction(7, 4, 1);
  210.                 return 1;
  211.         }
  212.         if ((fieldUp[8] + fieldUp[5] + fieldUp[2]) == action)
  213.         {
  214.                 botAction(8, 5, 2);
  215.                 return 1;
  216.         }
  217.         if ((fieldUp[0] + fieldUp[1] + fieldUp[2]) == action)
  218.         {
  219.                 botAction(0, 1, 2);
  220.                 return 1;
  221.         }
  222.         if ((fieldUp[2] + fieldUp[4] + fieldUp[6]) == action)
  223.         {
  224.                 botAction(2, 4, 6);
  225.                 return 1;
  226.         }
  227.         return 0;
  228. }
  229.  
  230. void versusGM()
  231. //игра против человека на одном экране
  232. {
  233.         fieldUpdate();
  234.         gameStatus = 3;
  235.         while (gameStatus == 3)
  236.         {
  237.                 cout << "select the position you want to make turn" << "n" << endl;
  238.                 choice = safe_input();
  239.                 system("cls");//отчистка консоли
  240.                 if (turn)
  241.                 {
  242.                         if (field[choice] == '_') //проверяет свободна ли позиция которую выбрал игрок
  243.                         {
  244.                                 field[choice] = 'x';
  245.                         }
  246.                         else
  247.                         {
  248.                                 cout << "n" << "THIS POSITION IS ALREADY TAKEN!!!" << "n" << endl;
  249.                                 turn = !turn;
  250.                         }
  251.                 }
  252.                 else
  253.                 {
  254.                         if (field[choice] == '_') //проверяет свободна ли позиция которую выбрал игрок
  255.                         {
  256.                                 field[choice] = 'o';
  257.                         }
  258.                         else
  259.                         {
  260.                                 cout << "n" << "THIS POSITION IS ALREADY TAKEN!!!" << "n" << endl;
  261.                                 turn = !turn;
  262.                         }
  263.                 }
  264.                 turn = !turn;
  265.                 fieldUpdate();
  266.                 gameStatus = winner();
  267.         }
  268.         switch (gameStatus)
  269.         {
  270.         case 0: cout << "n" << "O - WIN!!!" << "n";
  271.                 break;
  272.         case 1: cout << "n" << "X - WIN!!!" << "n";
  273.                 break;
  274.         case 2: cout << "n" << "NOBODY WINS  :c   " << "n";
  275.                 break;
  276.         }
  277. }
  278.  
  279. bool mnogohodovochka()
  280. {
  281.         if ((fieldUp[4] == 1) && ((fieldUp[6] + fieldUp[2] == 20) || (fieldUp[8] + fieldUp[0] == 20))  && (fieldUp[1] + fieldUp[3] + fieldUp[5] + fieldUp[7] == 0))
  282.         {
  283.                 field[1] = 'o';
  284.                 return 1;
  285.         }
  286.         else
  287.         {
  288.                 return 0;
  289.         }
  290. }
  291.  
  292. void botGM3()
  293. //игра против сложного бота
  294. {
  295.         gameStatus = 3;
  296.         while (gameStatus == 3)
  297.         {
  298.                 if (turn == 1)
  299.                 {
  300.                         botAD = 0;
  301.                         fieldCheckUp();
  302.                         botAD = mnogohodovochka();
  303.                         if (!botAD)
  304.                         {
  305.                                 botAD = botMain(2);
  306.                         }
  307.                         if (!botAD)
  308.                         {
  309.                                 botAD = botMain(20);
  310.                         }
  311.                         if (!botAD)
  312.                         {
  313.                                 botAD = botMain(100);
  314.                         }
  315.                         if (botAD)
  316.                         {
  317.                                 turn = !turn;
  318.                         }
  319.                         if (!botAD)
  320.                         {
  321.                                 system("cls"); //отчистка консоли
  322.                                 while (turn)
  323.                                 {
  324.                                         choice = (rand() % 8);
  325.                                         if (field[choice] == '_')
  326.                                         {
  327.                                                 field[choice] = 'o';
  328.                                                 turn = !turn;
  329.                                         }
  330.                                 }
  331.                         }
  332.                         gameStatus = winner();
  333.                 }
  334.                 else
  335.                 {
  336.                         fieldUpdate();
  337.                         cout << "select the position you want to make turn" << "n" << endl;
  338.                         choice = safe_input();
  339.                         system("cls"); //отчистка консоли
  340.                         if (field[choice] == '_') //проверяет свободна ли позиция которую выбрал игрок
  341.                         {
  342.                                 field[choice] = 'x';
  343.                                 gameStatus = winner();
  344.                         }
  345.                         else
  346.                         {
  347.                                 cout << "n" << "THIS POSITION IS ALREADY TAKEN!!!" << "n" << endl;
  348.                                 turn = !turn;
  349.                         }
  350.                         turn = !turn;
  351.                 }
  352.         }
  353.         system("cls");
  354.         fieldUpdate();
  355.         switch (gameStatus)
  356.         {
  357.         case 0: cout << "n" << "HARD BOT - WIN!!!" << "n";
  358.                 break;
  359.         case 1: cout << "n" << "GENIUS!!!!!!!!!!!!!!!!!!!!" << "n"; //этого не может быть, но я добавил на всякий случай чтоб уидеть баг если он будет.
  360.                 break;
  361.         case 2: cout << "n" << "NOBODY WINS  :c   " << "n";
  362.                 break;
  363.         }
  364. }
  365.  
  366. void botGM2()
  367. //игра против среднего бота
  368. {
  369.         gameStatus = 3;
  370.         while (gameStatus == 3)
  371.         {
  372.                 if (turn == 1)
  373.                 {
  374.                         botAD = 0;
  375.                         fieldCheckUp();
  376.                         botAD = botMain(2);
  377.                         if (botAD)
  378.                         {
  379.                                 turn = !turn;
  380.                         }
  381.                         if (!botAD)
  382.                         {
  383.                                 botAD = botMain(20);
  384.                         }
  385.                         if (botAD)
  386.                         {
  387.                                 turn = !turn;
  388.                         }
  389.                         if (!botAD)
  390.                         {
  391.                                 system("cls"); //отчистка консоли
  392.                                 while (turn)
  393.                                 {
  394.                                         choice = (rand() % 8);
  395.                                         if (field[choice] == '_')
  396.                                         {
  397.                                                 field[choice] = 'o';
  398.                                                 turn = !turn;
  399.                                         }
  400.                                 }
  401.                         }
  402.                         gameStatus = winner();
  403.                 }
  404.                 else
  405.                 {
  406.                         fieldUpdate();
  407.                         cout << "select the position you want to make turn" << "n" << endl;
  408.                         choice = safe_input();
  409.                         system("cls"); //отчистка консоли
  410.                         if (field[choice] == '_') //проверяет свободна ли позиция которую выбрал игрок
  411.                         {
  412.                                 field[choice] = 'x';
  413.                                 gameStatus = winner();
  414.                         }
  415.                         else
  416.                         {
  417.                                 cout << "n" << "THIS POSITION IS ALREADY TAKEN!!!" << "n" << endl;
  418.                                 turn = !turn;
  419.                         }
  420.                         turn = !turn;
  421.                 }
  422.         }
  423.         system("cls");
  424.         fieldUpdate();
  425.         switch (gameStatus)
  426.         {
  427.         case 0: cout << "n" << "MEDIUM BOT - WIN!!!" << "n";
  428.                 break;
  429.         case 1: cout << "n" << "YOU WIN!!!" << "n";
  430.                 break;
  431.         case 2: cout << "n" << "NOBODY WINS  :c   " << "n";
  432.                 break;
  433.         }
  434. }
  435.  
  436. void botGM1()
  437. //игра против легкого бота
  438. {
  439.         gameStatus = 3;
  440.         while (gameStatus == 3)
  441.         {
  442.                 if (turn == 1)
  443.                 {
  444.                         choice = (rand() % 8);
  445.                         system("cls"); //отчистка консоли
  446.                         if (field[choice] == '_') //проверяет свободна ли позиция которую выбрал бот
  447.                         {
  448.                                 field[choice] = 'o';
  449.                                 gameStatus = winner();
  450.                         }
  451.                         else
  452.                         {
  453.                                 turn = !turn;
  454.                         }
  455.                         turn = !turn;
  456.                 }
  457.                 else
  458.                 {
  459.                         fieldUpdate();
  460.                         cout << "select the position you want to make turn" << "n" << endl;
  461.                         choice = safe_input();
  462.                         system("cls"); //отчистка консоли
  463.                         if (field[choice] == '_') //проверяет свободна ли позиция которую выбрал игрок
  464.                         {
  465.                                 field[choice] = 'x';
  466.                                 gameStatus = winner();
  467.                         }
  468.                         else
  469.                         {
  470.                                 cout << "n" << "THIS POSITION IS ALREADY TAKEN!!!" << "n" << endl;
  471.                                 turn = !turn;
  472.                         }
  473.                         turn = !turn;
  474.                 }
  475.         }
  476.         system("cls");
  477.         fieldUpdate();
  478.         switch (gameStatus)
  479.         {
  480.         case 0: cout << "n" << "EASY BOT - WIN!!!" << "n" << "seriously?.." << "n";
  481.                 break;
  482.         case 1: cout << "n" << "YOU WIN!!!" << "n";
  483.                 break;
  484.         case 2: cout << "n" << "NOBODY WINS  :c   " << "n";
  485.                 break;
  486.         }
  487. }
  488.  
  489. void localGM()
  490. //в планах добавить режим игры по локальной сети
  491. {
  492.         cout << " IN THE DEVELOPMENT!!!" << endl;
  493. }
  494.  
  495. int main()
  496. {
  497.         srand(time(nullptr)); //для random(), берет за онсову системное время
  498.         short int gm;
  499.         bool localMP;
  500.         bool end = 0; //условия нового матча (gameover)
  501.         while (!end)
  502.         {
  503.                 for (short int clean = 0; clean < 9; clean++) //отчистка поля
  504.                 {
  505.                         field[clean] = '_';
  506.                 }
  507.                 system("cls");//отчистка консоли
  508.                 cout << "mode?" << "n" << "versus(0)" << "n" << "easy bot(1)" << "n" << "medium bot(2)" << "n" << "hard bot(3)" << "n" << endl;
  509.                 gm = safe_input();
  510.                 system("cls");//отчистка консоли
  511.                 if (gm != 0)
  512.                 {
  513.                         cout << "who goes first?" << "n" << "bot(0)" << "n" << "random(1)" << "n" << "player(2)" << endl;
  514.                         short int randomTurn;
  515.                         randomTurn = safe_input();
  516.                         switch (randomTurn) //определение права первого хода
  517.                         {
  518.                         case 1: turn = (rand() % 2);
  519.                                 break;
  520.                         case 2: turn = 0;
  521.                                 break;
  522.                         case 0: turn = 1;
  523.                                 break;
  524.                         }
  525.                         system("cls");
  526.                         switch (gm) //вызов функции определенного режима игры
  527.                         {
  528.                         case 1: botGM1();
  529.                                 break;
  530.                         case 2: botGM2();
  531.                                 break;
  532.                         case 3: botGM3();
  533.                         }
  534.                 }
  535.                 else
  536.                 {
  537.                         cout << "split screan(0)" << "n" << "local multiplayer(1) (IN THE DEVELOPMENT!!!)" << endl;
  538.                         localMP = safe_input();
  539.                         if (localMP) //режимы мультиплеера
  540.                         {
  541.                                 system("cls");
  542.                                 localGM();                             
  543.                         }
  544.                         else
  545.                         {
  546.                                 system("cls");
  547.                                 versusGM();
  548.                         }
  549.                 }
  550.  
  551.          cout << "n" << "gameover?" << "n" << "no(0)" << "n" << "yes(1)" << endl;
  552.                 end = safe_input(); //узнаем, хочет ли пользователь закрыть программу или сыграть еще одну игру
  553.         }
  554.         return 0;
  555. }

Share with your friends:

Распечатать