Форум программистов, компьютерный форум CyberForum.ru

Крестики Нолики. Где-то ошибка - C++

Восстановить пароль Регистрация
 
MMt
0 / 0 / 0
Регистрация: 29.04.2014
Сообщений: 168
23.06.2014, 18:38     Крестики Нолики. Где-то ошибка #1
Тихо едет не спеша, крыша шифером шурша.
В общем. Надо чтоб было игровое поле 3х3. Изначально заполнено каким то символом.
Игрок 1 вводит координаты - строка/столбец ячейки.
Игрок 1 вводит символ +/0. Программа проверяет и матюкается если он ввел не свой символ.

Рисуем поле. Все ячейки кроме введенных заполенны по умолчанию, какимто символом. Выбраная игроком ячейка заполнена + или 0.

Игрок 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
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include <iostream>
using namespace std;
 
 
//---------
    void PGShow(char PlayGr[3][3], char empty, int gT, int vT, char choice);
//-----------
    int TVer(int vT);
    int TGor(int gT);
//-----------
    char PlMoov1(char choice);
    char PlMoov2(char choice);
//-----------
 
 
int main() {
    //иниц. всех переменных.
    setlocale(0,"");
    char empty='X';
    char choice;
    char PlayGr[3][3];  
    int gT, vT;
    
    /*
    // заполнение массива пустыми значениями.
    for(int i=0; i<3;++i){
        for(int k=0; k<3; ++k)
            PlayGr[i][k]=empty;
    }*/
    
    
    return 0;
}
 
//----------------------------------------------
void PGShow(char PlayGr[3][3], char empty, int gT, int vT, char choice){ 
    
        // тут в массив с Х рисуем нужный символ.
        for(int i =0; i<3; ++i){            
            for(int k=0; k<3;++k){
                if (i == vT && k == gT)
                    PlayGr[i][k]=choice;
                
                cout    << PlayGr[i][k];
            }
            cout    <<endl;             
        }
                
        //рисуем массив и смотрим что получилось.
        for(int i=0; i<3;++i){
            
            for(int k=0; k<3;++k){
                cout    << PlayGr[i][k];
            }
            cout    <<endl;
        }
}
//--------------------------------------------
int  TGor(int gT){
    
        cout    <<"Введите строку с клeточкой: ";
        cin     >>gT;
        gT = gT-1; 
        
    return gT;
}
//-----------------------------------------
int  TVer (int vT){
        int val1;
        cout    <<"Введите столбик с клeточкой: ";
        cin     >>val1;
        vT = val1-1;        
    return vT;
};
//----------------------------------------------------------------
char PlMoov1(char choice){
    cout    << "Ходит игрок №1. Игрок ставит 0 : ";
    
    for(int i =0; choice != '0'; i++){
        cin     >> choice;
        
        if(choice != '0')
            cout    << "Вы должны ввести только (0 нуль). \n";
        
        else if(choice == '0')
            choice = '0';
    }
    
    return choice;
}
//-------------------------
char PlMoov2(char choice){
    cout    << "Ходит игрок №2. Игрок ставит + : ";
    
    for(int i =0; choice != '+'; i++){
        cin     >> choice;
        if(choice != '+')
            cout    << "Вы должны ввести только (+ плюс). \n";
        
        else if(choice == '+')
            choice = '+';
    }
    
    return choice;
}
//------------------------
Гдето я запутался. И мозги не варят.... прошу подсказать идея или логика решения правильная? Может скорее всего где то синтаксическая или небольшая логическая ошибка.

ПРошу указать на ошибку а не давать решение задачи. Сам решить хочу. Спасибо)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.06.2014, 18:38     Крестики Нолики. Где-то ошибка
Посмотрите здесь:

C++ Крестики нолики
C++ Крестики Нолики
C++ Крестики нолики
Ошибка в програме Крестики-нолики C++
C++ крестики-нолики
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Керра
Модератор
 Аватар для Керра
1270 / 438 / 45
Регистрация: 24.08.2011
Сообщений: 2,123
23.06.2014, 19:04     Крестики Нолики. Где-то ошибка #2
C++
1
2
3
4
5
    int TVer(int vT);
    int TGor(int gT);
//-----------
    char PlMoov1(char choice);
    char PlMoov2(char choice);
что должны принимать и возвращать эти функции? может быть они должны менять значения?

вообще по сути-то зачем игрок должен вводить свой значок? игрок №1 ставит допустим крестик, игрок №2 ставит нолик. зачем у них еще это спрашивать, если и так понятно кто что ставит?

за исключением того, что можно было бы сделать красивее и рациональнее, и не разбивать функции на 2 (чтение строки и столбца - фактически одна функция), вроде норм, но в майне ничего не делается, так что ошибки и не можеть быть пока что
допиши майн, посмотрим
Psilon
Master of Orion
 Аватар для Psilon
5737 / 4685 / 619
Регистрация: 10.07.2011
Сообщений: 14,160
Записей в блоге: 5
Завершенные тесты: 4
23.06.2014, 19:05     Крестики Нолики. Где-то ошибка #3
MMt, а вопрос-то, где вопрос?
Устраняйте дублирование (например, последние 2 метода можно легко объединить в один, и не только их). Меньше дублирования - меньше шансов совершить ошибку
BatonPro
30 / 30 / 24
Регистрация: 21.06.2014
Сообщений: 81
23.06.2014, 19:08     Крестики Нолики. Где-то ошибка #4
Идея у Вас правильная, логика хромает. В любом случае тяжело оценивать только несколько функций, которые только написаны и не используются.

Цитата Сообщение от MMt Посмотреть сообщение
Игрок 1 вводит символ +/0. Программа проверяет и матюкается если он ввел не свой символ.
Зачем при ходе вводить символ, ведь в крестиках-ноликах первый игрок всегда ставит 'X', а второй 'О'.

C++
1
char empty='X';
Если пустые клеточки выводить как Х - игровое поле будет нечитабельным. Логичнее сделать их пробелом
C++
1
char empty=' ';

А вот как раз сами крестики и нолики логичнее сделать буквами 'X' и 'O' - в отличии от варианта '+' и '0' - буквы имеют одинаковую ширину и высоту и будут выглядеть аккуратнее.
Psilon
Master of Orion
 Аватар для Psilon
5737 / 4685 / 619
Регистрация: 10.07.2011
Сообщений: 14,160
Записей в блоге: 5
Завершенные тесты: 4
23.06.2014, 19:37     Крестики Нолики. Где-то ошибка #5
Вот мое виденье, в плюсах я не очень шарю, так что просьба не бить ногами
Кликните здесь для просмотра всего текста
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
#include <iostream>
 
using namespace std;
 
 
const int N = 3;
const char Empty = '-';
char map[N][N];
 
void ClearMap();
void DrawMap();
int Turn(const char*, char);
int Win(int, int, char);
 
int main()
{
    ClearMap(); 
    int i = 0;
    for (; i < 9 && !(Turn("Player 1", 'X') || Turn("Player 2", '0')); i++)
    {
    }
    if (i == 9)
        cout << "DRAW!" << endl;
    return 0;
}
 
void ClearMap()
{
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            map[i][j] = Empty;
}
 
void DrawMap()
{
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
            cout << '|' << map[i][j];
        cout << '|' << endl;
    }
}
 
int Turn(const char* playername, char symbol)
{
    int x, y;
    DrawMap();
    cout << playername << "'s turn. Enter coordinates X and Y" << endl;
    cin >> x >> y;
    while (x < 0 || y < 0 || x > 3 || y > 3 || map[x][y] != Empty)
    {
        cout << "Invalid coordinates. Try again" << endl;
        cin >> x >> y;
    }
    map[x][y] = symbol;
    int win = Win(x, y, symbol);
    if (win)
        cout << playername << " WIN!" << endl;
    return win;
}
 
int Win(int x, int y, char symbol)
{
    //проверяем горизонталь
    int i;
    for (i = 0; i < 3 && map[i][y] == symbol; i++)
    {
    }
    if (i == 3)
        return 1;
    //проверяем вертикаль
    for (i = 0; i < 3 && map[x][i] == symbol; i++)
    {
    }
    if (i == 3)
        return 1;
    //возвращаем диагонали
    return map[0][0] == symbol && map[1][1] == symbol && map[2][2] == symbol
        || map[0][2] == symbol && map[1][1] == symbol && map[2][0] == symbol;
}
Хедин
 Аватар для Хедин
73 / 68 / 36
Регистрация: 17.05.2014
Сообщений: 301
23.06.2014, 20:16     Крестики Нолики. Где-то ошибка #6
MMt, хочу узнать, а зачем игроку нужно вводить свой символ и что бы программа проверяла? Достаточно ввести проверку на корректные координаты, а уж какой символ вписать, программа сама поймет
MMt
0 / 0 / 0
Регистрация: 29.04.2014
Сообщений: 168
23.06.2014, 20:44  [ТС]     Крестики Нолики. Где-то ошибка #7
да. блин я и в самом деле слишком заумно все делаю. хочу как понавороченней.
Хедин
 Аватар для Хедин
