Игра на си крестики нолики

10 февраля 2020 - Администратор

Полный код программы на си игры крестики нолики с компьютером 

 

В этой статье мы приведем  пример программы игры крестики нолики с компьютером на си. 

В нашей программе крестики нолики на си были введены следующие переменные и массивы. Массив a[i][j] отвечает за игровое поле. i – номер строки клетки, j – номер столбца клетки. Если значение элемента равно ноль , то на данное игровое поле пусто, если равно 1, то данное игровое поле занято ноликом, если 2 , то клетка поля занята крестиком.
Переменные igra и res отвечают за состояние игры. Если эти переменные равны нулю, то пока ещё никто не победил, если 1, то победили нолики, если 2, то крестики, если 3, то ничья. В переменную hi записывается ход игрока, например, «12» - первая цифра отвечает за строку, вторая цифра за столбец игрового поля. Переменные str и sto отвечают за номер выбранных строки и столбца. В переменную och записывается номер игрока, делающего текщий ход, 1 – нолик, 2 – крестик. Переменная v отмечает выбор, предлагаемый игроку в конце каждой игры, 1 – играем дальше, 2 – прекращаем игру, Переменная ud проверяет корректность ввода игрока при выборе игрока, то есть, если och равна 1 или 2, то ввод корректен. В процедуре hodkomp(n) присутствует переменная nv, в которой хранится номер игрока соперника. Также в этой процедуре используется  переменная  k, которая используется для фиксации выбора хода компьютера.
В программе присутствует следующие процедуры. 
Процедура nul()  Обнуление игрового поля
Процедура visual() визуализация текущего состояния поля
Процедура hod(n).  Запрашивает ход человека
Процедура hodkomp(n) Осуществляет ход компьютера Подробнее об алгоритме хода компьютера в игре крестики нолики  и его реализации на си 
Функция proverka() проверяет состояние игры
Если proverka() = 0, то никто пока не победил , если proverka() = 1, то победил нолик, если 2 – крестик, если 3, то ничья.
Подробно об алгоритме программы игры крестики нолики на си в статье 

Полный код программы игры крестики нолики на си
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>

int a[3][3];// объявляем  текущее поле  3 строки и 3 столбца. если  нет ничего то поле 0, если нолик,  то  1, если крестик то 2 

int sec()
{
time_t t;
struct tm *t_m;
t=time(NULL);
t_m=localtime(&t);
return t_m->tm_sec;
}

//------------------- обнуление поля
void nul()
{ int i,j;
//  пробегаем по всем строкам
 for(i=1; i<=3; i++)
 {
// пробегаем по всем столбцам
  for (j=1;j<=3;j++)
  {
      a[i][j]=0;
  }   
     
 }
}


//------------------ вывод  поля на экран
void visual()
{
int i,j;
printf (" 1 2 3\n");
//  пробегаем по всем строкам   
 for(i=1; i<=3; i++)
 {
  printf ("%d", i);   
// пробегаем по всем столбцам       
  for (j=1;j<=3;j++)
  {    
      if (a[i][j]==0){printf("| ");};
      if (a[i][j]==1){printf("|O");};
      if (a[i][j]==2){printf("|X");};
  } 
// переходим на следующую строку  
  printf ("|\n");    
  printf ("________\n");    
 }       
 }

//------------------------------------ Ход игрока n - номер игрока  
void hod (int n)
{
int hi;// ход игрока
int sto; //  номер столбца в ходе
int str; // номер строки в ходе
int ver; // проверка на корректность хода если нельзя такой ход то 0 , если можно то 1
ver=0;
// запрашиваем ход,  пока не будет введен корректный ход
while (ver==0)
{
// ввод хода
printf ("Ваш ход. Введите номер строки и столбца. ");   
scanf("%d", &hi);
// определяем номер столбца - это последняя цифра в ходе
sto=hi%10;
// определяем номер строки хода - это первая цифра
str=(hi-sto)/10;
// проверка корректности хода, клетка должна быть пуста и номер должен быть один из номеров таблицы 3 на 3
if (a[str][sto]==0 && (hi==11 || hi==12 || hi==13 || hi==21 || hi==22 || hi==23 || hi==31 || hi==32 || hi==33 )) (ver=1);
}
// если  ходил игрок 1  то поле хода  1
if ( n==1) {a[str][sto]=1;}
if ( n==2) {a[str][sto]=2;}
 }

