0 / 0 / 0
Регистрация: 10.04.2017
Сообщений: 1
1

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

16.04.2017, 03:11. Показов 774. Ответов 0
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте, форумчане! Прошу у экспертов помощи в улучшении кода. Недавно перешёл на C/C++, задался идеей переписать на C++ свои старые игрушки на других языках. С интерактивным меню для теста на зека и простейшей текстовой игрой "Угадай число" проблем не возникло. И вот уже решена третья задача - написание "Крестиков-ноликов", но здесь я решил улучшить свой старый алгоритм, сделать игру компьютера разумнее. Код компилируется, ошибок и вылетов не возникает, однако очень хотелось бы получить советы по рефакторингу и вообще экспертное мнение со стороны. Хороший ли алгоритм или надо дальше думать над стратегией игры, не лишнего ли памяти задействовано и т.д. Может, у кого-то есть общие рекомендации, пожалуйста, говорите) Да, тут нет ни одного объекта, потому что я нз какие именно классы правильнее создать, думаю, это должен быть объект игрового поля (где что стоит и рейтинги) и класс игрока с двумя объектами (координаты, метод вывода символов, кто ходит, кто выиграл и т.д.), но смутно представляю себе всю эту картину. И объявление с реализацией хранятся в одном файле, да, мне так проще. Функции Pick() и frame() - это меню и "фрейм", они хранится с моём хейдере visualcon.h, с ним всё норм, тоже прилагаются ниже. Знаю, что реализацию функций надо выносить, сильно не бейте. Принимаю любые тапки, жесткие и мягкие. Код, вроде, понятен, если есть вопросы, задавайте. Хорошего дня

main.cpp
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>
#include <string>
#include <stdio.h>
#include <windows.h>
#include <time.h>
#include "C:/dev/gamedev/visualcon.h"
#include "game.h"
using namespace std;
 
string List[3] = {"Крестики", "Нолики", "Выход"};
int Zone[10], Line[8];
 
void marking( int pos1, int pos2, int pos3, int pos4 )
{
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD Pos;
    system("chcp 866 > nul");
    
    Pos.X = 0;  Pos.Y = pos1;
    SetConsoleCursorPosition( hConsole, Pos );
    cout << char(199);
    for (int x = 0; x < 50; x++)
        cout << char(196);
    cout << char(182);
    
    Pos.Y = pos2;
    SetConsoleCursorPosition( hConsole, Pos );
    cout << char(199);
    for (int x = 0; x < 50; x++)
        cout << char(196);
    cout << char(182);
    
    Pos.Y = 0;  Pos.X = pos3;
    SetConsoleCursorPosition( hConsole, Pos );
    cout << char(209);
    for (int y = 0; y < 30; y++) {
        Pos.Y++;  SetConsoleCursorPosition( hConsole, Pos );
        cout << char(179);
    }
    SetConsoleCursorPosition( hConsole, Pos );
    cout << char(207);  
 
    Pos.Y = 0;  Pos.X = pos4;
    SetConsoleCursorPosition( hConsole, Pos );
    cout << char(209);
    for (int y = 0; y < 30; y++) {
        Pos.Y++;  SetConsoleCursorPosition( hConsole, Pos );
        cout << char(179);
    }
    SetConsoleCursorPosition( hConsole, Pos );
    cout << char(207);  
    
    Pos.Y = pos1;  Pos.X = pos3;
    SetConsoleCursorPosition( hConsole, Pos );
    cout << char(197);
    Pos.Y = pos2;
    SetConsoleCursorPosition( hConsole, Pos );
    cout << char(197);
    Pos.X = pos4;
    SetConsoleCursorPosition( hConsole, Pos );
    cout << char(197);
    Pos.Y = pos1;
    SetConsoleCursorPosition( hConsole, Pos );
    cout << char(197);
    
    system("chcp 1251 > nul");  
}
 