73 / 68 / 36
Регистрация: 17.05.2014
Сообщений: 301
23.06.2014, 21:01     Крестики Нолики. Где-то ошибка #8
MMt, сделайте тогда не ввод координат ячейки, а некий прицел, который будет перемещаться стрелочками с клавиатуры (подобие курсора мыши)
MMt
0 / 0 / 0
Регистрация: 29.04.2014
Сообщений: 168
23.06.2014, 23:38  [ТС]     Крестики Нолики. Где-то ошибка #9
потом. сделаю когда разберусь с логикой от рисовки и ввода с координат.

Добавлено через 13 минут
Промежуточный вариант. Сейчас буду дописывать очищение консоли и возможно выбор ячейки с помощью курсора.

Есть замечания по логике или коду?
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
#include <iostream>
using namespace std;
 
 
 
void draw_Field(char Field[3][3],char choice, int gor_cell, int ver_cell);
int main() {
    setlocale(0,"");
    char Field[3][3];
    char choice, empty = '.';
    int ver_cell, gor_cell;
    
    //инициализация массива
    for(int i=0; i<3;++i){
        for(int k=0; k<3; ++k){
            Field[i][k]= empty;
        }
    }
    //заполнение массива
    for(int i=0; i<3;++i){
        for(int k=0; k<3; ++k){
            cout    << Field[i][k];
        }
        cout    << endl;
    }
    
    //цикл в 9 ходов где игроки будуи вводить координаты.
    for(int z=0; z<9; ++z){
        int fver_cell, fgor_cell;
        
        cout    << "Игрок 1 введите координаты (Х). Строка/Столбик от 1 до 3... ";
        cin     >> fver_cell    >> fgor_cell;
        
        ver_cell = fver_cell-1;
        gor_cell = fgor_cell-1;
        
        choice = 'X';
        
        draw_Field(Field, choice, gor_cell, ver_cell);
        
        cout    << "Игрок 2 введите координаты (0). Строка/Столбик от 1 до 3... ";
        cin     >> fver_cell    >> fgor_cell;
        
        ver_cell = fver_cell-1;
        gor_cell = fgor_cell-1;
        
        choice = '0';
        
        draw_Field(Field, choice, gor_cell, ver_cell);
        
    }
    
    
    
    
    
    
    
    
 
 
    return 0;
}
 
void draw_Field(char Field[3][3], char choice, int gor_cell, int ver_cell){
    
    for(int i=0; i<3; ++i){
        for(int k=0; k<3; ++k){
            if(gor_cell == k && ver_cell == i)
                Field[i][k] = choice;
            cout    << Field[i][k];
        }
        cout    << endl;
    }
}
Добавлено через 2 часа 1 минуту
решил сделать проверку на победу или поражение. правльная логика? или я снова "мудрю"

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
    for(int i=0; i<3; ++i){
            for(int k=0; k<3; ++k){
                if( Field[0][0]='X' &&
                    Field[0][1]='X' &&
                    Field[0][2]='X')
                    
                    res = "Èãðîê 1 âûèãðГ*Г«!\n \n";
                
                else if(Field[1][0]='X' &&
                        Field[1][1]='X' &&
                        Field[1][2]='X')
                        res =  "Èãðîê 1 âûèãðГ*Г«!\n \n";
                
                else if(Field[2][0]='X' &&
                        Field[2][1]='X' &&
                        Field[2][2]='X')
                        res =  "Èãðîê 1 âûèãðГ*Г«!\n \n";     
                
                else if(Field[0][1]='X' &&
                        Field[1][1]='X' &&
                        Field[2][1]='X')
                        res =  "Èãðîê 1 âûèãðГ*Г«!\n \n";
                        
                else if(Field[0][2]='X' &&
                        Field[1][2]='X' &&
                        Field[2][2]='X')
                        res =  "Èãðîê 1 âûèãðГ*Г«!\n \n"; 
                        
                else if(Field[2][0]='X' &&
                        Field[1][1]='X' &&
                        Field[0][2]='X')
                        res =  "Èãðîê 1 âûèãðГ*Г«!\n \n"; 
                
                else if(Field[0][0]='X' &&
                        Field[1][1]='X' &&
                        Field[2][2]='X')
                        res =  "Èãðîê 1 âûèãðГ*Г«!\n \n"; 
                
                else if(Field[0][0]='0' &&
                        Field[0][1]='0' &&
                        Field[0][2]='0')
                        res =  "Èãðîê 2 âûèãðГ*Г«!\n \n";
                
                else if(Field[1][0]='0' &&
                        Field[1][1]='0' &&
                        Field[1][2]='0')
                        res =  "Èãðîê 2 âûèãðГ*Г«!\n \n";
                
                else if(Field[2][0]='0' &&
                        Field[2][1]='0' &&
                        Field[2][2]='0')
                        res =  "Èãðîê 2 âûèãðГ*Г«!\n \n";     
                
                else if(Field[0][1]='0' &&
                        Field[1][1]='0' &&
                        Field[2][1]='0')
                        res =  "Èãðîê 2 âûèãðГ*Г«!\n \n";
                        
                else if(Field[0][2]='0' &&
                        Field[1][2]='0' &&
                        Field[2][2]='0')
                        res =  "Èãðîê 2 âûèãðГ*Г«!\n \n"; 
                        
                else if(Field[2][0]='0' &&
                        Field[1][1]='0' &&
                        Field[0][2]='0')
                        res =  "Èãðîê 2 âûèãðГ*Г«!\n \n"; 
                
                else if(Field[0][0]='0' &&
                        Field[1][1]='0' &&
                        Field[2][2]='0')
                        res =  "Èãðîê 2 âûèãðГ*Г«!\n \n";
                else 
                        res =  "ГЌГЁГ·ГјГї!";
            }
                        
        }
        return res;
}
Psilon
Master of Orion
 Аватар для Psilon
