“同一个世界”游戏简单闯关算法

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;
        }
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值