int main( int argc, char** argv ) 
{
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD Pos;
    int who, res;
    AllocConsole();
    system("chcp 1251 > nul");
    system("mode con: cols=52 lines=32");
    srand(time(0));
    
    while(1) {
        system("cls");
        showCur(0);
 
        frame( -1, 0, 53, 32, 0, 14, "OXO" );
        cout << "Кем будете играть?" << endl;
        who = Pick( List, 3 );
        if (who == 2)
            return 0;
        frame( 0, 0, 52, 31, 13, 0, "OXO" );
        marking( 10, 20, 17, 34 );
    
        for (int i = 0; i < 8; i++)
            Line[i] = 0;
        for (int i = 1; i < 10; i++)
            Zone[i] = 'Y';
        res = game(who);
    
        Pos.X = 20;  Pos.Y = 31;
        SetConsoleCursorPosition( hConsole, Pos );
        if ( res == 0 )  cout << "Вы выиграли";
        else if ( res == 1 ) cout << "Я выиграл";
        else cout << "Ничья";
    
        getch();
    }
    return 0;
}
game.h
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
#ifndef game_H
#define game_H
 
using namespace std;
extern int Zone[10], Line[8];
 
void drawZn( int zn, COORD Pos )
{   
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    if (zn == 'X') {
        Pos.X -= 2;  Pos.Y -= 3;
        SetConsoleCursorPosition( hConsole, Pos );
        cout << "0    0";
        Pos.Y++;  SetConsoleCursorPosition( hConsole, Pos );
        cout << " 0  0 ";
        Pos.Y++;  SetConsoleCursorPosition( hConsole, Pos );
        cout << "  00  ";
        Pos.Y++;  SetConsoleCursorPosition( hConsole, Pos );
        cout << "  00  ";
        Pos.Y++;  SetConsoleCursorPosition( hConsole, Pos );
        cout << " 0  0  ";
        Pos.Y++;  SetConsoleCursorPosition( hConsole, Pos );
        cout << "0    0";
    }
    else {
        Pos.X -= 2;  Pos.Y -= 3;
        SetConsoleCursorPosition( hConsole, Pos );
        cout << "  00  ";
        Pos.Y++;  SetConsoleCursorPosition( hConsole, Pos );
        cout << " 0  0 ";
        Pos.Y++;  SetConsoleCursorPosition( hConsole, Pos );
        cout << "0    0";
        Pos.Y++;  SetConsoleCursorPosition( hConsole, Pos );
        cout << "0    0";
        Pos.Y++;  SetConsoleCursorPosition( hConsole, Pos );
        cout << " 0  0  ";
        Pos.Y++;  SetConsoleCursorPosition( hConsole, Pos );
        cout << "  00  ";
        
    }
}
 
int stepHum(COORD &Pos)
{
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    int step = 0;
    while (Zone[step] != 'Y')
        step = getch() - 48;
    switch(step)
    {
    case 1:     Pos.X = 8;  Pos.Y = 25;  
                Line[0]++;  Line[3]++;  Line[6]++;
                break;
    case 2:     Pos.X = 25;  Pos.Y = 25;  
                Line[0]++;  Line[4]++;
                break;
    case 3:     Pos.X = 42;  Pos.Y = 25;  
                Line[0]++;  Line[5]++;  Line[7]++;
                break;
    case 4:     Pos.X = 8;  Pos.Y = 15;
                Line[1]++;  Line[3]++;
                break;
    case 5:     Pos.X = 25;  Pos.Y = 15;  
                Line[1]++;  Line[4]++;  Line[6]++;  Line[7]++;
                break;
    case 6:     Pos.X = 42;  Pos.Y = 15;  
                Line[1]++;  Line[5]++;
                break;
    case 7:     Pos.X = 8;  Pos.Y = 5;  
                Line[2]++;  Line[3]++;  Line[7]++;
                break;
    case 8:     Pos.X = 25;  Pos.Y = 5;  
                Line[2]++;  Line[4]++;
                break;
    case 9:     Pos.X = 42;  Pos.Y = 5;
                Line[2]++;  Line[5]++;  Line[6]++;
                break;
    default:    Pos.X = 1;  Pos.Y = 31;
                SetConsoleCursorPosition( hConsole, Pos );
                cout << "error" << endl;
                break;
    };
    return step;
}
 
int findLine(int i)
{
    int step;
    switch(i)
    {
    case 0: case 1: case 2:
        for (step = 3 * i + 1; Zone[step] != 'Y'; step++)
            ;
        break;
    case 3: case 4: case 5:
        for (step = i - 3 + 1; Zone[step] != 'Y'; step += 3)
            ;
        break;                      
    case 6:
        for (step = 1; Zone[step] != 'Y'; step += 4)
            ;
        break;
    case 7:
        for (step = 3; Zone[step] != 'Y'; step += 2)
            ;
        break;
    default: cout << "error";  break;
    };
    return step;
}
 
int stepCom(COORD &Pos)
{
    int step = 0;
    
//  Проверка на допустимость выигрыша:    
    for (int i = 0; i < 8 && step == 0; i++)
        if (Line[i] < -1) {
            step = findLine(i);
        }   
        
//  Проверка на заполненность линий противником:
    if (step == 0)
        for (int i = 0; i < 8 && step == 0; i++)
            if (Line[i] > 1) {
                step = findLine(i);
            }
     
//  В произвольной ситуации:
    int f = 1;
    if (step == 0) {
        step = 0;
        while ( (Zone[step] != 'Y') || (f == 1) ) {
            f = 0;
            step = rand() % 9 + 1;
            switch(step)
            {
            case 1: if (Line[0] + Line[3] + Line[6] > 2)  f = 1;            break;
            case 2: if (Line[0] + Line[4] > 1)  f = 1;                      break;
            case 3: if (Line[0] + Line[5] + Line[7] > 2)  f = 1;            break;
            case 4: if (Line[1] + Line[3] > 1)  f = 1;                      break;
            case 5: if (Line[1] + Line[4] + Line[6] + Line[7] > 3)  f = 1;  break;
            case 6: if (Line[1] + Line[5] > 1)  f = 1;                      break;
            case 7: if (Line[2] + Line[3] + Line[7] > 2)  f = 1;            break;
            case 8: if (Line[2] + Line[4] > 1)  f = 1;                      break;
            case 9: if (Line[2] + Line[5] + Line[6] > 2)  f = 1;            break;
            };
        }
    }
    
//  Изменение позиций и рейтингов:
    switch(step)
    {
    case 1: Line[0]--;  Line[3]--;  Line[6]--;
            Pos.X = 8;  Pos.Y = 25;
            break;
    case 2: Line[0]--;  Line[4]--;
            Pos.X = 25;  Pos.Y = 25;
            break;
    case 3: Line[0]--;  Line[5]--;  Line[7]--;
            Pos.X = 42;  Pos.Y = 25;
            break;
    case 4: Line[1]--;  Line[3]--;
            Pos.X = 8;  Pos.Y = 15;
            break;
    case 5: Line[1]--;  Line[4]--;  Line[6]--;  Line[7]--;
            Pos.X = 25;  Pos.Y = 15;
            break;
    case 6: Line[1]--;  Line[5]--;
            Pos.X = 42;  Pos.Y = 15;
            break;
    case 7: Line[2]--;  Line[3]--;  Line[7]--;
            Pos.X = 8;  Pos.Y = 5;
            break;
    case 8: Line[2]--;  Line[4]--;
            Pos.X = 25;  Pos.Y = 5;
            break;
    case 9: Line[2]--;  Line[5]--;  Line[6]--;
            Pos.X = 42;  Pos.Y = 5;
            break;
    };
    
    return step;
}
 
