Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ТП_23_ИСТ_1_1_Какушкина_Ольга_Витальевна_KР_01ОФ

.docx
Скачиваний:
0
Добавлен:
23.06.2025
Размер:
318.1 Кб
Скачать

МИНОБРНАУКИ РОССИИ

Ф едеральное государственное бюджетное образовательное учреждение высшего образования

НИЖЕГОРОДСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ

УНИВЕРСИТЕТ им. Р.Е.АЛЕКСЕЕВА

Институт радиоэлектроники и информационных технологий

Кафедра информатики и систем управления

Программа играющая в «ГЕКСАГОН»

(наименование темы проекта или работы)

Курсовая работа (1-ый этап)

по дисциплине

Алгоритмы и структуры данных

(наименование дисциплины)

РУКОВОДИТЕЛЬ:

________________ Капранов С. Н.

(подпись) (фамилия, и.,о.)

СТУДЕНТ:

________________ Какушкина О. В.

(подпись) (фамилия, и.,о.)

23-ИСТ-1-1

(шифр группы)

Работа защищена «___» ____________

С оценкой ________________________

Нижний Новгород 2025

  1. Текст задачи:

  • Взятие обязательно. Побитые шашки снимаются только после завершения хода.

  • Захват соседних клеток:

    • Если игрок ставит свою шашку на клетку или перемещает её, он может захватить соседние клетки противника.

    • Захват происходит, если клетка противника находится в непосредственной близости (соседние клетки) от новой позиции шашки игрока.

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

  • Направления захвата:

    • В Гексагоне используется шестигранная сетка, поэтому у каждой клетки есть 6 соседей (по одному в каждом направлении).

    • Направления задаются следующим образом:

      • Слева.

      • Углом вверх вправо.

      • Вправо.

      • Справа.

      • Углом вверх влево.

      • Вверх.

  • Условия захвата:

    • Она находится в пределах игрового поля.

    • Она принадлежит противнику (не пустая и не принадлежит текущему игроку).

    • Она является соседней для новой позиции шашки игрока.

  • Запрет на самозахват:

    • Игрок не может захватывать свои собственные клетки.

Выигрыш партии

Партия считается выигранной в следующих случаях:

  1. Один из игроков контролирует больше клеток, чем противник, когда все клетки на поле заполнены.

  2. Один из игроков заявляет о сдаче.

  3. Один из игроков просрочил время (если используется контроль времени).

  4. Шашки и клетки одного из игроков обездвижены (он не имеет возможности сделать ход, когда пришла его очередь).

Ничья

Партия считается закончившейся вничью в следующих случаях:

  1. Один из игроков предлагает ничью, а другой её принимает.

  2. При невозможности выигрыша ни одного из игроков (например, если у обоих игроков одинаковое количество клеток).

  3. Если три раза повторяется одна и та же позиция.

  4. Если в течение 15 ходов игроки делали ходы, не приводящие к изменению соотношения сил (например, не было захватов и перемещений, меняющих баланс).

Факторы, учитываемые в оценочной функции

  1. Количество занятых клеток:

    1. Каждая клетка, занятая игроком 1 (PLAYER1), добавляет +1 к оценке.

    2. Каждая клетка, занятая игроком 2 (PLAYER2), вычитает -1 из оценки.

    3. Это базовый фактор, который отражает текущее соотношение сил на поле.

  2. Контроль центральных клеток:

    1. Центральные клетки имеют стратегическое значение, так как они обеспечивают больше возможностей для захвата и контроля.

    2. Если клетка игрока находится в центральной зоне, добавляется бонус +3 (значение CENTRAL_CELL_BONUS).

    3. Центральные клетки определены в массиве:

      1. cpp

      2. Copy

      3. std::vector<std::pair<int, int>> centralCells = {

      4. {NUM_ROWS / 2, NUM_COLS / 2},

      5. {NUM_ROWS / 2 - 1, NUM_COLS / 2},

      6. {NUM_ROWS / 2, NUM_COLS / 2 - 1},

      7. {NUM_ROWS / 2 + 1, NUM_COLS / 2},

      8. {NUM_ROWS / 2, NUM_COLS / 2 + 1}

      9. };

  3. Формирование цепочек:

    1. Если клетка игрока имеет соседнюю клетку, также занятую этим игроком, это считается цепочкой.

    2. За каждую такую связь добавляется бонус +2 (значение CHAIN_BONUS).

    3. Это поощряет игрока создавать группы клеток, которые могут быть использованы для захвата или защиты.

  4. Потенциальные угрозы:

    1. Если клетка игрока находится под угрозой захвата противником (например, если рядом с ней есть клетка противника, за которой есть пустая клетка), вычитается штраф -1 (значение THREAT_BONUS).

    2. Если клетка противника находится под угрозой захвата игроком, добавляется бонус +1.

  5. Формула вычисления оценки

