<commit_before>#include "model/Snake.h"
#include "util/util.h"
#include "GameCtrl.h"
#include <queue>
#include <algorithm>
#include <stdexcept>

using std::vector;
using std::list;
using std::queue;
using util::Random;

Snake::Snake() {}

Snake::~Snake() {}

void Snake::setDirection(const Direction &d) {
    direc = d;
}

void Snake::setMap(Map *const m) {
    map = m;
}

Direction Snake::getDirection() const {
    return direc;
}

bool Snake::isDead() const {
    return dead;
}

void Snake::testMinPath(const Pos &from, const Pos &to, std::list<Direction> &path) {
    map->setTestEnabled(true);
    findMinPath(from, to, path);
    map->showPath(from, path);
    map->setTestEnabled(false);
}

void Snake::testMaxPath(const Pos &from, const Pos &to, std::list<Direction> &path) {
    map->setTestEnabled(true);
    findMaxPath(from, to, path);
    Pos cur = from;
    for (const Direction d : path) {
        map->getPoint(cur).setDist(GameCtrl::EMPTY_VALUE);
        cur = cur.getAdj(d);
    }
    map->getPoint(from).setDist(0);
    map->getPoint(to).setDist(1);
    map->showPath(from, path);
    map->setTestEnabled(false);
}

void Snake::testHamilton() {
    map->setTestEnabled(true);
    enableHamilton();
    SizeType row = map->getRowCount(), col = map->getColCount();
    for (SizeType i = 1; i < row - 1; ++i) {
        for (SizeType j = 1; j < col - 1; ++j) {
            Pos pos = Pos(i, j);
            Point &point = map->getPoint(pos);
            point.setDist(point.getIndex());
            map->showPos(pos);
        }
    }
}

void Snake::addBody(const Pos &p) {
    if (bodies.size() == 0) {  // Insert a head
        map->getPoint(p).setType(Point::Type::SNAKE_HEAD);
    } else {  // Insert a body
        if (bodies.size() > 1) {
            const Pos &oldTail = getTail();
            map->getPoint(oldTail).setType(Point::Type::SNAKE_BODY);
        }
        map->getPoint(p).setType(Point::Type::SNAKE_TAIL);
    }
    bodies.push_back(p);
}

void Snake::move() {
    if (isDead() || direc == NONE) {
        return;
    }
    map->getPoint(getHead()).setType(Point::Type::SNAKE_BODY);
    Pos newHead = getHead().getAdj(direc);
    bodies.push_front(newHead);
    if (!map->isSafe(newHead)) {
        dead = true;
    } else {
        if (map->getPoint(newHead).getType() != Point::Type::FOOD) {
            removeTail();
        } else {
            map->removeFood();
        }
    }
    map->getPoint(newHead).setType(Point::Type::SNAKE_HEAD);
}

void Snake::move(const std::list<Direction> &path) {
    for (const Direction &d : path) {
        setDirection(d);
        move();
    }
}

void Snake::enableHamilton() {
    if (map->getRowCount() % 2 == 1 && map->getColCount() % 2 == 1) {
        throw std::range_error("Snake.enableHamilton(): require even amount of rows or columns.");
    }
    hamiltonEnabled = true;
    buildHamilton();
}