int game(int who)
{
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    int get, step;
    COORD Pos;
    char zn = 'X';                                      
    showCur(0);
    step = 0;  Zone[step] = 'O';
    for (int l = 0; l < 9; l++) {   
        step = who == 0 ? stepHum(Pos) : stepCom(Pos);
        if (who == 0)
            SetConsoleTextAttribute( hConsole, (WORD) ((0 << 4) | 10) );
        else
            SetConsoleTextAttribute( hConsole, (WORD) ((0 << 4) | 15) );
        
        SetConsoleCursorPosition( hConsole, Pos );
        drawZn( zn, Pos );
        Zone[step] = who;
 
        SetConsoleTextAttribute( hConsole, (WORD) ((0 << 4) | 13) );
        if ( (Line[0] > 2) || (Line[1] > 2) || (Line[2] > 2) || (Line[3] > 2) || (Line[4] > 2) || (Line[5] > 2) || (Line[6] > 2) || (Line[7] > 2) )
            return 0;
        else if ( (Line[0] < -2) || (Line[1] < -2) || (Line[2] < -2) || (Line[3] < -2) || (Line[4] < -2) || (Line[5] < -2) || (Line[6] < -2) || (Line[7] < -2) )
            return 1;
        who = who == 0 ? 1 : 0;
        zn = zn == 'X' ? 'O' : 'X';
    }
    return 2;   //  ничья
}
 
#endif;
Вырезки из visualcon.h
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
void showCur( int show )
{
    CONSOLE_CURSOR_INFO Cur;
    if( show == 0 ) {
        Cur.bVisible = FALSE;
        Cur.dwSize = 1;
    }
    else {
        Cur.bVisible = TRUE;
        Cur.dwSize = show;
    }
    SetConsoleCursorInfo( GetStdHandle(STD_OUTPUT_HANDLE), &Cur );
}
 
void frame( int x0, int y0, int sizeX, int sizeY, int color, int backColor, string name = "ITMM" )
{
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute( hConsole, (WORD) ((backColor << 4) | color) );
    COORD Pos;
    if( x0 > -1 )  Pos.X = x0;
    else Pos.X = 0;
    if( y0 > -1 )  Pos.Y = y0;
    else Pos.Y = 0;
    SetConsoleCursorPosition( hConsole, Pos );
    int x1 = x0 + sizeX - 1;
    int y1 = y0 + sizeY - 1;
    x0++;  y0++;
    system("chcp 866 > nul");
 
    if( y0 > 0 ) {
        if( x0 > 0 )
            cout << char(201);
        for( int x = x0; x < x1; x++ )
            cout << char(205);
        cout << "&";
        if( (sizeX > name.size()) && (sizeX + x0 > name.size() + 1) ) {
            if( x0 > 0 )  Pos.X = x0;
            else Pos.X = 1;
            SetConsoleCursorPosition( hConsole, Pos );
            system("chcp 1251 > nul");
            cout << name;
            system("chcp 866 > nul");
            if( x0 > 0 )  Pos.X = x0 - 1;
            else Pos.X = 0;
            SetConsoleCursorPosition( hConsole, Pos );
        }
    }
    else Pos.Y = -1;
 
    Pos.Y++;  SetConsoleCursorPosition( hConsole, Pos );
    for( int y = y0; y < y1; y++ ) {
        if( x0 > 0 )
            cout << char(186);
        for( int x = x0; x < x1; x++ )
            cout << " ";
        cout << char(186);
        Pos.Y++;  SetConsoleCursorPosition( hConsole, Pos );
    }
 
    if( x0 > 0)
        cout << char(200);
    for( int x = x0; x < x1; x++ )
        cout << char(205);
    cout << char(188);
 
    system("chcp 1251 > nul");
    Pos.X = x0;  Pos.Y = y0;
    SetConsoleCursorPosition( hConsole, Pos );
    cin.sync();
}
 
