Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
0 / 0 / 0
Регистрация: 20.01.2011
Сообщений: 4
1

Нужна оценка

20.01.2011, 19:42. Показов 1073. Ответов 14
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем доброго времени суток.
Чуть меньше недели назад начал изучать С++ и сегодня написал таки некое подобие программы.

Суть просьбы: нужна чья-нибудь проверка на явный быдлокод/неудачные моменты; хотелось бы услышать мнение от всех, кто пишет больше моего. Сорсы, разумеется, прикреплены.
Буду рад любой критике в свой адрес.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// Игра в крестики-нолики.
#include <iostream>
#include <conio.h>
 
using namespace std;
 
// Класс для создания ячеек поля. 
// value - значение: -1 "нолик", 1 "крестик", 0 пусто; prior - приоритет ячейки.
class Cell 
{
    public:
        int getValue () { return value; }
        void setValue ( int val ) { value = val; } 
        int getPrior () { return prior; }
        void setPrior ( int pr ) { prior = pr; }
    private:
        int value, prior;
};
 
void CreateField ( Cell **pField );
int SetPriority ( Cell **pField );
int CheckResultFromLastStep ( Cell **pField );
void Crossing ( Cell **pField );
void Zeroing ( Cell **pField );
 
 
int main()
{
    enum Cycle { UWin, CWin, CycCont, CycBreak };
    int fCycle, fCycle0, UserSc=0, CompSc=0;
    do
    {
        Cell **Field = new Cell*[3]; // Создание массива 3х3.
        for ( int i=0; i<3; i++ )
        {
            Field[i] = new Cell[3];
        }
        CreateField ( &*Field ); // Установка первоначальных значений и приоритетов.
        fCycle=2;
        fCycle0=2;
        while( fCycle==CycCont && fCycle0==CycCont )
        {
            system ("cls");
            cout << "Welcome to Tic-Tac-Toe                                    ";
            cout << "You " << UserSc << " - " << CompSc << " Comp \n\n";
            for ( int i=0; i<3; i++ ) //Вывод поля.
            {
                for ( int j=0; j<3; j++ )
                {
                    if ( Field[i][j].getValue () == 1 )
                        cout << "X ";
                    if ( Field[i][j].getValue () == -1 )
                        cout << "Y ";
                    if ( Field[i][j].getValue () == 0 )
                        cout << "_ ";
                }
                cout << endl;
            }
            cout << endl;
            Crossing ( &*Field ); // Ввод "крестика", изменение значения ячейки и ее приоритета.
            fCycle = SetPriority ( &*Field ); // Поиск наилучшей ячейки для следующего хода ИИ (по приоритету), проверка на выйгрыш пользователя.
            if (fCycle == CycCont)
            {
                Zeroing ( &*Field ); // Ввод "нолика", изменение значения ячейки и ее приоритета.
                fCycle0 = CheckResultFromLastStep ( &*Field ); // Проверка результатов после последнего действия ИИ, переустановка приоритета.
            }
        }
        for (int i=0; i<3; i++) // Удаление массива.
            delete Field[i];
        delete [] Field;
 
        cout << "\n\n";
        if ( fCycle==UWin )
        {
            cout << "You won!!1 \n\n";
            UserSc++;
        }
        if ( fCycle0==CWin )
        {
            cout << "Computer won! \n\n";
            CompSc++;
        }
        if ( fCycle==CycBreak )
        {
            cout << "Nobody won.. \n\n";
        }
        getch();
    } while ( true );
    getch();
    return 0;
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Установка значения всех клеток на "0" (пустые) и установка приоритета на 3 для угловых, 4 - центральной, 1 - остальных.
void CreateField ( Cell **pField )
{
    for ( int i=0; i<3; i++ )
        for ( int j=0; j<3; j++ )
        {
            pField[i][j].setValue(0);
            pField[i][j].setPrior(1);
        }
    pField[1][1].setPrior(4);
    pField[0][0].setPrior(3);
    pField[0][2].setPrior(3);
    pField[2][0].setPrior(3);
    pField[2][2].setPrior(3);
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// Установка приоритета в случае заполнения пользователем 2-х рядомстоящих клеток.
int SetPriority ( Cell **pField )
{
    int fNoWinner=0, fUser;
    for ( int i=0; i<3; i++ ) // Определение элементов (крестиков и ноликов) по строкам и столбцам.
    {
        fUser=0;
        for ( int j=0; j<3; j++ ) // Поиск элементов по строкам.
            if ( pField[i][j].getValue()==1 )
                fUser++;
        if ( fUser==3 ) // Определение победил ли игрок.
            return 0;
        if ( fUser==2 ) // Есть ли строки/столбцы, в которых пользователю осталось заполнить одну ячейку.
            for ( int j=0; j<3; j++ ) // Если есть - находим эту ячейку и присваиваем ей повышенный приоритет.
                if ( pField[i][j].getValue()==0 )
                    pField[i][j].setPrior(10);
    }
//------------------------------------------------------------------------------------
    for ( int j=0; j<3; j++ ) // Определение элементов (крестиков и ноликов) по строкам и столбцам.
    {
        fUser=0;
        for ( int i=0; i<3; i++ ) // Поиск элементов по столбцам.
            if ( pField[i][j].getValue()==1 )
                fUser++;
        if ( fUser==3 ) // Определение победил ли игрок.
            return 0;
        if ( fUser==2 ) // Есть ли строки/столбцы, в которых пользователю осталось заполнить одну ячейку.
            for ( int i=0; i<3; i++ ) // Если есть - находим эту ячейку и присваиваем ей повышенный приоритет.
                if ( pField[i][j].getValue()==0 )
                    pField[i][j].setPrior(10);
    }
//------------------------------------------------------------------------------------
    fUser=0;
    for ( int i=0; i<3; i++ ) // Определение элементов на диагоналях.
        for ( int j=0; j<3; j++ ) // Определение элементов на главной диагонали.
            if ( i==j && pField[i][j].getValue()==1 )
                fUser++;
    if ( fUser==3 ) // Определение победил ли игрок.
        return 0;
    if ( fUser==2 ) // Осталось ли пользователю заполнить одну ячейку на диагонали.
        for ( int i=0; i<3; i++ ) // Если такая ячейка есть - находим ее и присваиваем ей повышенный приоритет.
            for ( int j=0; j<3; j++ )
                if ( pField[i][j].getValue()==0 && i==j )
                    pField[i][j].setPrior(10);
//------------------------------------------------------------------------------------
    fUser=0;
    for ( int i=0; i<3; i++ ) // Определение элементов на диагоналях.
        for ( int j=0; j<3; j++ ) // Определение элементов на побочной диагонали диагонали.
            if ( i+j==2 && pField[i][j].getValue()==1 )
                fUser++;
    if ( fUser==3 ) // Определение победил ли игрок.
        return 0;
    if ( fUser==2 ) // Осталось ли пользователю заполнить одну ячейку на диагонали.
        for ( int i=0; i<3; i++ ) // Если такая ячейка есть - находим ее и присваиваем ей повышенный приоритет.
            for ( int j=0; j<3; j++ )
                if ( pField[i][j].getValue()==0 && i+j==2 )
                    pField[i][j].setPrior(10);
//------------------------------------------------------------------------------------
    for ( int i=0; i<3; i++ ) // Проверка на заполненность всего поля.
        for ( int j=0; j<3; j++ )
            if ( pField[i][j].getPrior()==-1 )
                fNoWinner++;
    if ( fNoWinner==9 )
        return 3;
    else
        return 2;
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// Проверка результатов после последнего действия ИИ.
int CheckResultFromLastStep ( Cell **pField )
{
    int fNoWinner=0, fComp;
    for ( int i=0; i<3; i++ ) // Определение элементов (крестиков и ноликов) по строкам и столбцам.
    {
        fComp=0;
        for ( int j=0; j<3; j++ ) // Поиск элементов по строкам.
            if ( pField[i][j].getValue()==-1 )
                fComp++;
        if ( fComp==3 ) // Победил ли ИИ.
            return 1; 
        if ( fComp==2 ) // Есть ли строки/столбцы, в которых ИИ осталось заполнить одну ячейку.
            for ( int j=0; j<3; j++ ) // Если есть - находим эту ячейку и присваиваем ей повышенный приоритет.
                if ( pField[i][j].getValue()==0 )
                    pField[i][j].setPrior(12);
    }
//------------------------------------------------------------------------------------
    for ( int j=0; j<3; j++ ) // Определение элементов (крестиков и ноликов) по строкам и столбцам.
    {
        fComp=0;
        for ( int i=0; i<3; i++ ) // Поиск элементов по столбцам.
            if ( pField[i][j].getValue()==-1 )
                fComp++;
        if ( fComp==3 ) // Победил ли ИИ.
            return 1; 
        if ( fComp==2 ) // Есть ли строки/столбцы, в которых ИИ осталось заполнить одну ячейку.
            for ( int i=0; i<3; i++ ) // Если есть - находим эту ячейку и присваиваем ей повышенный приоритет.
                if ( pField[i][j].getValue()==0 )
                    pField[i][j].setPrior(12);
    }
//------------------------------------------------------------------------------------
    fComp=0;
    for ( int i=0; i<3; i++ ) // Определение элементов на диагоналях.
        for ( int j=0; j<3; j++ ) // Определение элементов на главной диагонали.
            if ( i==j && pField[i][j].getValue()==-1 )
                fComp++;
    if ( fComp==3 ) // Победил ли ИИ.
        return 1; 
    if ( fComp==2 ) // Осталось ли ИИ заполнить одну ячейку на диагонали.
        for ( int i=0; i<3; i++ ) // Если такая ячейка есть - находим ее и присваиваем ей повышенный приоритет.        
            for ( int j=0; j<3; j++ ) 
                if ( pField[i][j].getValue()==0 && i==j )
                    pField[i][j].setPrior(12);
//------------------------------------------------------------------------------------
    fComp=0;
    for ( int i=0; i<3; i++ ) // Определение элементов на диагоналях.
        for ( int j=0; j<3; j++ ) // Определение элементов на побочной диагонали диагонали.
            if ( i+j==2 && pField[i][j].getValue()==-1 )
                fComp++;
    if ( fComp==3 ) // Победил ли ИИ.
        return 1; 
    if ( fComp==2 ) // Осталось ли ИИ заполнить одну ячейку на диагонали.
        for ( int i=0; i<3; i++ ) // Если такая ячейка есть - находим ее и присваиваем ей повышенный приоритет.        
            for ( int j=0; j<3; j++ ) 
                if ( pField[i][j].getValue()==0 && i+j==2 )
                    pField[i][j].setPrior(12);
//------------------------------------------------------------------------------------
    return 2;
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Ввод координат для хода пользователя; перерасчет значений и приоритета для хода ИИ.
void Crossing ( Cell **pField )
{
    bool fl=0;
    int X,Y;
    while ( fl==0 ) // Ввод, изменение значения ячейки и ее приоритета.
    {
        cout << "Enter coords X: ";
        cin >> X;
        X--;
        cout << "Enter coords Y: ";
        cin >> Y;
        Y--;
        if ( X<=2 && Y<=2 )
            if ( pField[X][Y].getValue() == 0 )
            {
                fl=1;
                pField[X][Y].setValue(1);
                pField[X][Y].setPrior(-1);
            }
            else
                cout << "Incorrect coords" << endl;
        else
            cout << "Incorrect coords" << endl;
    }
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Нахождение наибольшего приоритета, ход компьютера.           
void Zeroing ( Cell **pField )
{
    int max=0, X=0, Y=0;
    for ( int i=0; i<3; i++ ) // Поиск максимального значения приоритета с запоминанием индексов.
        for ( int j=0; j<3; j++ )
            if ( max<pField[i][j].getPrior() )
            {
                max = pField[i][j].getPrior();
                X = i;
                Y = j;
            }
    pField[X][Y].setValue(-1);
    pField[X][Y].setPrior(-1);
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
20.01.2011, 19:42
Ответы с готовыми решениями:

Оценка значения машинного нуля относительно заданного вещественного числа (нужна блок-схема)
Программа оценивает значение машинного нуля относительно заданного вещественного числа (float,...

Список учеников имеет следующую структуру: фамилия – класс - оценка по алгебре - оценка по физике - средний балл
Задание такое Список учеников имеет следующую структуру: фамилия – класс - оценка по алгебре -...

Нужна оценка!
Процессор Intel Core i5-4570 3.2GHz Корпус Zalman Z5 Plus Black Видеокарта msi geforce gtx 760...

Нужна оценка сборки
Хочу собрать компьютер для игр таких как GTA SAMP, World of tanks и т. д. Мне помогли в другой теме...

14
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
20.01.2011, 19:52 2
%user_name%, Первое замечение. Функции с префиксом get должны быть константные.
+ Я бы использовал побольше перечислений. Магические числа не украшают код
2
68 / 68 / 3
Регистрация: 18.12.2010
Сообщений: 127
20.01.2011, 20:07 3
Вы используете в классе геттеры и сеттеры (функции). Отделяйте спецификацию от реализации (инкапсуция в каком-то роде). Т.е. header file постовляет только своего рода заглушки на функции, а cpp-файл реализует эти же функции.

А так если вы действительно работаете с С++ только неделю, то довольно не плохо!!!

Добавлено через 3 минуты
Впредь не выкладывайте код целиком, а только отдельные "интересные" кусочки (рассматривать 300 строчек чужого кода особой радости не приносит!!!)
1
Эксперт С++
5043 / 2622 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 1
20.01.2011, 20:47 4
killboss, стиль написания кода это личное дело каждого и никакого отношения к ООП не имеет. К тому же функции действительно небольшие.
ForEveR, в Java вообще нет понятия заголовочных файлов, по другому просто нельзя писать, в C# вроде бы тоже не принято.

%user_name%, если вы пишете на C++ с использованием STL (а я разглядел строку using namespace std), то пользоваться динамическим выделением памяти в чистом виде не совсем хороший путь. Пользуйтесь контейнерами vector, list и так далее.
Отдельные функции CreateField и ей подобные лучше выделить в класс Field.

И еще все таки лучше обойтись без использования using namespace, а писать путь полностью, то есть std::cout, std::cin, std::vector и так далее, иначе вся прелесть и смысл пространств имен теряется.
1
0 / 0 / 0
Регистрация: 20.01.2011
Сообщений: 4
20.01.2011, 21:21  [ТС] 5
Цитата Сообщение от ForEveR Посмотреть сообщение
%user_name%, Первое замечение. Функции с префиксом get должны быть константные.
Учту.

Цитата Сообщение от ForEveR Посмотреть сообщение
+ Я бы использовал побольше перечислений. Магические числа не украшают код
Мм.. использование enum - признак хорошего тона?
Спасибо


Цитата Сообщение от killboss Посмотреть сообщение
Вы используете в классе геттеры и сеттеры (функции). Отделяйте спецификацию от реализации (инкапсуция в каком-то роде). Т.е. header file постовляет только своего рода заглушки на функции, а cpp-файл реализует эти же функции.
Ага, знаем, но просто здесь класс маленький, поэтому не решился отделять от тела основной программы.
Вопрос: как подключать хеадеры? #include <file_name.h>?

Цитата Сообщение от killboss Посмотреть сообщение
Впредь не выкладывайте код целиком, а только отдельные "интересные" кусочки (рассматривать 300 строчек чужого кода особой радости не приносит!!!)
Не подумал, больше не буду. )
Спасибо
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
20.01.2011, 21:22 6
%user_name%, #include "file_name.h"
0
Эксперт С++
5043 / 2622 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 1
20.01.2011, 21:24 7
Цитата Сообщение от %user_name% Посмотреть сообщение
Мм.. использование enum - признак хорошего тона?
Использование магических чисел - признак плохого тона
1
0 / 0 / 0
Регистрация: 20.01.2011
Сообщений: 4
20.01.2011, 21:24  [ТС] 8
Цитата Сообщение от fasked Посмотреть сообщение
%user_name%, если вы пишете на C++ с использованием STL (а я разглядел строку using namespace std), то пользоваться динамическим выделением памяти в чистом виде не совсем хороший путь. Пользуйтесь контейнерами vector, list и так далее.
Отдельные функции CreateField и ей подобные лучше выделить в класс Field.
Этот момент понятен..

Цитата Сообщение от fasked Посмотреть сообщение
И еще все таки лучше обойтись без использования using namespace, а писать путь полностью, то есть std::cout, std::cin, std::vector и так далее, иначе вся прелесть и смысл пространств имен теряется.
..а вот этот как-то не очень.
Можно разъяснить?)
0
54 / 54 / 9
Регистрация: 09.11.2010
Сообщений: 120
20.01.2011, 21:26 9
Цитата Сообщение от fasked Посмотреть сообщение
И еще все таки лучше обойтись без использования using namespace, а писать путь полностью, то есть std::cout, std::cin, std::vector и так далее, иначе вся прелесть и смысл пространств имен теряется.
Объясните мне пожалуйста почему "лучше обходиться" без using namespace'a и полностью писать std::? Не удобно же ...
0
68 / 68 / 3
Регистрация: 18.12.2010
Сообщений: 127
20.01.2011, 21:29 10
Цитата Сообщение от %user_name% Посмотреть сообщение
#include <file_name.h>
Эти файлы расположены где-то c:\program files\vs\ и так далее.
Вам же нужно (как я понял) открыть файл, который находится в проекте. Поэтому

C++
1
#include "file_name.h"
Да и необходимо что этот файл был прикреплён к проекту: Project->Add Existing Item или New Item (что вам подходит)
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
20.01.2011, 21:29 11
Escapable, Неудобно спать на потолке. А прямое использование std::
1) Явно видно использование пространтсва имен.
2) Нет возможности колизий.
0
Freelance
Эксперт С++
2891 / 1826 / 356
Регистрация: 09.09.2010
Сообщений: 3,841
20.01.2011, 21:30 12
Escapable, Вот напишите проект на С++, строк так, на пару тисяч и тогда посмотрите удобно или нет.
0
68 / 68 / 3
Регистрация: 18.12.2010
Сообщений: 127
20.01.2011, 21:32 13
Цитата Сообщение от Escapable Посмотреть сообщение
Объясните мне пожалуйста почему "лучше обходиться" без using namespace'a и полностью писать std::? Не удобно же ...
Во избежание конфликта имён!
0
Эксперт С++
5043 / 2622 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 1
20.01.2011, 21:35 14
Цитата Сообщение от Escapable Посмотреть сообщение
Объясните мне пожалуйста почему "лучше обходиться" без using namespace'a и полностью писать std::? Не удобно же ...
Для избежания конфликтов. Если во всем пространстве попадется две функции (класса, переменных и так далее) с одинаковыми именами, то возникнет конфликт. Например, в пространстве std существует класс vector. Допустим, что программист создал класс с аналогичным именем. И получаем такой код.

C++
1
2
3
4
5
6
7
8
9
#include <vector> // это вектор библиотеки STL
#include "myvector" // а это вектор, созданный нашим программистом
 
using namespace std;
 
int main()
{
     vector<int> v; // ошибка
}
В таком коде возникнет ошибка, потому как неизвестно экземпляр какого из двух классов создавать. Если же исключить строку using namespace и написать конкретно std::vector<int> или mynamespace::vector<int>, то конфликта соответственно не возникнет.
В небольших проектах, конечно это несущественно, так как весь объем кода довольно легко контролируется, но использование явного указания считается хорошей привычкой.
1
0 / 0 / 0
Регистрация: 20.01.2011
Сообщений: 4
20.01.2011, 21:58  [ТС] 15
На ~10 часу прослушивания одной песни появилась мысль: "А сколько я уже это слушаю?" отсюда же вопрос: я так понимаю, что С++ позволяет писать плагины под приложения поддерживающие их (Aimp, WinAmp, etc)?

fasked, спасибо за разъяснение с примером.

ADDED: а ф-ии CheckResultFromLastStep() и SetPriority() оказывается-то практически идентичны и вполне можно было обойтись одной с некоторыми правками.
0
20.01.2011, 21:58
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.01.2011, 21:58
Помогаю со студенческими работами здесь

Нужна оценка профессионала
Приветствую! Нужна оценка профи.. как прописан www.1post.ru, правильно ли код внутри сделан.....

Нужна оценка ПК и монитора
1. ПК (собирался самостоятельно, но не мной). Процессор - AMD Athlon II X4 640 (4 ядра, 3 ГГц)....

Нужна оценка сборки
Прочитав кучу форумов, решил собрать себе компьютер, получилось вот так:...

Нужна оценка сборки
Процессор Intel Core i5-9600K Coffee Lake (3700MHz, LGA1151 v2, L3 9216Kb) Материнская плата ASUS...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru