mirror of
https://github.com/ProgramSnail/snake_2024.git
synced 2025-12-26 16:18:45 +00:00
functional bots, small refactoring, readme edit
This commit is contained in:
parent
5299e89633
commit
7e67a3bd30
13 changed files with 179 additions and 91 deletions
|
|
@ -28,16 +28,41 @@ protected:
|
|||
target_ = map_.find_nearest_food(get_pos());
|
||||
}
|
||||
|
||||
// check for case when no food found
|
||||
if (target_.has_value()) {
|
||||
direction_ = (Vecf(target_.value()) - real_pos_).norm();
|
||||
// TODO: manually change direction
|
||||
if (target_ != prev_target_) {
|
||||
direction_ = (Vecf(target_.value()) - real_pos_).norm();
|
||||
}
|
||||
} else {
|
||||
direction_ = {};
|
||||
}
|
||||
|
||||
prev_target_ = target_;
|
||||
}
|
||||
|
||||
protected:
|
||||
const Config bot_config_;
|
||||
|
||||
std::optional<Veci> target_ = {};
|
||||
std::optional<Veci> prev_target_ = {};
|
||||
float time_from_target_set_ = 0;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
inline Bot::Config default_bot_config = {
|
||||
.time_between_targets = 0.5,
|
||||
};
|
||||
|
||||
inline Bot default_bot(Veci pos, Map &map) {
|
||||
return Bot(
|
||||
{
|
||||
.obj =
|
||||
{
|
||||
.pos = pos,
|
||||
.color = {color::GRAY},
|
||||
},
|
||||
.initial_length = 20,
|
||||
.radius = 10,
|
||||
},
|
||||
default_snake_config, default_bot_config, map);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,11 +16,11 @@ struct Object {
|
|||
};
|
||||
|
||||
struct Square : public Object {
|
||||
int side;
|
||||
int64_t side;
|
||||
};
|
||||
|
||||
struct Circle : public Object {
|
||||
int radius;
|
||||
int64_t radius;
|
||||
};
|
||||
|
||||
} // namespace canvas
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <deque>
|
||||
#include <iostream>
|
||||
#include <optional>
|
||||
|
||||
#include "Canvas.hpp"
|
||||
|
|
@ -37,7 +36,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
int eat(Veci pos, int dist) { // TODO: faster variant ?
|
||||
int eat(Veci pos, int64_t dist) {
|
||||
size_t eaten_weight = 0;
|
||||
for (auto &food : food_) {
|
||||
if ((pos - food.pos).len_sq() < dist * dist and not food.eaten) {
|
||||
|
|
@ -48,7 +47,7 @@ public:
|
|||
return eaten_weight;
|
||||
}
|
||||
|
||||
void draw(Veci offset) override {
|
||||
void draw(Veci offset) const override {
|
||||
for (const auto &food : food_) {
|
||||
Veci food_pos = utils::to_world_coord(food.pos - offset);
|
||||
if (utils::is_on_screen(food_pos) and not food.eaten) {
|
||||
|
|
@ -92,14 +91,13 @@ private:
|
|||
.x = utils::rand_to(config_.size.x),
|
||||
.y = utils::rand_to(config_.size.y),
|
||||
},
|
||||
.weight = config_.min_food_weight +
|
||||
utils::rand_to(std::abs(config_.max_food_weight -
|
||||
config_.min_food_weight)),
|
||||
.weight = utils::rand_in_range(config_.min_food_weight,
|
||||
config_.max_food_weight),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
double food_lasted(const Food &food) {
|
||||
double food_lasted(const Food &food) const {
|
||||
return ((current_gen_ - food.gen) * config_.gen_interval +
|
||||
time_from_last_gen_) /
|
||||
(config_.food_exists_gens * config_.gen_interval);
|
||||
|
|
@ -107,6 +105,7 @@ private:
|
|||
|
||||
private:
|
||||
const Config config_;
|
||||
|
||||
double time_from_last_gen_ = 0;
|
||||
size_t current_gen_ = 0;
|
||||
std::deque<Food> food_ = {};
|
||||
|
|
|
|||
|
|
@ -5,3 +5,9 @@
|
|||
constexpr Veci WORLD_SIZE = {.x = 10000, .y = 10000};
|
||||
|
||||
constexpr double MIN_CONTROL_DISTANCE = 10;
|
||||
|
||||
constexpr int64_t BOT_GEN_INTERVAL = 1000;
|
||||
|
||||
constexpr int64_t BOT_GEN_RAND_OFFSET = 200;
|
||||
|
||||
constexpr int64_t MIN_BOT_GEN_DISTANCE = 200;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ class Player : public Snake {
|
|||
public:
|
||||
using Snake::Snake;
|
||||
|
||||
uint get_score() { return get_length() - get_initial_length(); }
|
||||
|
||||
void act(float dt) override {
|
||||
int eaten = map_.eat(
|
||||
utils::to_world_coord(get_pos() + utils::get_screen_center()), 20);
|
||||
|
|
@ -24,10 +26,14 @@ public:
|
|||
move(dt);
|
||||
}
|
||||
|
||||
void draw(Veci offset) override {
|
||||
void draw(Veci offset) const override {
|
||||
Snake::draw(offset - utils::get_screen_center());
|
||||
}
|
||||
|
||||
bool touches(const SnakeObject &other, Veci offset = {}) override {
|
||||
return Snake::touches(other, offset - utils::get_screen_center());
|
||||
}
|
||||
|
||||
protected:
|
||||
void change_direction(float) override {
|
||||
Veci cursor = utils::get_cursor();
|
||||
|
|
|
|||
|
|
@ -12,12 +12,13 @@ public:
|
|||
struct Config {
|
||||
Object obj;
|
||||
uint initial_length;
|
||||
int radius;
|
||||
int64_t radius;
|
||||
};
|
||||
|
||||
SnakeObject(Config config)
|
||||
: canvas_config_(config), length_{config.initial_length},
|
||||
track_{config.obj.pos} {}
|
||||
//
|
||||
|
||||
void add(Veci pos);
|
||||
|
||||
|
|
@ -50,10 +51,10 @@ public:
|
|||
|
||||
//
|
||||
|
||||
bool touches(const SnakeObject &other);
|
||||
virtual bool touches(const SnakeObject &other, Veci offset = {});
|
||||
|
||||
protected:
|
||||
const Config canvas_config_;
|
||||
Config canvas_config_;
|
||||
|
||||
size_t length_;
|
||||
std::deque<Veci> track_;
|
||||
|
|
@ -82,7 +83,7 @@ public:
|
|||
move(dt);
|
||||
}
|
||||
|
||||
void draw(Veci offset) override { SnakeObject::draw(offset); }
|
||||
void draw(Veci offset) const override { SnakeObject::draw(offset); }
|
||||
|
||||
protected:
|
||||
virtual void change_direction(float dt) = 0;
|
||||
|
|
@ -97,3 +98,21 @@ protected:
|
|||
Vecf direction_ = {};
|
||||
float move_time_delta_ = 0;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
template <Color color = color::WHITE, Veci pos = {}>
|
||||
inline canvas::SnakeObject::Config default_snake_object_config = {
|
||||
.obj =
|
||||
{
|
||||
.pos = pos,
|
||||
.color = color,
|
||||
},
|
||||
.initial_length = 20,
|
||||
.radius = 10,
|
||||
};
|
||||
|
||||
inline Snake::Config default_snake_config = {
|
||||
.speed = 100.0,
|
||||
.move_interval = 0.01,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
namespace canvas {
|
||||
|
||||
struct Text : public Object {
|
||||
uint scale;
|
||||
uint64_t scale;
|
||||
uint value;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -65,6 +65,14 @@ inline int rand_to(int x) {
|
|||
return (is_negative ? -1 : 1) + rand() % std::abs(x);
|
||||
}
|
||||
|
||||
inline int rand_in_range(int x, int y) {
|
||||
if (x > y) {
|
||||
std::swap(x, y);
|
||||
}
|
||||
|
||||
return rand_to(y - x) + x;
|
||||
}
|
||||
|
||||
} // namespace utils
|
||||
|
||||
namespace color {
|
||||
|
|
@ -107,7 +115,7 @@ using color::Color;
|
|||
class GameObject {
|
||||
public:
|
||||
virtual void act(float dt) = 0;
|
||||
virtual void draw(Veci offset) = 0;
|
||||
virtual void draw(Veci offset) const = 0;
|
||||
|
||||
virtual ~GameObject() {}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
|
||||
template <typename T> struct Vec {
|
||||
T x = {};
|
||||
|
|
@ -78,7 +79,7 @@ template <typename T> struct Vec {
|
|||
|
||||
//
|
||||
|
||||
int len_sq() const { return dot(*this, *this); }
|
||||
T len_sq() const { return dot(*this, *this); }
|
||||
|
||||
double len() const { return std::sqrt(len_sq()); }
|
||||
|
||||
|
|
@ -86,14 +87,14 @@ template <typename T> struct Vec {
|
|||
|
||||
//
|
||||
|
||||
int static dot(Vec left, Vec right) {
|
||||
T static dot(Vec left, Vec right) {
|
||||
return left.x * right.x + left.y * right.y;
|
||||
}
|
||||
|
||||
int static cross(Vec left, Vec right) {
|
||||
T static cross(Vec left, Vec right) {
|
||||
return left.x * right.y - left.y * right.x;
|
||||
}
|
||||
};
|
||||
|
||||
using Veci = Vec<int>;
|
||||
using Veci = Vec<int64_t>;
|
||||
using Vecf = Vec<double>;
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "Vec.hpp"
|
||||
|
||||
struct World {
|
||||
float game_time = {};
|
||||
Veci prev_cursor = {};
|
||||
Veci cursor = {};
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue