Renamed WFC to WaveFunctionCollapse, asn started transforming it.

This commit is contained in:
Relintai 2022-04-21 20:00:42 +02:00
parent 96738f5783
commit a501292046
2 changed files with 57 additions and 51 deletions

View File

@ -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() {
}

View File

@ -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