void Snake::decideNext() {
    if (isDead()) {
        return;
    } else if (!map->hasFood()) {
        direc = NONE;
        return;
    }

    if (hamiltonEnabled) {  // AI based on the Hamiltonian cycle

        SizeType size = map->getSize();
        Pos head = getHead(), tail = getTail();
        Point::ValueType tailIndex = map->getPoint(tail).getIndex();
        Point::ValueType headIndex = map->getPoint(head).getIndex();
        // Try to take shortcuts when the snake is not long enough
        if (bodies.size() < size * 3 / 4) {
            list<Direction> minPath;
            findMinPathToFood(minPath);
            if (!minPath.empty()) {
                Direction nextDirec = *minPath.begin();
                Pos nextPos = head.getAdj(nextDirec);
                Point::ValueType nextIndex = map->getPoint(nextPos).getIndex();
                Point::ValueType foodIndex = map->getPoint(map->getFood()).getIndex();
                headIndex = util::getDistance(tailIndex, headIndex, (Point::ValueType)size);
                nextIndex = util::getDistance(tailIndex, nextIndex, (Point::ValueType)size);
                foodIndex = util::getDistance(tailIndex, foodIndex, (Point::ValueType)size);
                if (nextIndex > headIndex && nextIndex <= foodIndex) {
                    direc = nextDirec;
                    return;
                }<commit_msg>Fix the if statement in Snake.cpp for clear statement<commit_after>#include "model/Snake.h"
#include "util/util.h"
#include "GameCtrl.h"
#include <queue>
#include <algorithm>
#include <stdexcept>

using std::vector;
using std::list;
using std::queue;
using util::Random;

Snake::Snake() {}

Snake::~Snake() {}

void Snake::setDirection(const Direction &d) {
    direc = d;
}

void Snake::setMap(Map *const m) {
    map = m;
}

Direction Snake::getDirection() const {
    return direc;
}

bool Snake::isDead() const {
    return dead;
}

void Snake::testMinPath(const Pos &from, const Pos &to, std::list<Direction> &path) {
    map->setTestEnabled(true);
    findMinPath(from, to, path);
    map->showPath(from, path);
    map->setTestEnabled(false);
}

void Snake::testMaxPath(const Pos &from, const Pos &to, std::list<Direction> &path) {
    map->setTestEnabled(true);
    findMaxPath(from, to, path);
    Pos cur = from;
    for (const Direction d : path) {
        map->getPoint(cur).setDist(GameCtrl::EMPTY_VALUE);
        cur = cur.getAdj(d);
    }
    map->getPoint(from).setDist(0);
    map->getPoint(to).setDist(1);
    map->showPath(from, path);
    map->setTestEnabled(false);
}

void Snake::testHamilton() {
    map->setTestEnabled(true);
    enableHamilton();
    SizeType row = map->getRowCount(), col = map->getColCount();
    for (SizeType i = 1; i < row - 1; ++i) {
        for (SizeType j = 1; j < col - 1; ++j) {
            Pos pos = Pos(i, j);
            Point &point = map->getPoint(pos);
            point.setDist(point.getIndex());
            map->showPos(pos);
        }
    }
}

void Snake::addBody(const Pos &p) {
    if (bodies.size() == 0) {  // Insert a head
        map->getPoint(p).setType(Point::Type::SNAKE_HEAD);
    } else {  // Insert a body
        if (bodies.size() > 1) {
            const Pos &oldTail = getTail();
            map->getPoint(oldTail).setType(Point::Type::SNAKE_BODY);
        }
        map->getPoint(p).setType(Point::Type::SNAKE_TAIL);
    }
    bodies.push_back(p);
}

void Snake::move() {
    if (isDead() || direc == NONE) {
        return;
    }
    map->getPoint(getHead()).setType(Point::Type::SNAKE_BODY);
    Pos newHead = getHead().getAdj(direc);
    bodies.push_front(newHead);
    if (!map->isSafe(newHead)) {
        dead = true;
    } else {
        if (map->getPoint(newHead).getType() != Point::Type::FOOD) {
            removeTail();
        } else {
            map->removeFood();
        }
    }
    map->getPoint(newHead).setType(Point::Type::SNAKE_HEAD);
}

void Snake::move(const std::list<Direction> &path) {
    for (const Direction &d : path) {
        setDirection(d);
        move();
    }
}

void Snake::enableHamilton() {
    if (map->getRowCount() % 2 == 1 && map->getColCount() % 2 == 1) {
        throw std::range_error("Snake.enableHamilton(): require even amount of rows or columns.");
    }
    hamiltonEnabled = true;
    buildHamilton();
}

void Snake::decideNext() {
    if (isDead()) {
        return;

    } else if (!isDead() && !map->hasFood()) {
        direc = NONE;
        return;
    }

    if (hamiltonEnabled) {  // AI based on the Hamiltonian cycle

        SizeType size = map->getSize();
        Pos head = getHead(), tail = getTail();
        Point::ValueType tailIndex = map->getPoint(tail).getIndex();
        Point::ValueType headIndex = map->getPoint(head).getIndex();
        // Try to take shortcuts when the snake is not long enough
        if (bodies.size() < size * 3 / 4) {
            list<Direction> minPath;
            findMinPathToFood(minPath);
            if (!minPath.empty()) {
                Direction nextDirec = *minPath.begin();
                Pos nextPos = head.getAdj(nextDirec);
                Point::ValueType nextIndex = map->getPoint(nextPos).getIndex();
                Point::ValueType foodIndex = map->getPoint(map->getFood()).getIndex();
                headIndex = util::getDistance(tailIndex, headIndex, (Point::ValueType)size);
                nextIndex = util::getDistance(tailIndex, nextIndex, (Point::ValueType)size);
                foodIndex = util::getDistance(tailIndex, foodIndex, (Point::ValueType)size);
                if (nextIndex > headIndex && nextIndex <= foodIndex) {
                    direc = nextDirec;
                    return;
                }
{'fraction_non_alphanumeric': 0.15773532152842498, 'fraction_numerical': 0.0032618825722274, 'mean_word_length': 2.578574406002501, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 83, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4470054', 'n_tokens_mistral': 2884, 'n_tokens_neox': 2805, 'n_words': 589}