Игра «Крестики-нолики» между двумя игроками: пользователем и компьютером (роботом)

Автор работы: Пользователь скрыл имя, 23 Января 2014 в 17:41, курсовая работа

Краткое описание

В работе разрабатывается консольное приложения, представляющего собой игру «Крестики нолики» с компьютером с поддержкой контейнерных классов STL.

Содержание

1. Введение
2. Интерфейс пользователя и Сценарии использования программы
3. Функциональные требования
4. Нефункциональные требования
5. Файловые интерфейсы
6. Исключительные ситуации
7. Контейнеры STL
8. Код игры с комментариями.
9. Заключение

Прикрепленные файлы: 1 файл

Курсовой прект крестики нолики.doc

— 176.00 Кб (Скачать документ)

Объявление структуры аналогично объявлению класса но вместо ключевого слова class ставится ключевое слово Struct :

struct идентификатор

{

Объявление данных или объектов

};

Объявлений структуры не подразумевает создание объекта или переменной. Объявление-это просто описание будущего объекта, в данном случае змейки. Чтобы использовать объект определенного класса или переменную определенного типа их сначала необходимо объявить в качестве объекта этого класса или переменной этого типа.

Аналогично для использования структурной переменной необходимо объявить переменную этой структуры.

Графический интерфейс.

Пользовательский интерфейс-это средства общения пользователя с вашей программой. которые могут включать в себя изображения , звуки и текст. Ориентируясь на среднего пользователя интерфейс должен быть простым и удобным. Это снизит вероятность ошибок.

7. Контейнеры STL

Стандартная библиотека шаблонов (STL) предоставляет несколько контейнеров для хранения коллекцию связанных объектов. Контейнеры все классы шаблонов, позволяющее определить, какие объекты разрешены в контейнерах. Этот раздел предоставляет обзор контейнеров STL, помогающие решить, который наилучшим образом подходящий для своего контейнера. Контейнеры STL можно разбить на категории 3, контейнеры последовательности, ассоциативные контейнеры и адаптеры контейнера. Эти категории и коллекции, которые принадлежат каждой категории, приведены здесь. Более подробные сведения можно найти в документации ссылки для контейнеров.

Контейнеры  последовательности

Контейнеры  последовательности поддерживают исходный порядок, вставляемых элементов. Это  позволяет определить место вставки  элемента в контейнере.

deque контейнер двойн-завершенной очереди () позволяет для быстрого вставок и удалений в начале и конце контейнера. Также можно случайно получить доступ к любой элемент быстро.

list предоставляет контейнер для быстрого вставок и удалений в любом месте в контейнере, но нельзя случайно получить доступ к элементу в контейнере.

vector контейнер ведет себя как массив, но будет увеличиваться автоматически по мере необходимости.

 

Ассоциативные контейнеры.

При указании характеристикой  ассоциативных контейнеров, что элементы вставляются в стандартный заказ, как отсортированный по возрастанию. Ассоциативные контейнеры можно группировать в 2 подмножеств: сопоставления и наборы. A mapиногда называют словарь, состоящий из пары " ключ-значение ". Ключ, используемый для упорядочения последовательности, а каким-либо образом, связанные с этим ключом. Например, a map может содержать уникальные ключи представления машинное каждое слово в текст и значениях, представляющее количество раз, машинное слово встречается в тексте. A set порядок по возрастанию просто контейнер уникальных элементов. Оба map и set разрешить только один экземпляр ключа или элемента, который необходимо вставить в контейнер. Если несколько экземпляров элементов необходимы, воспользуйтесь multimap OR multiset. Оба итератора сопоставления и поддержки двунаправленной наборов. Пока не часть стандарта STL, формальный hash_map и hash_set часто используется для повышения при поиске раз. Эти контейнеры хранят их элементы, такие как хэш-таблицы, каждая запись в таблице, содержащий список связанный двунаправленным элементов. Для обеспечения наиболее быстрые время поиска, убедитесь, что алгоритм хэширования для элементов возвращает равномерно распределенные значения хэша. Дополнительные сведения о ассоциативных контейнерах см. в следующей таблице.

Адаптеры  контейнера

Адаптеры контейнера просто изменения приведенных выше контейнеров. Адаптеры контейнера не поддерживают итераторы.

priority_queue контейнер упорядочивал те, что элемент с самым высоким значением всегда является первым в очереди.

queue контейнер следовать семантике FIFO (ранее пришел - первым вышел "). Первый элемент inserted (отправлянно) в очередь первое для удаления (извлекается).

stack контейнер следовать семантике LIFO (последнего in, out). Последний элемент для вставки (отправлянно) в стек первый элемент, удаляемый (извлекается).

Поскольку адаптеры контейнера не поддерживают итераторы, их нельзя использовать с алгоритмом STL.

Требования  для элементов контейнера.

Элементы, добавленные  в контейнер STL могут иметь любой тип объекта, который предоставляет открытый конструктор копии, открытый деструктор и открытый оператор присваивания. Деструктор не может создать исключение. Кроме того, ассоциативные как контейнеры set и map иметь открытый оператор сравнения быть определены, который по умолчанию operator<. Некоторые операции в контейнерах также могут потребовать открытого конструктора по умолчанию и открытого equivalence оператора.

 

 

8. Код игры с комментариями.

#include <iostream>

#include <string>

#include <vector>

#include <algorithm>

using namespace std;

 

/*

ввод  констант

создание  функций

создается пустая доска

вывод инструкций на дисплей

компьютер получает x

игрок получает o

спросить  игрока, если он хочет ходить первым.

    если игрок ходит первым

        игрок получает x

        компьютер получает o

    Если вторым то

        компьютер получает x

        игрок получает o

вывод доски на дисплей

если  никто не победит и ничья

 

    принимается решение по действию

    если игрок ходит

        игрок ставит позицию на доску

    если компьютер ходит

        высчитывается лучший ход

        компьютер ставит выбранную позицию  на доску

    обновление доски

 

определение победителя

вывод победителя на экран

спросить  игрока хочет ли он повторить игру

    если да

        начнется игра

    если нет

    игра окончена 

*/

 

 

const char EMPTY = ' ';

const char x = 'X';

const char o = 'O';

const char TIE = 'T';

const char NONE = 'N';

 

void instructions();

char askYesNo(string question);

int askNumber(string question, int high, int low = 1);

void displayBoard(const vector<char>* const board);

char winner(const vector<char>* const board);

bool isLegal(int move, const vector<char>* const board);

int humanMove(const vector<char>* const board, char human);

int computerMove(vector<char> board, char comp);

void announceWinner(char winner, char human, char comp);

char playAgain(string question);

void playGame();

 

int main()

{

setlocale (LC_ALL,".1251");

    int move;

    const int NUM_SQUARES = 9;

    vector<char> board(NUM_SQUARES, EMPTY);

 

    instructions();

    char computer = x;

    char human = o;

    char ans = askYesNo("Вы хотите ходить первым?");

    if (ans == 'y')

    {

        human = x;

        computer = o;

    }

    char turn = x;

    displayBoard(&board);

 

    while (winner(&board) == NONE)

    {

        if (turn == human)

        {

            move = humanMove(&board, human);

            board[move] = human;

        }

 

        else

        {

            move = computerMove(board, computer);

            board[move] = computer;

        }

        displayBoard(&board);

 

        if (turn == human)

        {

            turn = computer;

        }

        else { turn = human; }

    }

    announceWinner(winner(&board), human, computer);

    ans = playAgain("Вы хотите повторить игру? (y/n): ");

    if (ans == 'y')

    {

        cout << endl;

        playGame();

    }

    else

    {

        cout << "Спасибо за игру!";

        return 0;

    }

}

 

void playGame()

{

    main();

}

 

char playAgain(string question)

{

    char ans = 'n';

    cout << question;

    cin >> ans;

    return ans;

}

void instructions()

{

    cout << "Добро пожаловать в игру Крестики нолики.\n";

  

    cout << "Введите число от 0 - 8. Номера\n";

    cout << "расставляйте в ячейки приведенные в примере:\n\n";

 

    cout << "1 | 2 | 3\n";

    cout << "---------\n";

    cout << "4 | 5 | 6\n";

    cout << "---------\n";

    cout << "7 | 8 | 9\n\n";

    cout << "Приготовься. Игра сейчас начнется.\n\n";

}

 

char askYesNo(string question)

{

    char response;

    do

    {

        cout << question << "(y/n): ";

        cin >> response;

    } while (response != 'y' && response != 'n');

    return response;

}

 

int askNumber(string question, int high, int low)

{

    int number;

    do

    {

        cout << question << "("<< low << "- "<< high << "): ";

        cin >> number;

    } while (number > high || number < low);

    return number+1;

}

 

void displayBoard(const vector<char>* const board)

{

    cout << "\n\t" << (*board)[0] << " | "<< (*board)[1] << " | "<< (*board)[2];

    cout << "\n\t" << "---------";

    cout << "\n\t" << (*board)[3] << " | "<< (*board)[4] << " | "<< (*board)[5];

    cout << "\n\t" << "---------";

    cout << "\n\t" << (*board)[6] << " | "<< (*board)[7] << " | "<< (*board)[8];

    cout << "\n\n";

}

 

char winner(const vector<char>* const board)

{

    // все возможные варианты побед

    const int WINNING_ROWS[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}

                                    };

 

    const int TOTAL_ROWS = 8;

 

// если  в ряду есть три одинаковых  знчения (не пустые),

// тогда есть победитель

for(int row = 0; row < TOTAL_ROWS; ++row)

{

    if ( ((*board)[WINNING_ROWS[row][0]] != EMPTY) &&

         ((*board)[WINNING_ROWS[row][0]] == (*board)[WINNING_ROWS[row][1]]) &&

         ((*board)[WINNING_ROWS[row][1]] == (*board)[WINNING_ROWS[row][2]]) )

    {

         return (*board)[WINNING_ROWS[row][0]];

    }

}

 

 

// так  как никто не победил, проверяется  ничья (пустые квадраты)

if (count(board->begin(), board->end(), EMPTY) == 0)

    return TIE;

 

// так  как никто не победил, и не  ничья, игра продолжается

return NONE;

}

 

inline bool isLegal(int move, const vector<char>* const board)

{

    return ((*board)[move] == EMPTY);

}

 

int humanMove(const vector<char>* const board, char human)

{

    int move = askNumber("Ваш ход?", (board->size()));

    while (!isLegal(move-2, board))

    {

        cout << "\nЭта клетка занята.\n";

        move = askNumber("Ваш ход?", (board->size()));

    }

    cout << "Прекрасно...\n";

    return move-2;

}

 

int computerMove(vector<char> board, char computer)

{

    cout << "Я поставлю число в квадрат ";

 

    // если компьютер может победить на следующем ходе, делается ход.

    for(unsigned int move = 0; move < board.size(); ++move)

    {

        if (isLegal(move, &board))

        {

            board[move] = computer;

            if (winner(&board) == computer)

            {

                cout << move+1 << endl;

                return move;

            }

            // делана проверка движения , его отмена.

            board[move] = EMPTY;

        }

    }

 

    // если игрок может победить на следующем ходе, блокировать это движение.

    char human;

    if (computer == x)

    {

        human = o;

    }

    else { human = x; }

 

 

    for(unsigned int move = 0; move < board.size(); ++move)

    {

        if (isLegal(move, &board))

        {

            board[move] = human;

            if (winner(&board) == human)

            {

                cout << move+1 << endl;

                return move;

            }

            // сделана проверка движения , его отмена.

            board[move] = EMPTY;

        }

    }

 

    // лучшие шаги что-бы сделать ход

    const int BEST_MOVES[] = {5, 1, 3, 7, 9, 2, 4, 6, 8};

    // так как никто не может победить на следующем движении, выбрать лучший открытый квадрат.

    for(unsigned int i = 0; i < board.size(); ++i)

    {

        int move = BEST_MOVES[i];

        if (isLegal(move-1, &board))

        {

            cout << move << endl;

            return move-1;

        }

     }

    return 0;

}

 

void announceWinner(char winner, char human, char computer)

{

    if (winner == computer)

    {

        cout << "Компьютер" << " Выиграл!\n";

       

}

    else if (winner == human)

    {

        cout << "Игрок" << " Выиграл!\n";

       

}

    else

    {

        cout << "Ничья.\n";

    

}

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Список  рекомендуемой литературы:

 

1. Начальный  курс С и С++.: Учебник. /Б. И.  Березин. Москва:"ДИАЛОГ-МИФИ",1999г. 
2. Язык программирования С++. : Учебник. /. Страуструп. Киев:"ДиаСофт", 1993 г.

3. Введение в  язык С++: Учебник. / Бьярн Страустрап.

– СПб.: 1995.

4. Структуры  и алгоритмы обработки данных: Учебник. / Матьяш В.А., Путилов В.А., Фильчаков В.В. , Щёкин С.В. - Апатиты,  КФ Петр ГУ, 2000

5. С++ /Дэвис Стефан  Р.,4-е издание : Пер. с англ.:- М.: Издательский дом «Вильямс»,2003

6. Основы программирования: Учеб. Для сред. проф. образования /И.Г.Семакин, А.П.Шестаков. – М., 2006.

7. С++ экспресс  курс: Учебник. /Лаптев В.В. – СПб.: БХВ- Петербург 2004.

8. С++ учебный  курс: Учебник. /Франка П. – СПб.: Питер 2005.

9. МОДЕЛИ И CТРУКТУРЫ ДАННЫХ:/ Учебное пособие/ 
Д.Далека, А.С. Деревянко, О.Г.Кравец, Л.Е. Тимановская -Харьков: ХГПУ, 2000

10.Высшая математика  для экономистов: учебник для  студентов вузов/Н.Ш.Кремер,3-е издание.-М.:ЮНИТИ-ДАНА,2006

 

 

 

 

 

 

 

 

 

 


Информация о работе Игра «Крестики-нолики» между двумя игроками: пользователем и компьютером (роботом)