Wrote a function that simulates the destruction of a geoblock.
Pass it the index of the block in state that would be destroyed. The function will return whatever is left in state after triggering the destruction of said block.
This commit is contained in:
parent
ae65a2f682
commit
1917de87f4
3 changed files with 95 additions and 4 deletions
|
@ -1,5 +1,5 @@
|
|||
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
|
||||
list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake-d)
|
||||
list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake-d/cmake-d)
|
||||
project(disgaea_solver D)
|
||||
|
||||
add_executable(${PROJECT_NAME}
|
||||
|
|
|
@ -1,8 +1,93 @@
|
|||
module src.disgaea_solve;
|
||||
|
||||
struct Action {
|
||||
import std.array;
|
||||
import std.algorithm : remove;
|
||||
import std.range;
|
||||
import std.stdio;
|
||||
|
||||
struct GeoPair {
|
||||
char block;
|
||||
char tile;
|
||||
char panel;
|
||||
}
|
||||
|
||||
Action[] disgaea_solve (
|
||||
struct PlyItem {
|
||||
GeoPair[] geo_pair;
|
||||
int start_item;
|
||||
}
|
||||
|
||||
private int find_starting_pair (GeoPair[] parState) {
|
||||
int[char] seen_panels;
|
||||
foreach (geo; parState) {
|
||||
int* seen_panel = geo.panel in seen_panels;
|
||||
if (seen_panel)
|
||||
++*seen_panel;
|
||||
else
|
||||
seen_panels[geo.panel] = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int[] find_all_blocks_on_panel (GeoPair[] parState, char parPanel) {
|
||||
int[] retval;
|
||||
foreach (z, geo; parState) {
|
||||
if (geo.panel == parPanel)
|
||||
retval ~= cast(int)z;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
private void morph (GeoPair[] parState, char parFrom, char parTo) {
|
||||
foreach (ref geo; parState) {
|
||||
if (geo.panel == parFrom)
|
||||
geo.panel = parTo;
|
||||
}
|
||||
}
|
||||
|
||||
private GeoPair[] simulate (GeoPair[] parState, int parDestroy) {
|
||||
assert(parDestroy < parState.length);
|
||||
int[] destroyed = [parDestroy];
|
||||
auto state = parState.dup;
|
||||
|
||||
do {
|
||||
assert(!destroyed.empty);
|
||||
const auto current = destroyed.back;
|
||||
destroyed.popBack();
|
||||
auto current_geo = state[current];
|
||||
assert(current >= 0 && current < state.length);
|
||||
state = state.remove(current);
|
||||
|
||||
auto affected = find_all_blocks_on_panel(state, current_geo.panel);
|
||||
morph(state, current_geo.panel, current_geo.block);
|
||||
destroyed ~= affected;
|
||||
} while(!destroyed.empty);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
private int evaluate_state (GeoPair[] parState, int parStart) {
|
||||
int score = 0;
|
||||
//foreach (geo; parState) {
|
||||
// switch (geo.block) {
|
||||
// case '@':
|
||||
// if (geo.panel
|
||||
//}
|
||||
|
||||
return score;
|
||||
}
|
||||
|
||||
PlyItem[] disgaea_solve (GeoPair[] parState) {
|
||||
const int starting_index = find_starting_pair(parState);
|
||||
auto new_state = simulate(parState, starting_index);
|
||||
|
||||
writeln("Original state:");
|
||||
foreach (geo; parState) {
|
||||
writef("%s/%s, ", geo.block, geo.panel);
|
||||
}
|
||||
writeln("\nState after running simulation:");
|
||||
foreach (geo; new_state) {
|
||||
writef("%s/%s, ", geo.block, geo.panel);
|
||||
}
|
||||
writeln();
|
||||
return new PlyItem[1];
|
||||
}
|
||||
|
|
|
@ -13,5 +13,11 @@ int main (string[] parArgs) {
|
|||
return 2;
|
||||
}
|
||||
|
||||
disgaea_solve.disgaea_solve([
|
||||
GeoPair('b', 'r'),
|
||||
GeoPair('y', 'b'),
|
||||
GeoPair('g', 'r'),
|
||||
GeoPair('@', 'g')
|
||||
]);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue