“同一個世界”遊戲簡單闖關演算法
阿新 • • 發佈:2019-01-04
package com.xxx;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
public class SameWorld {
public static void main(String[] args) throws InterruptedException {
//0:白;1:黑
int[][] world = {
{1 , 0, 0, 0, 0, 1},
{-1, 1, 0, 0, 1, -1},
{-1, 1, 0, 0, 1, -1},
{-1, 1, 0, 0, 1, -1},
{-1, 1, 0, 0, 1, -1},
{-1, 1, 0, 0, 1, -1},
{1, 0, 0, 0, 0, 1}};
int[] start1Pos = {6, 0};
int[] start2Pos = {6, 5};
int initS1 = world.length;
int initS2 = world.length;
//預設嘗試50步
int retryStepCount = 20;
int maxX = world.length - 1;//從0算起
int maxY = world[0].length - 1;
//建立樹1
Node startN1 = new Node(start1Pos[0], start1Pos[1], null, world);
createTree(world, startN1, maxX, maxY);
//建立樹2
Node startN2 = new Node(start2Pos[0], start2Pos[1], null, world);
createTree(world, startN2, maxX, maxY);
//遍歷樹
overFlag:
for (int s1 = initS1; s1 <= retryStepCount; s1++) {
List<Node> list = findSomeStepsNode(startN1, s1);
for (Node node : list) {
int[][] world1 = copyArray(world);
run(world1, node);
//第二個起點開始跑
for (int s2 = initS2; s2 <= retryStepCount; s2++) {
List<Node> list2 = findSomeStepsNode(startN2, s2);
for (Node node2 : list2) {
int[][] world2 = copyArray(world1);
run(world2, node2);
//是否全部為同一顏色
Map<Integer, Void> map = new HashMap<>();
for (int x = 0; x <= maxX; x++) {
for (int y = 0; y <= maxY; y++) {
if (world2[x][y] != -1) {
map.put(world2[x][y], null);
}
}
}
if (map.size() == 1) {
System.out.println("起點一:");
printStep(node, world, 10);
System.out.println("起點二:");
printStep(node2, world, 20);
break overFlag;
}
}
}
}
}
}
public static int[][] copyArray(int[][] array) {
int[][] copyArray = new int[array.length][];
for (int i = 0; i < array.length; i++) {
copyArray[i] = new int[array[i].length];
for (int j = 0; j < array[i].length; j++) {
copyArray[i][j] = array[i][j];
}
}
return copyArray;
}
private static void printStep(Node node, int[][] world, int pathValue) {
//列印座標
Node temp = node;
Node parent;
Stack stacks = new Stack();
stacks.push("[" + node.x + "," + node.y + "]");
while ((parent = temp.parent) != null) {
stacks.push("[" + parent.x + "," + parent.y + "]");
temp = parent;
}
while (!stacks.isEmpty()) {
System.out.println(stacks.pop());
}
}
private static void run(int[][] num, Node node) {
Node temp = node;
num[node.x][node.y] = convertColor(num[node.x][node.y]);
Node parent;
while ((parent = temp.parent) != null) {
num[parent.x][parent.y] = convertColor(num[parent.x][parent.y]);
temp = temp.parent;
}
}
private static List<Node> findSomeStepsNode(Node startNode, int retryStepCount) {
List<Node> res = new ArrayList();
Stack<Node> stack = new Stack();
stack.push(startNode);
while (!stack.isEmpty()) {
Node node = stack.pop();
//判斷是否等於指定次數
int toTopStepCount = calc2TopSetpCount(node);
if (toTopStepCount == retryStepCount) {
res.add(node);
}
if (node.up != null) {
stack.push(node.up);
}
if (node.down != null) {
stack.push(node.down);
}
if (node.left != null) {
stack.push(node.left);
}
if (node.right != null) {
stack.push(node.right);
}
}
return res;
}
private static int calc2TopSetpCount(Node startN) {
int count = 1;
Node temp = startN;
while ((temp.parent) != null) {
count++;
temp = temp.parent;
}
return count;
}
private static int convertColor(int color) {
return (color == 1 ? 0 : 1);
}
private static void createTree(int[][] world, Node startN, int maxX, int maxY) {
Node up = null;
Node down = null;
Node left = null;
Node right = null;
//上
int uX = startN.x - 1;
if (uX >= 0) {
Node tempUp = new Node(uX, startN.y, startN, world);
if (world[tempUp.x][tempUp.y] != -1 && !existInTreeBranch(tempUp, startN)) {
up = tempUp;
}
}
//下
int dX = startN.x + 1;
if (dX <= maxX) {
Node tempDown = new Node(dX, startN.y, startN, world);
if (world[tempDown.x][tempDown.y] != -1 && !existInTreeBranch(tempDown, startN)) {
down = tempDown;
}
}
//左
int lY = startN.y - 1;
if (lY >= 0) {
Node tempLeft = new Node(startN.x, lY, startN, world);
if (world[tempLeft.x][tempLeft.y] != -1 && !existInTreeBranch(tempLeft, startN)) {
left = tempLeft;
}
}
//右
int rY = startN.y + 1;
if (rY <= maxY) {
Node tempRight = new Node(startN.x, rY, startN, world);
if (world[tempRight.x][tempRight.y] != -1 && !existInTreeBranch(tempRight, startN)) {
right = tempRight;
}
}
startN.up = up;
startN.down = down;
startN.left = left;
startN.right = right;
if (startN.up == null && startN.down == null && startN.left == null && startN.right == null) {
return;
}
if (startN.up != null) {
createTree(world, startN.up, maxX, maxY);
}
if (startN.down != null) {
createTree(world, startN.down, maxX, maxY);
}
if (startN.left != null) {
createTree(world, startN.left, maxX, maxY);
}
if (startN.right != null) {
createTree(world, startN.right, maxX, maxY);
}
}
private static boolean existInTreeBranch(Node tempDown, Node startN) {
if (startN == null) {
return true;
}
if (tempDown.equals(startN)) {
return true;
}
Node parent;
Node temp = startN;
while ((parent = temp.parent) != null) {
if (parent.equals(tempDown)) {
return true;
}
temp = temp.parent;
}
return false;
}
static class Node {
int color;
int x;
int y;
Node parent;
Node up;
Node down;
Node left;
Node right;
Node(int x, int y, Node parent, int[][] world) {
this.x = x;
this.y = y;
this.parent = parent;
color = world[x][y];
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Node node = (Node) o;
if (x != node.x) return false;
return y == node.y;
}
@Override
public int hashCode() {
int result = x;
result = 31 * result + y;
return result;
}
}
}