Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 26.06.2010, 19:00   #1
Atlika
 
Регистрация: 26.06.2010
Сообщений: 5
По умолчанию Самообучающиеся крестики-нолики

Пишу курсовую, используя код из книги Мозгового "85 нетривиальных проектов, решений и задач". Вылазят ошибки, которые никак не могу исправить. Компилирую на Borland C++ 5.
Помогите, пожалуйста, кто чем сможет!!! Курсовую уже в понедельник сдавать....
Код:
//#include <cstdlib>
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <iterator>
#include <math.h>

using namespace std;

const int InitWeight = 100; //начальный вес
const int PrecCoeff = 50; //точность генератора случайных чисел
const double StepCoeff = 0.65; // коэффициент обучения
const int LearningStep = 20; //шаг обучения

//Игровое поле (3 на 3 построчно). Может содержать
//символов-крестик "x" , "o" и пробел

char GameField[9];

//текущее состояние игры - выиграли крестики, выиграли нолики, ничья, 
//игра еще не закончена
enum OUTCOME { Xs, Os, DRAW, UNFINISHED };
OUTCOME GetOutcome()
{
        //все восемь победных расположений символов игрока
        int V[8][3] = { {0,1,2},{3,4,5},{6,7,8},{0,3,6},
                        {1,4,7},{2,5,8},{0,4,8},{2,4,6} };
        
        //если обнаружена победная комбинация
        for( int i = 0; i < 8; i++ )
             if (GameField[V[i][0]] == GameField[V[i][1]] &&
                 GameField[V[i][0]] == GameField[V[i][2]] &&
                 GameField[V[i][0]] != ' ')
             return GameField[V[i][0]] == 'x' ? Xs : Os;
             //если победных комбинаций не обнаружено, то результат
             //зависит от наличия на игровом поле пробельных символов
             //если пробелов нет, игра завершилась ничьей
             return (find(GameField, GameField + 9, ' ') == GameField + 9 ) ? DRAW : UNFINISHED;
};

//вывести текущее положение игрового поля
void PrintField()
{
     cout << GameField[0] << "|" << GameField[1] << "|" << GameField[2] << endl;
     cout << GameField[3] << "|" << GameField[4] << "|" << GameField[5] << endl;        
     cout << GameField[6] << "|" << GameField[7] << "|" << GameField[8] << endl; 
     cout << endl;
};

//состояние игрового поля 
struct TMyField
{
       char MyField[9];
       //конструктор: просто скопировать текущее содержимое
       //реального поля
       TMyField() { copy(GameField, GameField + 9, MyField); }

       //для объядинения в коллекцию требуется функция
       //упорядочивания
       bool operator<<(const TMyField& rhs) const
       {
            return lexicographical_compare(MyField, MyField + 9, rhs.MyField, rhs.MyField +9 );
            }
};

//матрица весов
struct TMyWeight
{
       int MyWeight[9];
       //изначально заполняется значениями веса InitWeight
       TMyWeight() { fill(MyWeight, MyWeight +9, InitWeight); }
};

//абстрактный класс Player
class Player
{
      protected:
                //используемый игроком символ (крестик или нолик)
                char Symbol;
                
      public:
             Player(char _symbol) : Symbol(_symbol) {}
             //сделать очередной ход
             virtual void MakeMove() = 0;
             //выполнить одну итерацию обучения
             virtual void Learn(int) {}
};

//игрок - человек
class HumanPlayer : public Player
{
      public:
             HumanPlayer(char _symbol) : Player(_symbol) {}
             
             virtual void MakeMove()
             {
                     int Cell;
                     //прочитать номер клетки и сделать ход
                     //корректность хода не проверяется
                     cin >> Cell;
                     GameField[Cell] = Symbol;
             }
};

//игрок-компьютер, использующий рандомизированную стратегию
class RandomPlayer : public Player
{
      public:
             RandomPlayer(char _symbol) : Player(_symbol) {}
             
             virtual void MakeMove()   // <- ругается в этом месте
             {
                     vector<int> v;
                     
                     //запомнить номера всех пустых клеток
                     for ( int i =0 ; i < 9 ; i++)
                         if(GameField[i] == ' ')
                            v.push_back(i);
                     //записать символ в случайно выбранную пустую клетку
                     GameField[v[random(v.size())]] = Symbol;  }
};
Atlika вне форума Ответить с цитированием
Старый 26.06.2010, 19:03   #2
Atlika
 
Регистрация: 26.06.2010
Сообщений: 5
По умолчанию

Код:
class SmartPlayer : public Player
{
      private:
              //элемент истроии текущей игры
              struct HistoryElement {
                     map<TMyField, TMyWeight>::iterator Situation; //позиция
                    int Move; //сделанный ход
                    HistoryElement(map<TMyField, TMyWeight>::iterator s, int m)
                                                : Situation(s), Move(m) {}
              };

              stack<HistoryElement> History; //история сделанных ходов
              //map<TMyField, TMyWeight>::Database; //полная база знаний игрока

              //поиск в базе знаний текущей игровой ситуации
              map<TMyField, TMyWeight>::iterator GetSituation();

              //генератор случайных чисел, учитывающий матрицу весов
             int GetWRandom(map<TMyField, TMyWeight>::iterator s);

public:
       SmartPlayer(char _symbol) : Player(_symbol) {}

       virtual void MakeMove();
       void Learn(int step);
};//найти в базе знаний ситуацию, сложившуюся на поле
map<TMyField, TMyWeight>::iterator SmartPlayer::GetSituation()
{ // <- ругается в этом месте
            //поиск в базу объекта TFiled, инициализирующийся содержимым GameField
            map<TMyField, TMyWeight>::iterator p = Database.find(TMyField());     // <- ругается в этом месте
            // если объект не найден
            if ( p == Database.end())
            {
                 TMyWeight w; //создать новую матрицу весов
                 for(int i = 0; i < 9; i++)
                 if (GameField[i] != ' ') //если клетка игрового поля занята
                    w.Weight[i] = 0; //ход невозможен (его вес равен нулю)
                 Database[TMyField()] = w; //записать текущюю ситуацию в базу
                                    return Database.find(TMyField());
                 }
                 return p;
}

//возвращает случайное число, соответсвующее матрице весов s->second
int SmartPlayer::GetWRandom(map<TMyField, TMyWeight>::iterator s)
{ // <- ругается в этом месте
    //найти сумму всех весов матрицы
    int sum = accumulate(s->second.Weight, s->second.Weight + 9, 0); // <- ругается в этом месте
    //если все ходы одинаково плохи ( их веса равны нулю )
    if ( sum == 0 )
       //выбираем первую попавшуюся пустую клетку
       return find(GameField, GameField + 9, ' ') - GameField;

    vector<int> coords; //генерация случайного числа
    for ( int i = 0; i < 9; i++ )
    fill_n(back_inserter(coords), PrecCoeff*s->second.Weight[i] / sum, i);

    return coords[random(coords.size())];
}

//сделать очередной ход
void SmartPlayer::MakeMove()
{ // <- ругается в этом месте
     //извлечь сттуацию из базы знаний
     map<TMyField, TMyWeight>::iterator s = GetSituation();

     int move = GetWRandom(s); //сгенерировать ход

     GameField[move] = Symbol; //сделать ход
     History.push(HistoryElement(s,move)); //запомнить ход в истории     // <- ругается в этом месте
}

void SmartPlayer::Learn(int step)
{ // <- ругается в этом месте
     //если история ходов уже пуста
     if (History.empty())      // <- ругается в этом месте
        return; //итерация обучения завершена
        
     //извлечь очередной ход
     HistoryElement h = History.top();      // <- ругается в этом месте
     History.pop();
     
     //ссылка на матрицу весов
     TWeight& w = h.Situation->second;     // <- ругается в этом месте
     
     //изменить вес хода
     w.Weight[h.Move] += step; 
     if (w.Weight[h.Move] < 0 ) //нижний предел веса - нуль
        w.Weight[h.Move] = 0;
     
     //выполнить обучение для предыдущего хода
     Learn(step * StepCoeff);
}

//провести одну игру между игроками Xp (крестики) и Op (нолики)
//параметр Verbose указывает, следует ли выводить на экран 
//игровое поле ( во время обучения лишь замедляет процесс)
void PlayGame(Player *Xp, Player *Op, bool Verbose)
{
     Player *Cp[] = { Xp, Op };
     //номер текущего хода
     int move = 0;
     fill(GameField, GameField + 9, ' '); //очистить поле
     //пока игра не закончилась
     while(GetOutcome() == UNFINISHED)
     {
      //сделать очередной ход
      Cp[move++ % 2]->MakeMove();
      //при необходимости вывести игровое поле на экран
      if(Verbose)
                 PrintField();
};

//выполнить итерацию обучения 
// (поощрять выигравшую сторону, наказываем проигравшую)
if (GetOutcome() == Xs)
   { Xp->Learn(LearningStep); Op->Learn(-LearningStep); }
else if(GetOutcome() == Os)
     { Xp->Learn(-LearningStep); Op->Learn(LearningStep); }
Atlika вне форума Ответить с цитированием
Старый 26.06.2010, 19:04   #3
Atlika
 
Регистрация: 26.06.2010
Сообщений: 5
По умолчанию

Код:
int main(int argc, char *argv[])
{
    randomize();
    RandomPlayer *r = new RandomPlayer('o');
    HumanPlayer *h = new HumanPlayer('o');
    SmartPlayer *s = new SmartPlayer('x');
    
    //сыграть 50000 партий между игроками s и r
    for ( int k = 0; k < 50000; k++)
        PlayGame(s,h,false);
        
    //сыграть партию между s и человеком
    PlayGame(s,h,true);
    
    delete s; delete h; delete r;
  
    
    system("PAUSE");
    return 0;
}
ошибки:
Код:
Error:  uuu.cpp(130,46):Too few arguments in template class name 'map'
Error:  uuu.cpp(130,56):Declaration terminated incorrectly
Error:  uuu.cpp(132,60):Too few arguments in template class name 'map'
Error:  uuu.cpp(132,62):Too few arguments in template class name 'map'
Error:  uuu.cpp(132,62):Declaration terminated incorrectly
Error:  uuu.cpp(136,36):Too few arguments in template class name 'stack'
Error:  uuu.cpp(136,45):Declaration terminated incorrectly
Error:  uuu.cpp(140,39):Too few arguments in template class name 'map'
Error:  uuu.cpp(140,49):Declaration terminated incorrectly
Error:  uuu.cpp(143,53):Too few arguments in template class name 'map'
Error:  uuu.cpp(143,63):) expected
Error:  uuu.cpp(153,25):Too few arguments in template class name 'map'
Error:  uuu.cpp(153,35):Declaration terminated incorrectly
Atlika вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Крестики нолики на C++ Alar Gamedev - cоздание игр: Unity, OpenGL, DirectX 11 15.03.2010 16:09
Крестики-нолики Linker88 Фриланс 10 20.05.2009 07:24
КРЕСТИКИ-НОЛИКИ((( magadan Паскаль, Turbo Pascal, PascalABC.NET 8 02.05.2009 22:16
Крестики нолики Gorbunov Общие вопросы C/C++ 5 22.01.2009 16:04
КРЕСТИКИ-НОЛИКИ oblachko Паскаль, Turbo Pascal, PascalABC.NET 1 17.01.2009 22:21