Форум русскоязычного сообщества Ubuntu


Хотите сделать посильный вклад в развитие Ubuntu и русскоязычного сообщества?
Помогите нам с документацией!

Автор Тема: Крестики нолики на с++  (Прочитано 12875 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Гриб_под_зонтом

  • Автор темы
  • Активист
  • *
  • Сообщений: 301
    • Просмотр профиля
Re: Крестики нолики на с++
« Ответ #75 : 26 Января 2015, 19:52:39 »
alsoijw,
Про пять символов никто не говорил. Ну ладно, тогда так: в строчке берём иксовый символ(x от 1 до предел-5) и от него проверяем наличие крестиков на следующих пяти клетках.
Hp 250 G3: 8Gb RAM, Intel Celeron 2.16-2.58GHz with 2 core, Intel HD Graphics.
Ubuntu 18.04 LTS with GNOME 3.

Оффлайн alsoijw

  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Re: Крестики нолики на с++
« Ответ #76 : 26 Января 2015, 19:54:59 »
Гриб_под_зонтом, согласен. Напиши код, который будет для каждой строки проверять выигрыш. Пока только строки. Если выиграл - напиши сообщение в начале поля, которое не будет стираться. Код целиком.

Пользователь решил продолжить мысль [time]26 Январь 2015, 18:56:37[/time]:
Можно ходить крестиком, можно ноликом. Пока так.

Пользователь решил продолжить мысль 26 Января 2015, 19:57:09:
Вернее пока только крестиком, ноликом ходить будет бот.
« Последнее редактирование: 26 Января 2015, 19:57:09 от alsoijw »
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн Гриб_под_зонтом

  • Автор темы
  • Активист
  • *
  • Сообщений: 301
    • Просмотр профиля
Re: Крестики нолики на с++
« Ответ #77 : 26 Января 2015, 20:14:09 »
alsoijw,
Не знаю почему, но такой код не работает:
Код: (cpp) [Выделить]
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <termios.h>
#include <sys/select.h>
using namespace std;
 
/*указываем размер поля*/
const int predel = 25;
char pole[predel][predel];
/*Координаты указателя*/
int x; int y;
/*Служит для выхода*/
bool nado;
 
void nonblock(int state)
{
        struct termios ttystate;
        tcgetattr(STDIN_FILENO, &ttystate);
        if (state == 1)
        {
                ttystate.c_lflag &= ~ICANON;
                ttystate.c_cc[VMIN] = 1;
        }
        else if (state == 0)
        {
                ttystate.c_lflag |= ICANON;
        }
        tcsetattr(0, TCSANOW, &ttystate);
}
bool win()
{
int win = 0;

     for (int x2 = 0; x2 < predel; x2++)
     {
for (int y2 = 0; y2 <= predel-5; y2++)
{
       for (int k=0; k <= 5; k++)
       {
               if (pole[x2][y2+k]=='X') win++;
               }
       if (win!=5) win = 0;
     }
    }
    if (win==5) return true;
    else return false;
}
inline int getch()
{
        nonblock(1);
        return fgetc(stdin);
}
 
void init()
{
        /*Заполняем поле пробелами*/
        for(int i = 0; i < predel; i++)
        {
                for(int m = 0; m < predel; m++)
                {
                        pole[m][i] = ' ';
                }
        }
        /*Выстанавливаем указатель в центре поля*/
        x = 13;
        y = 13;
        /*Заставляем приложение работать*/
        nado = true;
}
 
void print_pole()
{
        /*Стираем экран*/
        cout<<"\033[H\033[J\033[m";
        /*Печатаем поле*/
        for(int y1 = 0; y1 < predel; y1++)
        {
                for(int x1 = 0; x1 < predel; x1++)
                {
                        /*Если данный символ - указатель то выделям красным цветом*/
                        if(x == x1 && y == y1)
                        {
                                cout << "\x1b[41m" << pole[x1][y1] << "\x1b[0m";
                        }
                        else
                        {
                                cout << pole[x1][y1];
                        }
                }
                /*Закончили печатать одну строку, перевод каретки*/
                cout << endl;
        }
}
 
void motion()
{
        /*Указатель не должен выходить за пределы поля*/
        char m = getch();
        switch (m)
        {
                case 68:
                        if(x > 0)
                        {
                                x--;
                        }
                        break;
                case 67:
                        if(predel - x > 1)
                        {
                                x++;
                        }
                        break;
                case  65:
                        if(y > 0)
                        {
                                y--;
                        }
                        break;
                case 66:
                        if(predel - y > 1)
                        {
                                y++;
                        }
                        break;
                /*Для выхода*/
                case 'q' :
                        nado = false;
                        break;
                /*Если стоит крестик - убираем иначе ставим*/
                case 'z' :
                        if(pole[x][y] == ' ')
                        {
                                pole[x][y] = 'X';
                        }
                        else if(pole[x][y] == 'X')
                        {
                                pole[x][y] = ' ';
                        }
                        break;
        }
}
 
int main()
{
        init();
        print_pole();
        while(nado)
        {
                motion();
                print_pole();
                if (win()==true) break;
        }
        cout << "You win!" << endl;
        return 0;
}

Пользователь решил продолжить мысль 26 Января 2015, 20:15:13:
При вставке кода пробелы исчезают и появляются сами по себе, в оригинале такого нет
Hp 250 G3: 8Gb RAM, Intel Celeron 2.16-2.58GHz with 2 core, Intel HD Graphics.
Ubuntu 18.04 LTS with GNOME 3.

Оффлайн alsoijw

  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Re: Крестики нолики на с++
« Ответ #78 : 26 Января 2015, 21:37:55 »
Гриб_под_зонтом, баг#1 - если я просто вышел, то мне напишут что я победил.
Три цикла - как то много. Вот здесь
Код: (cpp) [Выделить]
for (int k=0; k <= 5; k++)
{
    if (pole[x2][y2+k]=='X') win++;
}
Ты не предусмотрел, что может попасться такая последовательность XXOXX. А жаль. Алгоритм: пробегаем строку, ищя повторение. Ищем повторение: сравниваем предыдущий символ с текущим, если равны - длина++, иначе запоминаем текущий символ(чтоб было с чем следующий сравнивать), изменяем длину.
Замечание Если текущий символ пробел - то цепочки нет, иначе цепочка началась(длина = 1).
Хотя я видел так - функция с пятью аргументами, котороя их сравнивает между собой. Тогда бы все функции для интеллекта выглядели бы очень похоже.
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн Гриб_под_зонтом

  • Автор темы
  • Активист
  • *
  • Сообщений: 301
    • Просмотр профиля
Re: Крестики нолики на с++
« Ответ #79 : 26 Января 2015, 21:58:57 »
alsoijw,
ХХОХХ я предусмотрел: k принимает значения от 1 до 5 и если win!=5 то win=0, то есть другого варианта кроме ХХХХХ нет
Hp 250 G3: 8Gb RAM, Intel Celeron 2.16-2.58GHz with 2 core, Intel HD Graphics.
Ubuntu 18.04 LTS with GNOME 3.

Оффлайн alsoijw

  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Re: Крестики нолики на с++
« Ответ #80 : 26 Января 2015, 22:18:56 »
Гриб_под_зонтом, извини, не заметил. Долго гипнотизировал код. Ошибка в чём? Ошибка в том, что нужно проверять не нужно ли сбрасывать и длину цепочки в одном месте.
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн Гриб_под_зонтом

  • Автор темы
  • Активист
  • *
  • Сообщений: 301
    • Просмотр профиля
Re: Крестики нолики на с++
« Ответ #81 : 26 Января 2015, 22:43:29 »
alsoijw,
То есть? Не совсем понял в чём ошибка
Hp 250 G3: 8Gb RAM, Intel Celeron 2.16-2.58GHz with 2 core, Intel HD Graphics.
Ubuntu 18.04 LTS with GNOME 3.

Оффлайн alsoijw

  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Re: Крестики нолики на с++
« Ответ #82 : 26 Января 2015, 23:04:46 »
Вот правильный код:
Код: (cpp) [Выделить]
bool win()
{
int win = 0;
for (int x2 = 0; x2 < predel; x2++)
{
for (int y2 = 0; y2 <= predel-5; y2++)
{
for (int k=0; k <= 5; k++)
{
if (pole[x2][y2+k]=='X') win++;
}
if (win==5) return true;
if (win!=5) win = 0;
}
}
return false;
}
При этом код наличия пропусков, выигрыша можно чуть чуть иначе оформить
Код: (cpp) [Выделить]
if (win==5) return true;
else if (win!=5) win = 0;
или поменять строчки местами...
ДЗПоправит баг#1 - если я просто вышел, то мне напишут что я победил, чтоб была проверка как по горизонтали так и по вертикали, если сможешь то и по диагонали. Код привести целиком. Предусмотреть выигрыш ноликов.

Пользователь решил продолжить мысль 26 Января 2015, 23:11:07:
Да, ещё я хочу узнать, почему эта версия работает, а предыдущая нет.
« Последнее редактирование: 26 Января 2015, 23:11:07 от alsoijw »
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн Гриб_под_зонтом

  • Автор темы
  • Активист
  • *
  • Сообщений: 301
    • Просмотр профиля
Re: Крестики нолики на с++
« Ответ #83 : 26 Января 2015, 23:24:18 »
alsoijw,
Код: (cpp) [Выделить]
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <termios.h>
#include <sys/select.h>
using namespace std;
 
/*указываем размер поля*/
const int predel = 25;
char pole[predel][predel];
/*Координаты указателя*/
int x; int y;
/*Служит для выхода*/
bool nado;
 
void nonblock(int state)
{
        struct termios ttystate;
        tcgetattr(STDIN_FILENO, &ttystate);
        if (state == 1)
        {
                ttystate.c_lflag &= ~ICANON;
                ttystate.c_cc[VMIN] = 1;
        }
        else if (state == 0)
        {
                ttystate.c_lflag |= ICANON;
        }
        tcsetattr(0, TCSANOW, &ttystate);
}
bool win()
{
        int win = 0;
        for (int x2 = 0; x2 < predel; x2++)
        {
                for (int y2 = 0; y2 <= predel-5; y2++)
                {
                        for (int k=0; k <= 5; k++)
                        {
                                if (pole[x2][y2+k]=='X') win++;
                        }
                        if (win==5) return true;
                        if (win!=5) win = 0;
                       
                        for (int k=0; k <= 5; k++)
                        {
                                if (pole[x2+k][y2]=='X') win++;
                        }
                        if (win==5) return true;
                        if (win!=5) win = 0;
                }
        }
        return false;
}
inline int getch()
{
        nonblock(1);
        return fgetc(stdin);
}
 
void init()
{
        /*Заполняем поле пробелами*/
        for(int i = 0; i < predel; i++)
        {
                for(int m = 0; m < predel; m++)
                {
                        pole[m][i] = ' ';
                }
        }
        /*Выстанавливаем указатель в центре поля*/
        x = 13;
        y = 13;
        /*Заставляем приложение работать*/
        nado = true;
}
 
void print_pole()
{
        /*Стираем экран*/
        cout<<"\033[H\033[J\033[m";
        /*Печатаем поле*/
        for(int y1 = 0; y1 < predel; y1++)
        {
                for(int x1 = 0; x1 < predel; x1++)
                {
                        /*Если данный символ - указатель то выделям красным цветом*/
                        if(x == x1 && y == y1)
                        {
                                cout << "\x1b[41m" << pole[x1][y1] << "\x1b[0m";
                        }
                        else
                        {
                                cout << pole[x1][y1];
                        }
                }
                /*Закончили печатать одну строку, перевод каретки*/
                cout << endl;
        }
}
 
void motion()
{
        /*Указатель не должен выходить за пределы поля*/
        char m = getch();
        switch (m)
        {
                case 68:
                        if(x > 0)
                        {
                                x--;
                        }
                        break;
                case 67:
                        if(predel - x > 1)
                        {
                                x++;
                        }
                        break;
                case  65:
                        if(y > 0)
                        {
                                y--;
                        }
                        break;
                case 66:
                        if(predel - y > 1)
                        {
                                y++;
                        }
                        break;
                /*Для выхода*/
                case 'q' :
                        nado = false;
                        break;
                /*Если стоит крестик - убираем иначе ставим*/
                case 'z' :
                        if(pole[x][y] == ' ')
                        {
                                pole[x][y] = 'X';
                        }
                        else if(pole[x][y] == 'X')
                        {
                                pole[x][y] = ' ';
                        }
                        break;
        }
}
 
int main()
{
        init();
        print_pole();
        while(nado)
        {
                motion();
                print_pole();
                if (win()==true) cout << "You win!" << endl; break;
        }       
        return 0;
}
Что значит inline? Раньше с этим не встречался
Hp 250 G3: 8Gb RAM, Intel Celeron 2.16-2.58GHz with 2 core, Intel HD Graphics.
Ubuntu 18.04 LTS with GNOME 3.

Оффлайн alsoijw

  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Re: Крестики нолики на с++
« Ответ #84 : 26 Января 2015, 23:48:01 »
Гриб_под_зонтом, http://cppstudio.com/post/2676/. Ты понял, как я починил функцию?
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн Гриб_под_зонтом

  • Автор темы
  • Активист
  • *
  • Сообщений: 301
    • Просмотр профиля
Re: Крестики нолики на с++
« Ответ #85 : 27 Января 2015, 00:10:53 »
alsoijw,
Понял. Кстати, попытался сделать то же самое в крестиках ноликах, но всё фигово вышло, пришлось возвращать как было. Как сделать такой выбор в кр?
Hp 250 G3: 8Gb RAM, Intel Celeron 2.16-2.58GHz with 2 core, Intel HD Graphics.
Ubuntu 18.04 LTS with GNOME 3.

Оффлайн alsoijw

  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Re: Крестики нолики на с++
« Ответ #86 : 27 Января 2015, 15:07:34 »
Гриб_под_зонтом, давай перед кодом будешь писать номер сборки. В предыдущей сборке код поломан, мне лень выяснять почему. Он сразу же завершает свою работу. Что пытался сделать, но не получилось?
ДЗ Теперь при выигрыше программа не завершается. В функции вывода поля сначала выводится выиграл/не выиграл, для выхода по прежнему есть клавиша.
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн Гриб_под_зонтом

  • Автор темы
  • Активист
  • *
  • Сообщений: 301
    • Просмотр профиля
Re: Крестики нолики на с++
« Ответ #87 : 27 Января 2015, 18:57:52 »
alsoijw,
Код: (cpp) [Выделить]
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <termios.h>
#include <sys/select.h>
using namespace std;
 
/*указываем размер поля*/
const int predel = 25;
char pole[predel][predel];
/*Координаты указателя*/
int x; int y;
/*Служит для выхода*/
bool nado;
 
void nonblock(int state)
{
        struct termios ttystate;
        tcgetattr(STDIN_FILENO, &ttystate);
        if (state == 1)
        {
                ttystate.c_lflag &= ~ICANON;
                ttystate.c_cc[VMIN] = 1;
        }
        else if (state == 0)
        {
                ttystate.c_lflag |= ICANON;
        }
        tcsetattr(0, TCSANOW, &ttystate);
}
bool win()
{
        int win = 0;
        for (int x2 = 0; x2 < predel; x2++)
        {
                for (int y2 = 0; y2 <= predel-5; y2++)
                {
                        for (int k=0; k <= 5; k++)
                        {
                                if (pole[x2][y2+k]=='X') win++;
                        }
                        if (win==5) return true;
                        if (win!=5) win = 0;
                       
                        for (int k=0; k <= 5; k++)
                        {
                                if (pole[x2+k][y2]=='X') win++;
                        }
                        if (win==5) return true;
                        if (win!=5) win = 0;
                }
        }
        return false;
}
inline int getch()
{
        nonblock(1);
        return fgetc(stdin);
}
 
void init()
{
        /*Заполняем поле пробелами*/
        for(int i = 0; i < predel; i++)
        {
                for(int m = 0; m < predel; m++)
                {
                        pole[m][i] = ' ';
                }
        }
        /*Выстанавливаем указатель в центре поля*/
        x = 13;
        y = 13;
        /*Заставляем приложение работать*/
        nado = true;
}
 
void print_pole()
{

        /*Стираем экран*/
        cout<<"\033[H\033[J\033[m";
        /*Печатаем поле*/
        for(int y1 = 0; y1 < predel; y1++)
        {
                for(int x1 = 0; x1 < predel; x1++)
                {
                        /*Если данный символ - указатель то выделям красным цветом*/
                        if(x == x1 && y == y1)
                        {
                                cout << "\x1b[41m" << pole[x1][y1] << "\x1b[0m";
                        }
                        else
                        {
                                cout << pole[x1][y1];
                        }
                }
                /*Закончили печатать одну строку, перевод каретки*/
                cout << endl;
               
        }
        if (win()==true) cout << "You win!" << endl;
}
 
void motion()
{
        /*Указатель не должен выходить за пределы поля*/
        char m = getch();
        switch (m)
        {
                case 68:
                        if(x > 0)
                        {
                                x--;
                        }
                        break;
                case 67:
                        if(predel - x > 1)
                        {
                                x++;
                        }
                        break;
                case  65:
                        if(y > 0)
                        {
                                y--;
                        }
                        break;
                case 66:
                        if(predel - y > 1)
                        {
                                y++;
                        }
                        break;
                /*Для выхода*/
                case 'q' :
                        nado = false;
                        break;
                /*Если стоит крестик - убираем иначе ставим*/
                case 'z' :
                        if(pole[x][y] == ' ')
                        {
                                pole[x][y] = 'X';
                        }
                        else if(pole[x][y] == 'X')
                        {
                                pole[x][y] = ' ';
                        }
                        break;
        }
}
 
int main()
{
        init();
        print_pole();
        while(nado)
        {
                motion();
                print_pole();
               
        }       
        return 0;
}
Hp 250 G3: 8Gb RAM, Intel Celeron 2.16-2.58GHz with 2 core, Intel HD Graphics.
Ubuntu 18.04 LTS with GNOME 3.

Оффлайн alsoijw

  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Re: Крестики нолики на с++
« Ответ #88 : 27 Января 2015, 21:16:22 »
Гриб_под_зонтом, замечание баг2 4 нижние строки не обрабатываются. ИМХО решать эту задачу 3 циклами не самый лучший вариант, но пока оставим так.
ДЗ Теперь реализуй проверку по диагонали. По диагонали должны быть две проверки. К примеру слева сверху справа вниз и справа сверху слева вниз. Не выйди за пределы поля!
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн Гриб_под_зонтом

  • Автор темы
  • Активист
  • *
  • Сообщений: 301
    • Просмотр профиля
Re: Крестики нолики на с++
« Ответ #89 : 29 Января 2015, 17:18:10 »
alsoijw,
Как сделать диагонали не знаю, пытался по разном но не вышло(
Hp 250 G3: 8Gb RAM, Intel Celeron 2.16-2.58GHz with 2 core, Intel HD Graphics.
Ubuntu 18.04 LTS with GNOME 3.

 

Страница сгенерирована за 0.036 секунд. Запросов: 25.