mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2024-12-24 04:46:48 +01:00
Renamed WFC to WaveFunctionCollapse, asn started transforming it.
This commit is contained in:
parent
96738f5783
commit
a501292046
@ -1,4 +1,5 @@
|
||||
#include "wfc.h"
|
||||
#include "wave_form_collapse.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace {
|
||||
@ -6,12 +7,12 @@ namespace {
|
||||
Vector<double> &normalize(Vector<double> &v) {
|
||||
double sum_weights = 0.0;
|
||||
int size = v.size();
|
||||
const double* vpr = v.ptr();
|
||||
const double *vpr = v.ptr();
|
||||
for (int i = 0; i < size; ++i) {
|
||||
sum_weights += vpr[i];
|
||||
}
|
||||
|
||||
double* vpw = v.ptrw();
|
||||
double *vpw = v.ptrw();
|
||||
double inv_sum_weights = 1.0 / sum_weights;
|
||||
for (int i = 0; i < size; ++i) {
|
||||
vpw[i] *= inv_sum_weights;
|
||||
@ -21,7 +22,7 @@ Vector<double> &normalize(Vector<double> &v) {
|
||||
}
|
||||
} //namespace
|
||||
|
||||
Array2D<uint32_t> WFC::wave_to_output() const {
|
||||
Array2D<uint32_t> WaveFormCollapse::wave_to_output() const {
|
||||
Array2D<uint32_t> output_patterns(wave.height, wave.width);
|
||||
|
||||
for (uint32_t i = 0; i < wave.size; i++) {
|
||||
@ -34,20 +35,24 @@ Array2D<uint32_t> WFC::wave_to_output() const {
|
||||
return output_patterns;
|
||||
}
|
||||
|
||||
WFC::WFC(bool periodic_output, int seed,
|
||||
//WaveFormCollapse::WaveFormCollapse() {
|
||||
//}
|
||||
|
||||
WaveFormCollapse::WaveFormCollapse(bool periodic_output, int seed,
|
||||
Vector<double> patterns_frequencies,
|
||||
Vector<Propagator::PropagatorEntry> propagator, uint32_t wave_height, uint32_t wave_width) :
|
||||
gen(seed), patterns_frequencies(normalize(patterns_frequencies)), wave(wave_height, wave_width, patterns_frequencies), nb_patterns(propagator.size()), propagator(wave.height, wave.width, periodic_output, propagator) {}
|
||||
gen(seed), patterns_frequencies(normalize(patterns_frequencies)), wave(wave_height, wave_width, patterns_frequencies), nb_patterns(propagator.size()), propagator(wave.height, wave.width, periodic_output, propagator) {
|
||||
}
|
||||
|
||||
Array2D<uint32_t> WFC::run() {
|
||||
Array2D<uint32_t> WaveFormCollapse::run() {
|
||||
while (true) {
|
||||
// Define the value of an undefined cell.
|
||||
ObserveStatus result = observe();
|
||||
|
||||
// Check if the algorithm has terminated.
|
||||
if (result == failure) {
|
||||
if (result == OBSERVE_STATUS_FAILURE) {
|
||||
return Array2D<uint32_t>(0, 0);
|
||||
} else if (result == success) {
|
||||
} else if (result == OBSERVE_STATUS_FAILURE) {
|
||||
return wave_to_output();
|
||||
}
|
||||
|
||||
@ -56,20 +61,20 @@ Array2D<uint32_t> WFC::run() {
|
||||
}
|
||||
}
|
||||
|
||||
WFC::ObserveStatus WFC::observe() {
|
||||
WaveFormCollapse::ObserveStatus WaveFormCollapse::observe() {
|
||||
// Get the cell with lowest entropy.
|
||||
int argmin = wave.get_min_entropy(gen);
|
||||
|
||||
// If there is a contradiction, the algorithm has failed.
|
||||
if (argmin == -2) {
|
||||
return failure;
|
||||
return OBSERVE_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
// If the lowest entropy is 0, then the algorithm has succeeded and
|
||||
// finished.
|
||||
if (argmin == -1) {
|
||||
wave_to_output();
|
||||
return success;
|
||||
return OBSERVE_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Choose an element according to the pattern distribution
|
||||
@ -98,5 +103,8 @@ WFC::ObserveStatus WFC::observe() {
|
||||
}
|
||||
}
|
||||
|
||||
return to_continue;
|
||||
return OBSERVE_STATUS_TO_CONTINUE;
|
||||
}
|
||||
|
||||
void WaveFormCollapse::bind_methods() {
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
#ifndef FAST_WFC_WFC_HPP_
|
||||
#define FAST_WFC_WFC_HPP_
|
||||
#ifndef WAVE_FORM_COLLAPSE_H
|
||||
#define WAVE_FORM_COLLAPSE_H
|
||||
|
||||
#include "core/reference.h"
|
||||
|
||||
#include <optional>
|
||||
#include <random>
|
||||
@ -8,13 +10,40 @@
|
||||
#include "propagator.h"
|
||||
#include "wave.h"
|
||||
|
||||
// Class containing the generic WFC algorithm.
|
||||
class WFC {
|
||||
class WaveFormCollapse : public Reference {
|
||||
GDCLASS(WaveFormCollapse, Reference);
|
||||
|
||||
public:
|
||||
enum ObserveStatus {
|
||||
OBSERVE_STATUS_SUCCESS,
|
||||
OBSERVE_STATUS_FAILURE,
|
||||
OBSERVE_STATUS_TO_CONTINUE
|
||||
};
|
||||
|
||||
Array2D<uint32_t> run();
|
||||
|
||||
ObserveStatus observe();
|
||||
|
||||
void propagate() { propagator.propagate(wave); }
|
||||
|
||||
void remove_wave_pattern(uint32_t i, uint32_t j, uint32_t pattern) {
|
||||
if (wave.get(i, j, pattern)) {
|
||||
wave.set(i, j, pattern, false);
|
||||
propagator.add_to_propagator(i, j, pattern);
|
||||
}
|
||||
}
|
||||
|
||||
WaveFormCollapse();
|
||||
WaveFormCollapse(bool periodic_output, int seed, Vector<double> patterns_frequencies,
|
||||
Vector<Propagator::PropagatorEntry> propagator, uint32_t wave_height,
|
||||
uint32_t wave_width);
|
||||
|
||||
protected:
|
||||
static void bind_methods();
|
||||
|
||||
private:
|
||||
// The random number generator.
|
||||
std::minstd_rand gen;
|
||||
|
||||
// The distribution of the patterns as given in input.
|
||||
const Vector<double> patterns_frequencies;
|
||||
|
||||
Wave wave;
|
||||
@ -22,43 +51,12 @@ private:
|
||||
// The number of distinct patterns.
|
||||
const size_t nb_patterns;
|
||||
|
||||
// The propagator, used to propagate the information in the wave.
|
||||
Propagator propagator;
|
||||
|
||||
// Transform the wave to a valid output (a 2d array of patterns that aren't in
|
||||
// contradiction). This function should be used only when all cell of the wave
|
||||
// are defined.
|
||||
Array2D<uint32_t> wave_to_output() const;
|
||||
|
||||
public:
|
||||
// Basic constructor initializing the algorithm.
|
||||
WFC(bool periodic_output, int seed, Vector<double> patterns_frequencies,
|
||||
Vector<Propagator::PropagatorEntry> propagator, uint32_t wave_height,
|
||||
uint32_t wave_width);
|
||||
|
||||
// Run the algorithm, and return a result if it succeeded.
|
||||
Array2D<uint32_t> run();
|
||||
|
||||
// Return value of observe.
|
||||
enum ObserveStatus {
|
||||
success, // WFC has finished and has succeeded.
|
||||
failure, // WFC has finished and failed.
|
||||
to_continue // WFC isn't finished.
|
||||
};
|
||||
|
||||
// Define the value of the cell with lowest entropy.
|
||||
ObserveStatus observe();
|
||||
|
||||
// Propagate the information of the wave.
|
||||
void propagate() { propagator.propagate(wave); }
|
||||
|
||||
// Remove pattern from cell (i,j).
|
||||
void remove_wave_pattern(uint32_t i, uint32_t j, uint32_t pattern) {
|
||||
if (wave.get(i, j, pattern)) {
|
||||
wave.set(i, j, pattern, false);
|
||||
propagator.add_to_propagator(i, j, pattern);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // FAST_WFC_WFC_HPP_
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user