int Pick( string LIST[], int np )
{   system("chcp 1251 > nul");
    np--;
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    int color, backColor;
    color = getColor();
    backColor = getBackColor();
    int p = 0;  char c = NULL;  COORD Pos;
    int x0, y0;  getCurPos( &x0, &y0 );
    Pos.X = x0;  Pos.Y = y0;
 
    SetConsoleTextAttribute( hConsole, (WORD) ((BACK_COLOR_PICK << 4) | TEXT_COLOR_PICK) );
    cout << ">" << LIST[0] << endl;
    Pos.Y++;
    SetConsoleTextAttribute( hConsole, (WORD) ((BACK_COLOR << 4) | TEXT_COLOR) );
    for( int i = 1; i < np+1; i++ )  {
        SetConsoleCursorPosition( hConsole, Pos );
        cout << " " << LIST[i] << endl;
        Pos.Y++;
    }
    showCur(0);
 
    while( (c != 13) && (c != ' ') )
    {
        c = getch();
        Pos.Y = y0 + p;
        SetConsoleCursorPosition( hConsole, Pos );
        SetConsoleTextAttribute( hConsole, (WORD) ((BACK_COLOR << 4) | TEXT_COLOR) );
        cout << " " << LIST[p] << endl;
        
        if ( (c - 48 < 10) &&  (c - 48 > np + 1) ) {
            cout << "error" << endl;
            p = Pick( LIST, np + 1 );
            c = 13;
        }
 
        switch(c)
        {
            case 72:    p--;            break;
            case 75:    p--;            break;
            case 77:    p++;            break;
            case 80:    p++;            break;
            case '1':   p = 0;  c = 13; break;
            case '2':   p = 1;  c = 13; break;
            case '3':   p = 2;  c = 13; break;
            case '4':   p = 3;  c = 13; break;
            case '5':   p = 4;  c = 13; break;
            case '6':   p = 5;  c = 13; break;
            case '7':   p = 6;  c = 13; break;
            case '8':   p = 7;  c = 13; break;
            case '9':   p = 8;  c = 13; break;
            case '0':   p = np; c = 13; break;
            case 27:    p = np; c = 13; break;
        }
        if( p == -1 )   p = np;
        if( p == np + 1 )   p = 0;
 
        Pos.Y = y0 + p;
        SetConsoleCursorPosition( hConsole, Pos );
        SetConsoleTextAttribute( hConsole, (WORD) ((BACK_COLOR_PICK << 4) | TEXT_COLOR_PICK) );
        cout << ">" << LIST[p] << endl;
        SetConsoleTextAttribute( hConsole, (WORD) ((BACK_COLOR << 4) | TEXT_COLOR) );
        Pos.Y = y0 + np + 1;
        SetConsoleCursorPosition( hConsole, Pos );
    }
    SetConsoleTextAttribute( hConsole, (WORD) ((color << 4) | backColor) );
    return p;
}
Добавлено через 8 минут
з.ы. Ещё не разобрался с разделами на киберфоруме. Надеюсь, админы простят косяки.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.04.2017, 03:11
Ответы с готовыми решениями:

Крестики-нолики
Помогите пожалуйста создать игру крестики-нолики на 2 игроков, поле игры - массив 3х3. Нашла...

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

Крестики Нолики
Прошу помочь, я написал игру крестики нолики, но при вводе. Выводится только крестик. ПОмогите. Не...

Крестики-нолики
Ребят! Как сделать проверку на занятость квадратика? #include &lt;iostream&gt; using namespace...

0
16.04.2017, 03:11
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
16.04.2017, 03:11
Помогаю со студенческими работами здесь

Крестики нолики
Здравствуйте. Я сделал программу позволяющую играть в крестики-нолики. Можете помочь найти...

Крестики нолики
Здравствуйте. Никак не получается определить, кто победил, всегда выводит ничью. Почему? ...

Крестики нолики
Недавно начал изучать C++. Фактически это первый язык программирования который я осваиваю. Решил...

Крестики Нолики
вот задали написать игру , скажите нормально впринципе написал или нет , и один вопрос немогу...


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

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Опции темы

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