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

Крестики-нолики. Минимакс. Надо сдать лабу. Преподавательница - зверь - C++

Восстановить пароль Регистрация
 
lissenok
0 / 0 / 1
Регистрация: 02.03.2014
Сообщений: 5
16.03.2014, 07:46     Крестики-нолики. Минимакс. Надо сдать лабу. Преподавательница - зверь #1
Доброго времени суток, уважаемые форумчане! Прошу вас о помощи. Преподавательница зверь!! Спрашивает о каждой строчке в коде. Который раз сдать не могу. Код прилагается. Если кому не сложно, прокомментируйте код относительно самих ходов Min и Max.

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
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
#include "stdafx.h"
#include "time.h"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <list>
using namespace std;
 
static const int INFINITY = 100;
static enum {PLAYING,OWIN,XWIN,DRAW} state;
typedef struct {
    char symbol;
    int move;
    bool selected;
    bool win;
}
player;
 
void display_board();       // отображение
void get_move();                // поиск(получение) хода
void update_game();             // следующий шаг игры         
bool free_square();     // проверка пустоты ячейки
void update_board();            // обновление позиций на доске
void verify_move();             // проверка валидности хода(0-8 и не занята ячейка)
void generate_moves(char _board[9], list<int> &move_list); // генерация всех ходов для minmax
void check_game_state(char board[9]);              // проверка постояния игры
 
int evaluate_position(char _board[9], player _player); // оценка положения
int MiniMax(char _board[9], player _player);    
int MinMove(char _board[9], player _player);    
int MaxMove(char _board[9], player _player);
           
static player player1, player2, cplayer;
static char board[9] = {0}; // обозначение доски для игры
static char symbol; // символ для текущего игрока
static int nmove;  // последний шаг сделанный действующим игроком
 
