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

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

23.06.2014, 18:38. Показов 1437. Ответов 15
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Тихо едет не спеша, крыша шифером шурша.
В общем. Надо чтоб было игровое поле 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;
}
//------------------------
Гдето я запутался. И мозги не варят.... прошу подсказать идея или логика решения правильная? Может скорее всего где то синтаксическая или небольшая логическая ошибка.

ПРошу указать на ошибку а не давать решение задачи. Сам решить хочу. Спасибо)
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
23.06.2014, 18:38
Ответы с готовыми решениями:

Ошибка в програме Крестики-нолики
main.cpp #include &quot;KR.h&quot; using namespace std; int main() { RandomPlayer *r = new...

Игра Крестики-Нолики (Ошибка в коде)
Доброго времени суток. Не показывает победителя если комбинация по...

Крестики нолики
Всем доброе утро) Написал программу, только не могу найти там ошибку в проверке. Когда надо...

Крестики нолики
Доброго времени суток, недавно, я решил написать программу Крестики нолики, опираясь на свои знания...

15
1296 / 469 / 151
Регистрация: 24.08.2011
Сообщений: 2,249
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 (чтение строки и столбца - фактически одна функция), вроде норм, но в майне ничего не делается, так что ошибки и не можеть быть пока что
допиши майн, посмотрим
0
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
23.06.2014, 19:05 3
MMt, а вопрос-то, где вопрос?
Устраняйте дублирование (например, последние 2 метода можно легко объединить в один, и не только их). Меньше дублирования - меньше шансов совершить ошибку
1
31 / 31 / 32
Регистрация: 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' - буквы имеют одинаковую ширину и высоту и будут выглядеть аккуратнее.
0
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
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;
}
0
76 / 71 / 55
Регистрация: 17.05.2014
Сообщений: 301
23.06.2014, 20:16 6
MMt, хочу узнать, а зачем игроку нужно вводить свой символ и что бы программа проверяла? Достаточно ввести проверку на корректные координаты, а уж какой символ вписать, программа сама поймет
0
0 / 0 / 0
Регистрация: 29.04.2014
Сообщений: 185
23.06.2014, 20:44  [ТС] 7
да. блин я и в самом деле слишком заумно все делаю. хочу как понавороченней.
0
76 / 71 / 55
Регистрация: 17.05.2014
Сообщений: 301
23.06.2014, 21:01 8
MMt, сделайте тогда не ввод координат ячейки, а некий прицел, который будет перемещаться стрелочками с клавиатуры (подобие курсора мыши)
0
0 / 0 / 0
Регистрация: 29.04.2014
Сообщений: 185
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;
}
0
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
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;
}
совсем никуда не годится. Даже если работает
0
Модератор
Эксперт по электронике
8909 / 6678 / 918
Регистрация: 14.02.2011
Сообщений: 23,523
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";
0
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
24.06.2014, 01:20 12
ValeryS, посмотрите мой вариант, там еще проще Не надо перебирать все варианты. Достаточно просто посмотреть текущую строку и столбец матрицы. Мы можем победить, только поставив крестик (или нолик) в какую-то ячейку, причем эта проставленная ячейка будет частью победной строки или стролбца (или ничья).
0
Модератор
Эксперт по электронике
8909 / 6678 / 918
Регистрация: 14.02.2011
Сообщений: 23,523
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;
будет более оправдано
да и здесь можно цикл использовать
0
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
24.06.2014, 21:35 14
ValeryS, в С же вроде нет bool, а есть только макрос BOOL . А вводить его через typedef не вижу смысла же. Хотя могу ошибаться Привык, что булевский тип это int.
0
Модератор
Эксперт по электронике
8909 / 6678 / 918
Регистрация: 14.02.2011
Сообщений: 23,523
24.06.2014, 22:01 15
Цитата Сообщение от Psilon Посмотреть сообщение
ValeryS, в С же вроде нет bool,
ну, а мы то в каком разделе?
Цитата Сообщение от Psilon Посмотреть сообщение
#include <iostream>
using namespace std;
это вроде тоже из плюсов
1
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
24.06.2014, 22:35 16
ValeryS, да путаюсь в них
0
24.06.2014, 22:35
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.06.2014, 22:35
Помогаю со студенческими работами здесь

Крестики нолики 10 на 10
Нашел код крестики нолики 4 на 4 но не компилируется, там ошибки почему то в &lt;&lt; хочу сделать из...

Крестики нолики
Доброго времени суток, недавно я решил написать игру крестики нолики, написал, но код в ~1300...

Крестики-нолики
Всем привет и заранее спасибо, кто откликнется. Проблема следующая: игра работает почти корректно,...

крестики-нолики
Здравствуйте! у кого есть примеры программ крестики-нолики? если не затруднит поделитесь...


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

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