5737 / 4685 / 619
Регистрация: 10.07.2011
Сообщений: 14,160
Записей в блоге: 5
Завершенные тесты: 4
24.06.2014, 00:20     Крестики Нолики. Где-то ошибка #10
MMt, дублирование, плохо. Удаляйте
Не хвастаюсь,просто посмотрите мой вариант, там дублирования нет или практически нет. Просто оцените, что можно вынести в отдельные функции, а то вот это например:
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
for(int i=0; i<3; ++i){
            for(int k=0; k<3; ++k){
                if( Field[0][0]='X' &&
                    Field[0][1]='X' &&
                    Field[0][2]='X')
                    
                    res = "Игрок 1 выиграл!\n \n";
                
                else if(Field[1][0]='X' &&
                        Field[1][1]='X' &&
                        Field[1][2]='X')
                        res =  "Игрок 1 выиграл!\n \n";
                
                else if(Field[2][0]='X' &&
                        Field[2][1]='X' &&
                        Field[2][2]='X')
                        res =  "Игрок 1 выиграл!\n \n";     
                
                else if(Field[0][1]='X' &&
                        Field[1][1]='X' &&
                        Field[2][1]='X')
                        res =  "Игрок 1 выиграл!\n \n";
                        
                else if(Field[0][2]='X' &&
                        Field[1][2]='X' &&
                        Field[2][2]='X')
                        res =  "Игрок 1 выиграл!\n \n"; 
                        
                else if(Field[2][0]='X' &&
                        Field[1][1]='X' &&
                        Field[0][2]='X')
                        res =  "Игрок 1 выиграл!\n \n"; 
                
                else if(Field[0][0]='X' &&
                        Field[1][1]='X' &&
                        Field[2][2]='X')
                        res =  "Игрок 1 выиграл!\n \n"; 
                
                else if(Field[0][0]='0' &&
                        Field[0][1]='0' &&
                        Field[0][2]='0')
                        res =  "Игрок 2 выиграл!\n \n";
                
                else if(Field[1][0]='0' &&
                        Field[1][1]='0' &&
                        Field[1][2]='0')
                        res =  "Игрок 2 выиграл!\n \n";
                
                else if(Field[2][0]='0' &&
                        Field[2][1]='0' &&
                        Field[2][2]='0')
                        res =  "Игрок 2 выиграл!\n \n";     
                
                else if(Field[0][1]='0' &&
                        Field[1][1]='0' &&
                        Field[2][1]='0')
                        res =  "Игрок 2 выиграл!\n \n";
                        
                else if(Field[0][2]='0' &&
                        Field[1][2]='0' &&
                        Field[2][2]='0')
                        res =  "Игрок 2 выиграл!\n \n"; 
                        
                else if(Field[2][0]='0' &&
                        Field[1][1]='0' &&
                        Field[0][2]='0')
                        res =  "Игрок 2 выиграл!\n \n"; 
                
                else if(Field[0][0]='0' &&
                        Field[1][1]='0' &&
                        Field[2][2]='0')
                        res =  "Игрок 2 выиграл!\n \n";
                else 
                        res =  "Ничья!";
            }
                        
        }
        return res;
}
совсем никуда не годится. Даже если работает
ValeryS
Модератор
6373 / 4839 / 440
Регистрация: 14.02.2011
Сообщений: 16,038
24.06.2014, 00:31     Крестики Нолики. Где-то ошибка #11
Цитата Сообщение от MMt Посмотреть сообщение
C++
1
2
3
4
5
6
  if( Field[0][0]='X' &&
                    Field[0][1]='X' &&
                    Field[0][2]='X')
                    
                    res = "Игрок 1 выиграл!\n \n";
           ;

с символами удобней работать человеку
машине удобней работать с числами
посему делай как ей удобней, ей же считать
например в пустых клетках 0 если нолик то -1 если крестик то 1
твоя проверка сведется к обычному сложению
C++
1
2
3
4
5
summ= Field[0][0]+ Field[0][1]+ Field[0][2];
if(summ==3)
  res = "Игрок 1 выиграл!\n \n";
if(summ==-3)
 res = "Игрок 2 выиграл!\n \n";
Psilon
Master of Orion
 Аватар для Psilon
5737 / 4685 / 619
Регистрация: 10.07.2011
Сообщений: 14,160
Записей в блоге: 5
Завершенные тесты: 4
24.06.2014, 01:20     Крестики Нолики. Где-то ошибка #12
ValeryS, посмотрите мой вариант, там еще проще Не надо перебирать все варианты. Достаточно просто посмотреть текущую строку и столбец матрицы. Мы можем победить, только поставив крестик (или нолик) в какую-то ячейку, причем эта проставленная ячейка будет частью победной строки или стролбца (или ничья).
ValeryS
Модератор
6373 / 4839 / 440
Регистрация: 14.02.2011
Сообщений: 16,038
24.06.2014, 07:19     Крестики Нолики. Где-то ошибка #13
Цитата Сообщение от Psilon Посмотреть сообщение
Мы можем победить, только поставив крестик (или нолик) в какую-то ячейку,
ну, так и в живую так жу
или ты имеешь ввиду цикл использовать?
это так скажем второй слой подсказок
или что я использовал -1 и 1,?
ну это один из вариантов решения, причем лежавший на поверхности
Цитата Сообщение от Psilon Посмотреть сообщение
int Win(int x, int y, char symbol)
не проще ли использовать здесь тип bool
тогда
Цитата Сообщение от Psilon Посмотреть сообщение
return map[0][0] == symbol && map[1][1] == symbol && map[2][2] == symbol
* * * * || map[0][2] == symbol && map[1][1] == symbol && map[2][0] == symbol;
будет более оправдано
да и здесь можно цикл использовать
Psilon
Master of Orion
 Аватар для Psilon
5737 / 4685 / 619
Регистрация: 10.07.2011
Сообщений: 14,160
Записей в блоге: 5
Завершенные тесты: 4
24.06.2014, 21:35     Крестики Нолики. Где-то ошибка #14
ValeryS, в С же вроде нет bool, а есть только макрос BOOL . А вводить его через typedef не вижу смысла же. Хотя могу ошибаться Привык, что булевский тип это int.
ValeryS
Модератор
6373 / 4839 / 440
Регистрация: 14.02.2011
Сообщений: 16,038
24.06.2014, 22:01     Крестики Нолики. Где-то ошибка #15
Цитата Сообщение от Psilon Посмотреть сообщение
ValeryS, в С же вроде нет bool,
ну, а мы то в каком разделе?
Цитата Сообщение от Psilon Посмотреть сообщение
#include <iostream>
using namespace std;
это вроде тоже из плюсов
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.06.2014, 22:35     Крестики Нолики. Где-то ошибка
Еще ссылки по теме:

C++ крестики нолики
C++ Крестики-нолики
Крестики-нолики C++

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

Или воспользуйтесь поиском по форуму:
Psilon
Master of Orion
 Аватар для Psilon
5737 / 4685 / 619
Регистрация: 10.07.2011
Сообщений: 14,160
Записей в блоге: 5
Завершенные тесты: 4
24.06.2014, 22:35     Крестики Нолики. Где-то ошибка #16
ValeryS, да путаюсь в них
Yandex
Объявления
24.06.2014, 22:35     Крестики Нолики. Где-то ошибка
Ответ Создать тему
Опции темы

Текущее время: 01:43. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru