Материал: РАЗРАБОТКА ИГРЫ В ВИРТУАЛЬНОЙ РЕАЛЬНОСТИ НА ТЕМУ СЕЛЕКЦИИ ПЧЕЛ НА ОСНОВЕ СТОХАСТИЧЕСКИХ ПРОЦЕССОВ

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

 

UFUNCTION(BlueprintCallable, Category = "Bees")

static void DiscoverSpecies(UBeeGenetic *bee);

 

UFUNCTION(BlueprintCallable, Category = "Bees")

static int32 DiscoveredCount();

 

UFUNCTION(BlueprintCallable, Category = "Bees")

static FBeeColors getBeeColors(TEnumAsByte<Species> species);

};

#include "BeeGenetic.h"

 

const float COMB_AMOUNT_PER_MINUTE = 0.5f;

 

// Sets default values for this component's properties

UBeeGenetic::UBeeGenetic()

{

// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features

// off to improve performance if you don't need them.

PrimaryComponentTick.bCanEverTick = false;

 

// ...

}

 

 

// Called when the game starts

void UBeeGenetic::BeginPlay()

{

Super::BeginPlay();

 

// ...

}

 

void UBeeGenetic::Init(TEnumAsByte<Species> main, TEnumAsByte<Species> sec, int32 speed, int32 fertility)

{

Main = main;

Sec = sec;

Speed = speed;

Fertility = fertility;

}

 

// Called every frame

void UBeeGenetic::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)

{

Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

 

// ...

}

 

int32 UBeeGenetic::GetSpeedValue()

{

int32 count = 0;

int32 mask = 1;

for (int i = 0; i < 8; ++i)

{

  if (mask & Speed)

  ++count;

  mask <<= 1;

}

return count;

}

 

int32 UBeeGenetic::GetFertiliryValue()

{

int32 count = 0;

int32 maskMain = 1;

int32 maskSec = 2;

for (int i = 0; i < 5; ++i)

{

  if (maskMain & Fertility || maskSec & Fertility)

  ++count;

  maskMain <<= 2;

  maskSec <<= 2;

}

return count;

}

 

int32 UBeeGenetic::GetRadiusValue()

{

int32 count = 0;

int32 maskMain = 1;

int32 maskSec = 2;

for (int i = 0; i < 3; ++i)

{

  if (maskMain & Radius || maskSec & Radius)

  ++count;

  maskMain <<= 2;

  maskSec <<= 2;

}

return count;

}

 

UBeeGenetic *UBeeGenetic::Construct(TEnumAsByte<Species> main, TEnumAsByte<Species> sec, int32 speed, int32 fertility)

{

UBeeGenetic *bee = NewObject<UBeeGenetic>();

bee->Init(main, sec, speed, fertility);

return bee;

}

 

//TODO: move this to helper functions

const int32 SPEED_GENS_COUNT = 8;

const int32 FERTILITRY_GENS_COUNT = 10;

static bool get_bit(int32 num, int32 pos)

{

return (num >> pos) & 1U;

}

 

static FString get_gens_str(int32 gen, int32 gens_count)

{

FString out;

for (int i = 0; i < gens_count; ++i)

{

  out += get_bit(gen, i) ? "1" : "0";

  if (i % 2 == 1)

  out += " ";

}

return out;

}

 

FString UBeeGenetic::GetInfoBee()

{

FString out = GetInfoSpecies();

out += ": " + GetInfoSpeed() + "; " + GetInfoFertility();

return out;

}

 

FString UBeeGenetic::GetInfoSpecies()

{

FString out;

FString mainName = UEnum::GetValueAsString(Main);

FString secName = UEnum::GetValueAsString(Sec);

if (mainName.Equals(secName))

  out = mainName;

else

  out = mainName + "-" + secName;

out += " bee";

return out;

}

 

FString UBeeGenetic::GetInfoSpeed()

{

return FString::Printf(TEXT("Speed %d %s"), GetSpeedValue(), *get_gens_str(Speed, SPEED_GENS_COUNT));

}

 

FString UBeeGenetic::GetInfoFertility()

{

return FString::Printf(TEXT("Fertility %d %s"), GetFertiliryValue(), *get_gens_str(Fertility, FERTILITRY_GENS_COUNT));

}

 

 

bool UBeeGenetic::GetGenSpeedValue(int32 index)

{

return get_bit(Speed, index) == 1;

}

 

bool UBeeGenetic::GetGenFertilityValue(int32 index)

{

return get_bit(Fertility, index) == 1;

}

 

int32 UBeeGenetic::GetProductivitySpeed()

{

int32 out = 0;

float speedCoeff = *SpeedCoeff.Find(GetSpeedValue());

out += *CombCostByTier.Find(*Tiers.FindKey(Main)) * speedCoeff;

if (Main != Sec)

{

  out += *CombCostByTier.Find(*Tiers.FindKey(Sec)) * speedCoeff;

  out *= 0.5f;

}

return out * COMB_AMOUNT_PER_MINUTE;

}

 

UBeeGenetic *UBeeGenetic::CreateMeadowBee()

{

return Construct(Species::Meadow, Species::Meadow, 15, 15);

}

 

UBeeGenetic *UBeeGenetic::CreateForestBee()

{

return Construct(Species::Forest, Species::Forest, 51, 51);

}

 

UBeeGenetic *UBeeGenetic::CreateRiverBee()

{

return Construct(Species::River, Species::River, 60, 60);

}

 

bool UBeeGenetic::IsDiscoveredSpecies(TEnumAsByte<Species> species)

{

return DiscoveredSpecies[species];

}

 

FString UBeeGenetic::GetSpeciesString(TEnumAsByte<Species> species)

{

return StaticEnum<Species>()->GetValueAsString(species);

}

 

void UBeeGenetic::DiscoverSpecies(UBeeGenetic *bee)

{

if (bee)

{

  DiscoveredSpecies[bee->Main] = true;

  DiscoveredSpecies[bee->Sec] = true;

}

}

 

int32 UBeeGenetic::DiscoveredCount()

{

int32 count = 0;

for (const auto [key, value] : DiscoveredSpecies)

{

  if (value)

  {

  ++count;

  }

}

return count;

}

 

FBeeColors UBeeGenetic::getBeeColors(TEnumAsByte<Species> species)

{

return SpeciesColors[species];

}

Приложение Б

 

Исходный код файлов InheritMutationLibrary.h и InheritMutationLibrary.cpp

#pragma once

 

#include "CoreMinimal.h"

#include "Kismet/BlueprintFunctionLibrary.h"

#include "BeeGenetic.h"

#include "InheritMutationLibrary.generated.h"

 

/**

 *

 */

UCLASS()

class BEEKEEPERVR_API UInheritMutationLibrary : public UBlueprintFunctionLibrary

{

GENERATED_BODY()

UFUNCTION(BlueprintCallable, Category = "Bees")

static UBeeGenetic *Inherit(const UBeeGenetic *p1, const UBeeGenetic *p2);

 

UFUNCTION(BlueprintCallable, Category = "Bees")

static UBeeGenetic *CopyBeeProps(const UBeeGenetic *from);

};

 

#include "InheritMutationLibrary.h"

#include "Math/UnrealMathUtility.h"

#include "Containers/Map.h"

 

const float MUTATION_GEN_CHANCE = 0.05f;

const float MUTATION_SPECIES_CHANCE = 0.4f;

const float MUTATION_SPECIES_CHANCE_PARENTS_EQUAL = 0.1f;

 

const float MUTATION_TIER_DOWN_TWO_CHANCE = 0.1f;

const float MUTATION_TIER_DOWN_ONE_CHANCE = 0.3f;

const float MUTATION_TIER_NO_CHANGE_CHANCE = 0.7f;

const float MUTATION_TIER_UP_ONE_CHANCE = 0.9f;

const float MUTATION_TIER_UP_TWO_CHANCE = 1.0f;

 

const int32 SPEED_GENS_COUNT = 8;

const int32 FERTILITRY_GENS_COUNT = 10;

 

static bool random(float less)

{

  return FMath::FRandRange(0.f, 1.f) < less;

}

 

//https://stackoverflow.com/questions/47981/how-do-i-set-clear-and-toggle-a-single-bit

static void set_bit(int32 &num, int32 pos)

{

  num |= 1UL << pos;

}