int q = 0;
//---------------------------------------------------------------------------------
int main() {
    srand((unsigned) time(NULL));
    
    // Get player sumbol
    int selection = rand() % 2;
    if(selection == 0) {
        player2.symbol = 'X';
        player1.symbol = 'O';
    }else if(selection == 1) {
        player1.symbol = 'X';
        player2.symbol = 'O';
    }
    state = PLAYING;
 
    // Play
    while(state == PLAYING) {
        get_move();
        update_game();
    }
 
    // если игра закончилась
    if(state == XWIN || state == OWIN || state == DRAW) {
        if(state == XWIN)   player1.win = 1;
        else if(state == OWIN)  player2.win = 1;
        
        if(player1.win)                 std::cout << "Player has won the game!" << std::endl;
        else if(player2.win)                std::cout << "Computer has won the game!" << std::endl;
        else if(player1.win == 0 && player2.win == 0)   std::cout << "No winner, this game is a draw." << std::endl;
    }
    system("PAUSE");
    
    return 0;
}
//---------------------------------------------------------------------------------
void get_move()  {
    player1.move = -1;
    player2.move = -1;
    std::cin.sync(); //очищение буфера стандартного ввода
        if(player1.selected) {
            std::cout << std::endl;
            std::cout << " Please Enter Your Move (1-9): ";
            std::cin >> player1.move;
            nmove = player1.move;
            symbol = player1.symbol;
            cplayer = player1;
            player1.selected = 0;
            player2.selected = 1;
        }else if(player2.selected) {
            player2.move = MiniMax(board, player2);
            nmove = player2.move;
            symbol = player2.symbol;
            cplayer = player2;
            player1.selected = 1;
            player2.selected = 0;
            state = PLAYING;
        }
    
    verify_move();
    if((state == XWIN || state == OWIN || state==DRAW)) return;
}
//---------------------------------------------------------------------------------
void update_board() {
    if(state == PLAYING) {
        if(player1.move != -1 && player2.move == -1)    board[player1.move - 1] = player1.symbol;
        else if(player2.move != -1)             board[player2.move - 1] = player2.symbol;
    }
}
//---------------------------------------------------------------------------------
void update_game() {
    update_board();
    display_board();
    check_game_state(board);
}
//---------------------------------------------------------------------------------
bool free_square()  {
    if(player1.move != -1 && player2.move == -1)
        return board[player1.move - 1] == 0;
    else if(player2.move != -1)
        return board[player2.move - 1] == 0;
    return 0;
}
//---------------------------------------------------------------------------------
void display_board()  {
    std::cout << std::endl;
    std::cout << " " << board[0] << " | " << board[1] << " | " << board[2] << std::endl;
    std::cout << "-----------" << std::endl;
    std::cout <<  " " << board[3] << " | " << board[4] << " | " << board[5] << std::endl;
    std::cout << "-----------" << std::endl;
    std::cout <<  " " << board[6] << " | " << board[7] << " | " << board[8] << std::endl;
    std::cout << std::endl;
}
//---------------------------------------------------------------------------------
void verify_move()  {
    if(!(nmove > 0 && nmove < 10) || !free_square()) {
        std::cout << "Invalid Move." << std::endl;
        player1.selected = 1;
        player2.selected = 0;
        get_move();
    }
}
//---------------------------------------------------------------------------------
void check_game_state(char board[9]) {
    if ((board[0] == symbol && board[1] == symbol && board[2] == symbol) ||
        (board[3] == symbol && board[4] == symbol && board[5] == symbol) ||
        (board[6] == symbol && board[7] == symbol && board[8] == symbol) ||
        (board[0] == symbol && board[3] == symbol && board[6] == symbol) ||
        (board[1] == symbol && board[4] == symbol && board[7] == symbol) ||
        (board[2] == symbol && board[5] == symbol && board[8] == symbol) ||
        (board[0] == symbol && board[4] == symbol && board[8] == symbol) ||
        (board[2] == symbol && board[4] == symbol && board[6] == symbol)) {
        if(symbol == 'X')   state = XWIN; 
        else if(symbol == 'O')  state = OWIN;
    }else {
        state = DRAW;
        for(int i = 0; i < 9;i++) {
            if(board[i] == 0) {
                state = PLAYING;
                break;
            }
        }
    }
}
//---------------------------------------------------------------------------------
void generate_moves(char _board[9], std::list<int> &move_list) {
    for(int i = 0; i < 9; i++) if(_board[i] == 0) move_list.push_back(i);
}
//---------------------------------------------------------------------------------
int evaluate_position(char _board[9], player _player)  {
    check_game_state(_board);
    if((state == XWIN || state == OWIN || state==DRAW)) {
        if((state == XWIN && _player.symbol == 'X') || (state == OWIN && _player.symbol == 'O')) return +INFINITY;
        else if((state == XWIN && _player.symbol == 'O') || (state == OWIN && _player.symbol == 'X')) return -INFINITY;
        else if(state == DRAW) return 0;
    }
    return -1;
}
//---------------------------------------------------------------------------------
int MiniMax(char _board[9], player _player)  {
    int best_val = -INFINITY, index = 0;
    std::list<int> move_list;
    char best_moves[9] = {0};
 
    generate_moves(_board, move_list); // генерить все ходы
    while(!move_list.empty()) { // по всем
        _board[move_list.front()] = _player.symbol; // заполнение ячейки символом игрока
        symbol = _player.symbol;
 
        
        int val = MinMove(_board, _player); // поиск MinMove
        if(val > best_val) { // выбор наибольшего
            best_val = val;
            index = 0;
            best_moves[index] = 1 + move_list.front();
        } else if(val == best_val)
            best_moves[++index] = 1 + move_list.front(); // если несколько наибольших - тоже заносим
 
        printf("\nminimax: %3d(%1d) ", 1 + move_list.front(), val);
        _board[move_list.front()] = 0; // отбрасываем ход, идем далее по циклу
        move_list.pop_front();
    }
    if(index > 0) index = rand() % index; // выбираем случайный из нескольких ходов
    printf("\nminimax best: %3d(%1d) ", best_moves[index], best_val);
    printf("Steps counted: %d",q);
    q = 0;
    return best_moves[index];
}
//---------------------------------------------------------------------------------
int MinMove(char _board[9], player _player)  {
    int pos_value = evaluate_position(_board, _player); // проверить состояние игры для текущего игрока
    if(pos_value != -1) return pos_value;
    q++;
    int best_val = +INFINITY; 
    std::list<int> move_list;
    generate_moves(_board, move_list); // генерить все ходы
    while(!move_list.empty()) { // по всем
        _player.symbol == 'X' ? symbol = 'O' : symbol = 'X'; // расчет для противника
        _board[move_list.front()] = symbol; // front - ссылка на первый элемент, заполнение ячейки символом
        int val = MaxMove(_board, _player); // подсчет MaxMove
        if(val < best_val) {
            best_val = val; // выбрать с наименьшим 
            //printf("%3d(%d) ",move_list.front()+1,best_val);
        }       
        _board[move_list.front()] = 0; 
        move_list.pop_front();
    }
    return best_val;
}
//---------------------------------------------------------------------------------
int MaxMove(char _board[9], player _player) {
    int pos_value = evaluate_position(_board, _player);
    if(pos_value != -1) return pos_value;
    q++;
    int best_val = -INFINITY;
    std::list<int> move_list;
    generate_moves(_board, move_list);
    while(!move_list.empty()) {
        _player.symbol == 'X' ? symbol = 'X' : symbol = 'O'; // расчет для себя
        _board[move_list.front()] = symbol;
        int val = MinMove(_board, _player);
        if(val > best_val) {
            best_val = val;
            //printf("%3d(%d) ",move_list.front()+1,best_val);
        }
        _board[move_list.front()] = 0;
        move_list.pop_front();
    }
    return best_val;
}
//---------------------------------------------------------------------------------
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.03.2014, 07:46     Крестики-нолики. Минимакс. Надо сдать лабу. Преподавательница - зверь
Посмотрите здесь:

Помогите, умоляю..... нужно сдать лабу..... срочно.... а нифига не получается.... я девушка, сразу поясняю..) C++
C++ Крестики нолики на С
Крестики-нолики C++
C++ Крестики Нолики
C++ Крестики-нолики
C++ крестики нолики
C++ Крестики-нолики
Крестики-нолики 3х3 и 5х5 МиниМакс C++

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Ответ Создать тему
Опции темы

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