Skip to content

Instantly share code, notes, and snippets.

@exoego
Created February 22, 2013 02:40
Show Gist options
  • Save exoego/5010324 to your computer and use it in GitHub Desktop.
Save exoego/5010324 to your computer and use it in GitHub Desktop.
自家製ライブラリでドラクエVIIのバロックタワーのパズルを解いてみました。 元ネタ http://d.hatena.ne.jp/torazuka/20130221/ddd
package net.exoego;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import net.exoego.queen.Sequence;
import net.exoego.util.function.Func1;
import net.exoego.util.function.Func2;
import net.exoego.util.function.Funcs;
import net.exoego.util.function.Predicate;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertThat;
public class DQ7BaroqueTowerPuzzle {
@Test
public void testWSSW() {
final List<Button> result = solve(new Statues(Direction.W, Direction.S, Direction.S, Direction.W));
assertThat(result, is(not(Collections.<Button>emptyList())));
System.out.println(result);
}
public static enum Direction {
N, E, W, S;
}
public static class Statues {
private final Direction top;
private final Direction right;
private final Direction bottom;
private final Direction left;
public Statues(Direction top, Direction right, Direction bottom, Direction left) {
this.top = top;
this.right = right;
this.bottom = bottom;
this.left = left;
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Statues)) {
return false;
}
final Statues statues = (Statues) o;
return bottom == statues.bottom && left == statues.left && right == statues.right && top == statues.top;
}
}
public static enum Button {
TOP_RIGHT, BOTTOM_RIGHT, BOTTOM_LEFT, TOP_LEFT;
public Statues rotateStatues(final Statues s) {
switch (this) {
case TOP_LEFT:
return new Statues(s.top, rotate(s.right), rotate(s.bottom), rotate(s.left));
case TOP_RIGHT:
return new Statues(rotate(s.top), s.right, rotate(s.bottom), rotate(s.left));
case BOTTOM_RIGHT:
return new Statues(rotate(s.top), rotate(s.right), s.bottom, rotate(s.left));
case BOTTOM_LEFT:
return new Statues(rotate(s.top), rotate(s.right), rotate(s.bottom), s.left);
default:
throw new IllegalArgumentException("unknown direction");
}
}
public String toString() {
return String.format("%s(%s)", name(), ordinal());
}
private Direction rotate(Direction dir) {
switch (dir) {
case N:
return Direction.E;
case E:
return Direction.S;
case W:
return Direction.N;
case S:
return Direction.W;
default:
throw new IllegalArgumentException("unknown direction");
}
}
}
public static List<Button> solve(final Statues statues) {
return Sequence.from(Button.values())
.map(Funcs.<Button>toSingletonList())
.iterateBreadthFirst(GROWTH)
.first(new Predicate<List<Button>>() {
private final Statues _ = new Statues(Direction.S, Direction.W, Direction.N, Direction.E);
public boolean evaluate(final List<Button> buttons) {
return Sequence.from(buttons).fold(statues, ROTATE).equals(_);
}
})
.getOrElse(Collections.<Button>emptyList());
}
private static final Func1<List<Button>, Iterable<List<Button>>> GROWTH = new Func1<List<Button>, Iterable<List<Button>>>() {
public Iterable<List<Button>> apply(final List<Button> o1) {
return Sequence.from(Button.values()).map(new Func1<Button, List<Button>>() {
public List<Button> apply(final Button last) {
final List<Button> newCombination = new ArrayList<Button>(o1);
newCombination.add(last);
return newCombination;
}
});
}
};
private static final Func2<Statues, Button, Statues> ROTATE = new Func2<Statues, Button, Statues>() {
@Override
public Statues apply(final Statues current, final Button button) {
return button.rotateStatues(current);
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment