Created
February 22, 2013 02:40
-
-
Save exoego/5010324 to your computer and use it in GitHub Desktop.
自家製ライブラリでドラクエVIIのバロックタワーのパズルを解いてみました。
元ネタ http://d.hatena.ne.jp/torazuka/20130221/ddd
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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