//-------------------Ход компьютера
void hodkomp(int n)
{ int i, j, k;
int nv; // против кого мы играем? Если 1, то = 1, то против ноликов, если = 2, то против крестиков
k=0; // Флаговая переменная. Если 0, то компьютер ещё не сходил, если 1 - компьютер сходил и все последующие проверки в этой процедуре пропускаются.
if (n==1) {nv=2;}
if (n==2) {nv=1;}
// ищем свой выигрышный ход
// проверяем все столбцы и выбираем оптимальный ход для компьютера
for (i=1; i<=3; i++)
{
    if (a[1][i]==n && a[2][i]==n && a[3][i]==0 && k==0) {a[3][i]=n; k=1;}
    if (a[1][i]==0 && a[2][i]==n && a[3][i]==n && k==0) {a[1][i]=n; k=1;}
    if (a[1][i]==n && a[2][i]==0 && a[3][i]==n && k==0) {a[2][i]=n; k=1;}
}
for (i=1; i<=3; i++)
{
    if (a[i][1]==n && a[i][2]==n && a[i][3]==0 && k==0) {a[i][3]=n; k=1;}
    if (a[i][1]==0 && a[i][2]==n && a[i][3]==n && k==0) {a[i][1]=n; k=1;}
    if (a[i][1]==n && a[i][2]==0 && a[i][3]==n && k==0) {a[i][2]=n; k=1;}
}

// блокируем противника
// проверяем все строки и выбираем оптимальный ход для компьютера
for (i=1; i<=3; i++)
{
    if (a[1][i]==nv && a[2][i]==nv && a[3][i]==0 && k==0) {a[3][i]=n; k=1;}
    if (a[1][i]==0 && a[2][i]==nv && a[3][i]==nv && k==0) {a[1][i]=n; k=1;}
    if (a[1][i]==nv && a[2][i]==0 && a[3][i]==nv && k==0) {a[2][i]=n; k=1;}
}
for (i=1; i<=3; i++)
{
    if (a[i][1]==nv && a[i][2]==nv && a[i][3]==0 && k==0) {a[i][3]=n; k=1;}
    if (a[i][1]==0 && a[i][2]==nv && a[i][3]==nv && k==0) {a[i][1]=n; k=1;}
    if (a[i][1]==nv && a[i][2]==0 && a[i][3]==nv && k==0) {a[i][2]=n; k=1;}
}
// если свободен центр, занимаем его
 if (k==0 && a[2][2]==0 && (rand()+sec())%7>1 ){a[2][2]=n;k=1;};
 // если свободно занимаем углы
 if (k==0 && a[1][1]==0 && (rand()+sec())%5>1 ){a[1][1]=n;k=1;}; 
  // если свободно занимаем углы
 if (k==0 && a[1][3]==0 && (rand()+sec())%5>1 ){a[1][3]=n;k=1;}; 
   // если свободно занимаем углы
 if (k==0 && a[3][1]==0 && (rand()+sec())%5>1 ){a[3][1]=n;k=1;}; 
    // если свободно занимаем углы
 if (k==0 && a[3][3]==0 && (rand()+sec())%5>1 ){a[3][3]=n;k=1;}; 
// случайный выбор свободного места
    for (i=1;i<=3;i++)
    {
        for (j=1;j<=3;j++)
        {
            if (a[i][j]==0 && (rand()+sec())%2==1 && k==0) 
            {a[i][j]=n;
             k=1;
            }
        }
    } 
 if (k==0)
 {
     for (i=1;i<=3;i++)
    {
        for (j=1;j<=3;j++)
        {
            if (a[i][j]==0 && k==0) 
            {a[i][j]=n;
             k=1;
            }
        }
    }       
   }
 }