Оценка вычисляется по следующей формуле:

Оценка=Клетки PLAYER1−Клетки PLAYER2+Центральные бонусы+Цепочки−УгрозыОценка=Клетки PLAYER1−Клетки PLAYER2+Центральные бонусы+Цепочки−Угрозы

Где:

  • Клетки PLAYER1: количество клеток, занятых игроком 1.

  • Клетки PLAYER2: количество клеток, занятых игроком 2.

  • Центральные бонусы: бонусы за контроль центральных клеток.

  • Цепочки: бонусы за формирование цепочек.

  • Угрозы: штрафы за потенциальные угрозы.

  1. пример расчета ОФ (игровая ситуация находиться на середине партии)

Рассмотрим пример игрового поля:

Шаги вычисления:

  1. Клетки PLAYER1:

    • Игрок 1 контролирует 1 клетку (2, 2) → +1.

  2. Клетки PLAYER2:

    • Игрок 2 контролирует 2 клетки (1, 2) и (2, 3) → -2.

  3. Центральные бонусы:

    • Клетка (2, 2) игрока 1 находится в центре → +3.

  4. Цепочки:

    • У игрока 1 нет соседних клеток, занятых им же → 0.

  5. Потенциальные угрозы:

    • Клетка (2, 2) игрока 1 может быть захвачена игроком 2 через клетку (2, 3) → -1.

    • Клетка (2, 3) игрока 2 может быть захвачена игроком 1 через клетку (2, 2) → +1.

Итоговая оценка:

Оценка=1−2+3+0−1+1=2Оценка=1−2+3+0−1+1=2

Эти факторы позволяют оценить текущее состояние игры и определить, какой игрок имеет преимущество. В приведенном примере оценка 2 указывает на небольшое преимущество игрока 1.

  1. программный код с комментариями всех участвующих в расчете функций

int Evaluation(TPlaying_Field* Playing_Field) {

int score = 0;

// Весовые коэффициенты для различных факторов

const int CENTRAL_CELL_BONUS = 3; // Бонус за контроль центральных клеток

const int CHAIN_BONUS = 2; // Бонус за формирование цепочек

const int THREAT_BONUS = 1; // Бонус за потенциальные угрозы

// Центральные клетки

std::vector<std::pair<int, int>> centralCells = {

{NUM_ROWS / 2, NUM_COLS / 2},

{NUM_ROWS / 2 - 1, NUM_COLS / 2},

{NUM_ROWS / 2, NUM_COLS / 2 - 1},

{NUM_ROWS / 2 + 1, NUM_COLS / 2},

{NUM_ROWS / 2, NUM_COLS / 2 + 1}

};

// Функция для обработки клетки игрока

auto evaluateCell = [&](int i, int j, CellState player, int playerModifier) {

// Базовый счет за клетку

score += playerModifier;

// Бонус за контроль центральных клеток

for (const auto& cell : centralCells) {

if (i == cell.first && j == cell.second) {

score += CENTRAL_CELL_BONUS * playerModifier;

}

}

// Оценка соседних клеток

for (const auto& dir : DIRECTIONS) {

int ni = i + dir[0];

int nj = j + dir[1];

if (IsInBounds(ni, nj)) {

if (Playing_Field->board[ni][nj] == EMPTY) {

score += 1 * playerModifier; // Пустая соседняя клетка

} else if (Playing_Field->board[ni][nj] != player) {

score -= 1 * playerModifier; // Клетка противника

}

}

}

// Бонус за формирование цепочек

for (const auto& dir : DIRECTIONS) {

int ni = i + dir[0];

int nj = j + dir[1];

if (IsInBounds(ni, nj) && Playing_Field->board[ni][nj] == player) {

score += CHAIN_BONUS * playerModifier;

}

}

// Учет потенциальных угроз

for (const auto& dir : DIRECTIONS) {

int ni = i + dir[0];

int nj = j + dir[1];

if (IsInBounds(ni, nj) && Playing_Field->board[ni][nj] != player && Playing_Field->board[ni][nj] != EMPTY) {

// Проверяем, может ли противник захватить клетку

int nni = ni + dir[0];

int nnj = nj + dir[1];

if (IsInBounds(nni, nnj) && Playing_Field->board[nni][nnj] == EMPTY) {

score -= THREAT_BONUS * playerModifier; // Штраф за потенциальную угрозу

}

}

}

};

// Основной цикл

for (int i = 0; i < NUM_ROWS; ++i) {

for (int j = 0; j < NUM_COLS; ++j) {

if (Playing_Field->board[i][j] == PLAYER1) {

evaluateCell(i, j, PLAYER1, 1); // Обработка клетки PLAYER1

} else if (Playing_Field->board[i][j] == PLAYER2) {

evaluateCell(i, j, PLAYER2, -1); // Обработка клетки PLAYER2

}

}

}

return score;

}