parent
f2ed196c3e
commit
16fab455c6
@ -0,0 +1,152 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "BasicTurnManager.h"
|
||||
#include "Templates/UnrealTemplate.h"
|
||||
|
||||
namespace basic_api_classes {
|
||||
base_ability::base_ability(double cost_, double damage_, double max_activation_radius_, double splash_radius_, double linear_width_) :
|
||||
cost(cost_), damage(damage_), max_activation_radius(max_activation_radius_), splash_radius(splash_radius_), linear_width(linear_width_) {};
|
||||
|
||||
bool base_ability::is_pers_hurt(double attacker_x, double attacker_y, double activation_x, double activation_y, double defender_x, double defender_y) {
|
||||
{
|
||||
double dist = (activation_x - defender_x) * (activation_x - defender_x) +
|
||||
(activation_y - defender_y) * (activation_y - defender_y);
|
||||
if (dist + 1e-6 < splash_radius * splash_radius) return true;
|
||||
}
|
||||
{
|
||||
double dist = (attacker_x - defender_x) * (attacker_x - defender_x) +
|
||||
(attacker_y - defender_y) * (attacker_y - defender_y);
|
||||
double dist1 = (attacker_x - activation_x) * (attacker_x - activation_x) +
|
||||
(attacker_y - activation_y) * (attacker_y - activation_y);
|
||||
if (dist > dist1 + 1e-6) return false;
|
||||
|
||||
double height = defender_x * (activation_y - attacker_y) - defender_y * (activation_x - attacker_x) -
|
||||
attacker_x * activation_y + attacker_y * activation_x;
|
||||
height *= height;
|
||||
return height < ((activation_y - attacker_y)* (activation_y - attacker_y) + (activation_x - attacker_x) * (activation_x - attacker_x))*
|
||||
linear_width*linear_width;
|
||||
}
|
||||
}
|
||||
|
||||
base_personage::base_personage(double x_, double y_, double hp, double trav_cost, TArray<base_ability*>&& abils) : is_dead(false), x_coordinate(x_),
|
||||
y_coordinate(y_), hitpoints(hp), travel_cost(trav_cost), abilities(MoveTemp(abils)) {};
|
||||
|
||||
FVector2D base_personage::get_personage_cords() const{
|
||||
return FVector2D{ static_cast<float>(x_coordinate), static_cast<float>(y_coordinate) };
|
||||
}
|
||||
|
||||
double base_personage::get_hitpoints() const{
|
||||
return hitpoints;
|
||||
}
|
||||
|
||||
void base_personage::move_to_position(double new_x, double new_y, double& rest_action_points) {
|
||||
double dist = (new_x - x_coordinate) * (new_x - x_coordinate) + (new_y - y_coordinate) * (new_y - y_coordinate);
|
||||
dist = sqrt(dist);
|
||||
if (rest_action_points + 1e-6 < dist * travel_cost) {
|
||||
rest_action_points -= dist * travel_cost;
|
||||
x_coordinate = new_x, y_coordinate = new_y;
|
||||
}
|
||||
}
|
||||
|
||||
void base_personage::accept_damage(double damage) {
|
||||
if (is_dead) return;
|
||||
hitpoints -= damage;
|
||||
if (hitpoints < 1e-6) {
|
||||
hitpoints = 0;
|
||||
is_dead = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool base_personage::is_attack_startable(size_t ability_number, double attack_pos_x, double attack_pos_y, double rest_action_points) const{
|
||||
if (ability_number >= abilities.Num()) return false;
|
||||
base_ability* ba = abilities[ability_number];
|
||||
double dist = (attack_pos_x - x_coordinate) * (attack_pos_x - x_coordinate) +
|
||||
(attack_pos_y - y_coordinate) * (attack_pos_y - y_coordinate);
|
||||
return dist + 1e-6 < ba->max_activation_radius * ba->max_activation_radius && ba->cost + 1e-6 < rest_action_points;
|
||||
}
|
||||
|
||||
bool base_personage::is_pers_dead() const{
|
||||
return is_dead;
|
||||
}
|
||||
|
||||
base_player::base_player(TArray<base_personage*>&& team_) : team(MoveTemp(team_)) {};
|
||||
|
||||
BasicTurnManager::BasicTurnManager(base_player* player1_, base_player* player2_, double points_per_move, double x_min_, double x_max_, double y_min_, double y_max_) :
|
||||
player1(player1_), player2(player2_), action_points(points_per_move), current_player_action_points(action_points), x_min(x_min_), x_max(x_max_), y_min(y_min_),
|
||||
y_max(y_max_), motion_number(1), first_player_motion(true), team1_alive((player1->team).Num()), team2_alive((player2->team).Num()) {}
|
||||
|
||||
bool BasicTurnManager::check_correctness(double x, double y) const{
|
||||
return x >= x_min && x <= x_max && y >= y_min && y <= y_max;
|
||||
}
|
||||
|
||||
void BasicTurnManager::next_move() {
|
||||
current_player_action_points = action_points;
|
||||
if (!first_player_motion) ++motion_number;
|
||||
first_player_motion ^= 1;
|
||||
}
|
||||
|
||||
int BasicTurnManager::get_move_number() const{
|
||||
return motion_number;
|
||||
}
|
||||
|
||||
bool BasicTurnManager::is_first_player_move() const {
|
||||
return first_player_motion;
|
||||
}
|
||||
|
||||
size_t BasicTurnManager::first_team_alive() const {
|
||||
return team1_alive;
|
||||
}
|
||||
|
||||
size_t BasicTurnManager::second_team_alive() const {
|
||||
return team2_alive;
|
||||
}
|
||||
|
||||
void BasicTurnManager::move_command(size_t pers_num, double new_x, double new_y) {
|
||||
if (!check_correctness(new_x, new_y)) return;
|
||||
if (first_player_motion) {
|
||||
if (pers_num >= (player1->team).Num()) return;
|
||||
(player1->team)[pers_num]->move_to_position(new_x, new_y, current_player_action_points);
|
||||
}
|
||||
else {
|
||||
if (pers_num >= (player2->team).Num()) return;
|
||||
(player2->team)[pers_num]->move_to_position(new_x, new_y, current_player_action_points);
|
||||
}
|
||||
}
|
||||
|
||||
void BasicTurnManager::attack_command(size_t pers_num, size_t abil_num, double attack_x, double attack_y) {
|
||||
if (!check_correctness(attack_x, attack_y)) return;
|
||||
if (first_player_motion) {
|
||||
if (pers_num >= (player1->team).Num()) return;
|
||||
base_personage* attacker = (player1->team)[pers_num];
|
||||
if (!attacker->is_attack_startable(abil_num, attack_x, attack_y, current_player_action_points)) return;
|
||||
base_ability* attack = (attacker->abilities)[abil_num];
|
||||
current_player_action_points -= attack->cost;
|
||||
for (auto def : player2->team) {
|
||||
if (def->is_pers_dead()) continue;
|
||||
if (attack->is_pers_hurt(attacker->get_personage_cords().X, attacker->get_personage_cords().Y, attack_x, attack_y,
|
||||
def->get_personage_cords().X, def->get_personage_cords().Y)) {
|
||||
def->accept_damage(attack->damage);
|
||||
|
||||
if (def->is_pers_dead()) --team2_alive;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (pers_num >= (player2->team).Num()) return;
|
||||
base_personage* attacker = (player2->team)[pers_num];
|
||||
if (!attacker->is_attack_startable(abil_num, attack_x, attack_y, current_player_action_points)) return;
|
||||
base_ability* attack = (attacker->abilities)[abil_num];
|
||||
current_player_action_points -= attack->cost;
|
||||
for (auto def : player1->team) {
|
||||
if (def->is_pers_dead()) continue;
|
||||
if (attack->is_pers_hurt(attacker->get_personage_cords().X, attacker->get_personage_cords().Y, attack_x, attack_y,
|
||||
def->get_personage_cords().X, def->get_personage_cords().Y)) {
|
||||
def->accept_damage(attack->damage);
|
||||
|
||||
if (def->is_pers_dead()) --team1_alive;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Math/UnrealMathUtility.h"
|
||||
#include "Containers/Array.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
namespace basic_api_classes {
|
||||
|
||||
struct base_ability {
|
||||
const double cost;
|
||||
const double damage;
|
||||
const double splash_radius;
|
||||
const double linear_width;
|
||||
const double max_activation_radius;
|
||||
base_ability(double cost_, double damage_, double max_activation_radius_, double splash_radius_, double linear_width_);
|
||||
bool is_pers_hurt(double attacker_x, double attacker_y, double activation_x, double activation_y, double defender_x, double defender_y);
|
||||
~base_ability();
|
||||
};
|
||||
|
||||
|
||||
struct base_personage {
|
||||
private:
|
||||
bool is_dead;
|
||||
double x_coordinate;
|
||||
double y_coordinate;
|
||||
double hitpoints;
|
||||
const double travel_cost;
|
||||
public:
|
||||
const TArray<base_ability*> abilities;
|
||||
base_personage(double x_, double y_, double hp, double trav_cost, TArray<base_ability*>&& abils);
|
||||
FVector2D get_personage_cords() const;
|
||||
double get_hitpoints() const;
|
||||
void move_to_position(double new_x, double new_y, double& rest_action_points);
|
||||
void accept_damage(double damage);
|
||||
bool is_attack_startable(size_t ability_number, double attack_pos_x, double attack_pos_y, double rest_action_points) const;
|
||||
bool is_pers_dead() const;
|
||||
~base_personage();
|
||||
};
|
||||
|
||||
struct base_player {
|
||||
const TArray<base_personage*> team;
|
||||
base_player(TArray<base_personage*>&& team_);
|
||||
~base_player();
|
||||
};
|
||||
|
||||
|
||||
struct BasicTurnManager
|
||||
{
|
||||
private:
|
||||
bool first_player_motion;
|
||||
const base_player* player1;
|
||||
const base_player* player2;
|
||||
int motion_number;
|
||||
const double action_points;
|
||||
double current_player_action_points;
|
||||
size_t team1_alive;
|
||||
size_t team2_alive;
|
||||
const double x_min;
|
||||
const double x_max;
|
||||
const double y_min;
|
||||
const double y_max;
|
||||
bool check_correctness(double x, double y) const;
|
||||
public:
|
||||
BasicTurnManager(base_player* player1_, base_player* player2_, double points_per_move, double x_min_, double x_max_, double y_min_, double y_max_);
|
||||
void move_command(size_t pers_num, double new_x, double new_y);
|
||||
void attack_command(size_t pers_num, size_t abil_num, double attack_x, double attack_y);
|
||||
void next_move();
|
||||
int get_move_number() const;
|
||||
bool is_first_player_move() const;
|
||||
size_t first_team_alive() const;
|
||||
size_t second_team_alive() const;
|
||||
~BasicTurnManager();
|
||||
};
|
||||
|
||||
}
|
Loading…
Reference in new issue