//------------------ Проверка. Если ни один игрок не выиграл то 0, если выиграл нолик то 1 если выиграл крестик то 2
int proverka()
{   int i;
    int res; // значение функции. Если ни один игрок не выиграл то 0, если выиграл нолик то 1 если выиграл крестик то 2
    res=0;
   // проверям выигрыш первого игрока
   // пробегаем по всем строкам        
    for (i=1; i<=3; i++)
    {
        // проверка  все ли встроке нолики
        if (a[i][1]==1 && a[i][2]==1 && a[i][3]==1 ) {res=1;}
    }
   // пробегаем по всем столбцам      
    for (i=1; i<=3; i++)
    {
        // проверка все ли в столбце нолики
        if (a[1][i]==1 && a[2][i]==1 && a[3][i]==1 ) {res=1;}
    }
    // проверка диагоналей 
      if (a[1][1]==1 && a[2][2]==1 && a[3][3]==1 )  {res=1;}
      if (a[1][3]==1 && a[2][2]==1 && a[3][1]==1 )  {res=1;} 
      
   // проверим выигрыш второго игрока
   // пробегаем по всем строкам        
      for (i=1; i<=3; i++)
    {
    // проверка  все ли в строке крестики
        if (a[i][1]==2 && a[i][2]==2 && a[i][3]==2 ) {res=2;}
    }
    // пробегаем по всем столбцам
    for (i=1; i<=3; i++)
    {
     // проверка все ли в столбце крестики  
        if (a[1][i]==2 && a[2][i]==2 && a[3][i]==2 ) {res=2;}
    }
      // проверка диагоналей 
      if (a[1][1]==2 && a[2][2]==2 && a[3][3]==2 )  {res=2;}
      if (a[1][3]==2 && a[2][2]==2 && a[3][1]==2 )  {res=2;}  
      // условие ничьи
      if (a[1][1]*a[1][2]*a[1][3]*a[2][1]*a[2][2]*a[2][3]*a[3][1]*a[3][2]*a[3][3]>0 && res==0){res=3;}  
    return res;
}


main()

int och; // здесь хранится значение, за кого мы играем
int v; // если = 1, то играем ещё, если = 2, то прекращаем игру.
int igra;// состояние игры если победил нолик то 1, если победил крестик то 2 если никто  пока не победил то 0
int ud; // проверка корректности ввода

v=1;
while (v==1)
{
ud=0;
while (ud==0)
{
printf ("Выберите кем будете играть. 1 -  первыми нолики. 2 - вторыми крестики \n");
scanf("%d",&och);
if (och==1 || och==2 ){ud=1;}
}
// обнуляем очищаем поле
nul();
// отображаем игровое поле
visual();
igra=0;
// пока никто не побелил продолжается игра
while (igra==0)
{

if (och==1){
// ход 1 го игрока нолика
hod(1);
// отображаем игровое поле
visual();
// проверка на победу первого игрока
igra=proverka();
// если первый игрок не победил , то ходит второй игрок
if (igra==0)
{
printf ("Ходит компьютер\n");
// ход второго игрока
hodkomp(2);
// отображаем игровое поле
visual();
// проверка на победу второго игрока
igra=proverka();
}
}
if (och==2){
// ход 1 го игрока нолика
printf ("Ходит компьютер\n");
hodkomp(1);
// отображаем игровое поле
visual();
// проверка на победу первого игрока
igra=proverka();
// если первый игрок не победил, то ходит второй игрок
if (igra==0)
{
// ход второго игрока
hod(2);
// отображаем игровое поле
visual();
// проверка на победу второго игрока
igra=proverka();
}
}
}
// отображение результатов игры
if (igra==1){printf ("Победил нолик\n");};
if (igra==2){printf ("Победил крестик\n");};
if (igra==3){printf ("Ничья ");};
printf ("Сыграем еще? 1 - да. 2 - нет. \n");
scanf("%d", &v);

}
}

Полезно почитать по теме игра крестики нолики на си с компьютером
Алгоритм игры крестики нолики  с компьютером на си 
Основные процедуры программы игры крестики нолики на си 
Алгоритм хода компьютера в игре крестики нолики на си

Поделиться:

 
 
Комментарии (0)

Нет комментариев. Ваш будет первым!