iPad游戏 Calcculator: The Game 程序自动计算求解方法
今天在iPad上下了个小游戏,主要是一个计算器的界面,有开始值,目标值,限定步数,以及一些加减乘除,还有作者脑洞想出来的功能键,主要有左移,直接把一个数加到末尾,将其中的某个数改为另一个数等等。。玩到20几关的时候感觉每道题要想一会儿才能解出来,于是有了下面的程序,写完程序就不想玩了。
游戏界面如下,就像一个真的计算器。其中紫色的2、5分别表示在当前数字最后插入2、5,+5和-5就是加减,初始值是0,限定5步,得到目标值210,想想该怎么操作?是不是不是太容易一眼看出来?这就对了,这么容易让你看出来作者怎么赚钱?
答案是:SET 2==>2, SET 5==>25, SUB 5 ==> 20, SET 5 ==>205, ADD 5 ==> 210
代码如下,用回溯的思想,DFS实现的。
package com; import com.google.common.collect.Lists; import java.util.ArrayDeque; import java.util.Deque; import java.util.List; /** * 2018-08-24 下午10:36. * */ public class Calc { public static void main(String[] args) { int n = 5; int start = 0; int target = 210; List<Num> list = Lists.newArrayList(); list.add(new Num(OpType.SET, 2)); list.add(new Num(OpType.SET, 5)); // list.add(new Num(OpType.LEFT_SHIFT, 0)); list.add(new Num(OpType.ADD, 5)); list.add(new Num(OpType.SUB, 5)); // list.add(new Num(OpType.SET, 0)); // list.add(new Num(OpType.SET, 5)); dfs(list, new ArrayDeque<>(), n, start, target); } static void dfs(List<Num> list, Deque<Num> res, int step, int last, int target) { if (list == null || list.size() == 0 || step <= 0) { return; } for (int i = 0; i < list.size(); i++) { Num num = list.get(i); int tmp = num.calc(last); if (tmp == 0xdeadbeef) { continue; } res.offer(num); if (tmp == target) { System.out.println(res); } else { dfs(list, res, step - 1, tmp, target); } res.pollLast(); } } static class Num { OpType opType; int num; protected Num(OpType opType, int num) { this.opType = opType; this.num = num; } public int calc(int last) { if (this.opType == OpType.SET) { if (last == 0) { return this.num; } else { return last * (int)Math.pow(10, this.num / 10 + 1) + this.num; } } if (this.opType == OpType.LEFT_SHIFT) { return last / 10; } if (this.opType == OpType.ADD) { return this.num + last; } if (this.opType == OpType.SUB) { return last - this.num; } if (this.opType == OpType.MUL) { return last * this.num; } else { if (last % this.num == 0) { return last / this.num; } else { return 0xdeadbeef; } } } @Override public String toString() { return "Num{" + "opType=" + opType + ", num=" + num + '}'; } } enum OpType { SET, ADD, SUB, MUL, DIV, LEFT_SHIFT; } }
上面那道题代码输出就是:
[Num{opType=SET, num=2}, Num{opType=SET, num=5}, Num{opType=SUB, num=5}, Num{opType=SET, num=5}, Num{opType=ADD, num=5}]
根据输出操作即可。
目前定义了几个基本操作,当然估计这游戏后面估计还有其他的神奇操作,我没有继续往后玩了就写到这里了。