1. 程式人生 > >“同一個世界”遊戲簡單闖關演算法

“同一個世界”遊戲簡單闖關演算法

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; } } }