人力资源机 https://blog.csdn.net/nameofcsdn/article/details/73656618
目录
在我玩人力资源机快通关的时候才发现,每一关的解法是可以复制成文本的,然后任何时候都可以用文本直接粘贴。
于是我分析到,这个游戏处理玩家操作的其实主要就2个模块,一个是把玩家的操作变成文本,一个是执行文本命令。
然后我突然觉得,这不就是标准的指令语言吗!(虽然一开始就觉得是编程游戏,但是对于它的语言类型并没有一个清晰的感知)
下面,我按照学习BF语言https://blog.csdn.net/nameofcsdn/article/details/110231730的经验,研究一下人力资源机指令语言,简称HR语言。
一,基础指令集
(1)输入输出指令
INBOX
OUTBOX
(2)计算指令
COPYFROM x
COPYTO x
ADD x
SUB x
BUMPA x
BUMPS x
其中x表示数组的第x个格子
(3)跳转指令
JUMP a
JUMPZ a
JUMPN a
a表示goto标签
二,翻译程序
我们来用c++把HR语言翻译成c++
#include<iostream>
#include<string>
#include<map>
#include<algorithm>
using namespace std;
string hr[] = {
"INBOX",
"OUTBOX",
"COPYFROM x",
"COPYTO x",
"ADD x",
"SUB x",
"a:"
"JUMP a",
"JUMPZ a",
"JUMPN a",
"BUMPUP x",
"BUMPDN x"
};
bool contain(string s1, string s2)
{
if (s1.length() < s2.length())return false;
for (int i = 0; i < s2.length(); i++)if (s1[i] != s2[i])return false;
return true;
}
string remove(string s1, string s2)
{
int keyLen = s2.length();
return s1.substr(keyLen, s1.length() - keyLen);
}
string translate(string cmd)
{
string ans;
if (cmd == "INBOX") {
return "cin >> reg;\n";
}
if (cmd == "OUTBOX") {
return "cout<<reg;\n";
}
if (contain(cmd, "COPYFROM")) {
ans = "reg = paper[";
return ans + remove(cmd, "COPYFROM") + "]; \n";
}
if (contain(cmd, "COPYTO")) {
ans = "paper[";
return ans + remove(cmd, "COPYTO") + "] = reg; \n";
}
if (contain(cmd, "ADD")) {
ans = "reg += paper[";
return ans + remove(cmd, "ADD") + "]; \n";
}
if (contain(cmd, "SUB")) {
ans = "reg -= paper[";
return ans + remove(cmd, "SUB") + "]; \n";
}
if (contain(cmd, "JUMPZ")) {
ans = "if(reg == 0)goto";
return ans + remove(cmd, "JUMPZ") + "; \n";
}
if (contain(cmd, "JUMPN")) {
ans = "if(reg < 0)goto";
return ans + remove(cmd, "JUMPZ") + "; \n";
}
if (contain(cmd, "JUMP")) {
ans = "goto";
return ans + remove(cmd, "JUMP") + "; \n";
}
if (contain(cmd, "BUMPUP")) {
ans = "reg = ++paper[";
return ans + remove(cmd, "BUMPUP") + "]; \n";
}
if (contain(cmd, "BUMPDN")) {
ans = "reg = --paper[";
return ans + remove(cmd, "BUMPDN") + "]; \n";
}
return cmd + "\n";
}
int main()
{
for (int i = 0; i < sizeof(hr) / sizeof(string); i++)cout << translate(hr[i]);
return 0;
}
以第17关 VIP休息室 为例:
string hr[] = {
"a:",
"b:",
"INBOX",
"JUMPN d",
"INBOX",
"JUMPN e",
"c :",
"COPYFROM 4",
"OUTBOX",
"JUMP b",
"d :",
"INBOX",
"JUMPN c",
"e :",
"COPYFROM 5",
"OUTBOX",
"JUMP a"
};
换掉hr数组之后执行,输出:
三,执行程序
用c++执行上面翻译的程序片段:
#include<iostream>
using namespace std;
int paper[30];
int reg;
void init()
{
paper[4] = 0, paper[5] = 1;
}
void exec()
{
a:
b:
cin >> reg;
if (reg < 0)goto d;
cin >> reg;
if (reg < 0)goto e;
c:
reg = paper[4];
cout << reg;
goto b;
d:
cin >> reg;
if (reg < 0)goto c;
e:
reg = paper[5];
cout << reg;
goto a;
}
int main()
{
init();
exec();
return 0;
}
其中init函数是根据关卡给出的初始居民而定,exec函数内就完全是上面翻译的程序片段。
四,其他指令
1,注释
注释严格说来不算指令,刚好人力资源机里面注释是单独放在最后面的,比如:
-- HUMAN RESOURCE MACHINE PROGRAM --
INBOX
OUTBOX
DEFINE LABEL 9
eJzTZGBguOvyL9PcKT6/xEGibINdZ/MGO6cuRfvfE/a7vt9c4rBiV48Jwx6gMgaXCP4ivdBXHXqhsgsF
wvrWXQlfscs2RvBIYZzgEf7UFbse5sZMu1l4s+Fm4cWatoLfE9oK5m/TLi46CdKb2/2o5XxL5tHmPrO1
K2aIzC1a6t33eGnpotcLu6/aLlY6c3ul+1aXdXor5+4KnlS/m3nqpT2yC533Buys3/3lHsMwAXuf7Fw7
49n0NRNe/ll/6YXPbpEX/Xu/P8vdY/mMY6fls6YtYc/tN4U959g50O4cBSMLAAC8Nme8;
所以注释部分可以不用理会。
2,指针
指针的语法,就是6个计算指令**** x可以变成**** [x],前者是第x个格子的数,后者是第[第x个格子的数]个格子的数,也就是指针。
首先把翻译程序优化一下:
#include<iostream>
#include<string>
#include<map>
#include<algorithm>
using namespace std;
string hr[] = {
"a:",
"b:",
"INBOX",
"JUMPN d",
"INBOX",
"JUMPN e",
"c :",
"COPYFROM 4",
"OUTBOX",
"JUMP b",
"d :",
"INBOX",
"JUMPN c",
"e :",
"COPYFROM 5",
"OUTBOX",
"JUMP a"
};
bool contain(string s1, string s2)
{
if (s1.length() < s2.length())return false;
for (int i = 0; i < s2.length(); i++)if (s1[i] != s2[i])return false;
return true;
}
string remove(string s1, string s2)
{
int keyLen = s2.length();
string ans = s1.substr(keyLen, s1.length() - keyLen);
while(ans[0]==' ')ans = ans.substr(1, ans.length() - 1);
return ans;
}
string translate(string cmd)
{
string ans;
if (cmd == "INBOX") {
return "cin >> reg;\n";
}
if (cmd == "OUTBOX") {
return "cout<<reg;\n";
}
if (contain(cmd, "COPYFROM")) {
ans = "reg = paper[";
return ans + remove(cmd, "COPYFROM") + "]; \n";
}
if (contain(cmd, "COPYTO")) {
ans = "paper[";
return ans + remove(cmd, "COPYTO") + "] = reg; \n";
}
if (contain(cmd, "ADD")) {
ans = "reg += paper[";
return ans + remove(cmd, "ADD") + "]; \n";
}
if (contain(cmd, "SUB")) {
ans = "reg -= paper[";
return ans + remove(cmd, "SUB") + "]; \n";
}
if (contain(cmd, "JUMPZ")) {
ans = "if(reg == 0)goto ";
return ans + remove(cmd, "JUMPZ") + "; \n";
}
if (contain(cmd, "JUMPN")) {
ans = "if(reg < 0)goto ";
return ans + remove(cmd, "JUMPZ") + "; \n";
}
if (contain(cmd, "JUMP")) {
ans = "goto ";
return ans + remove(cmd, "JUMP") + "; \n";
}
if (contain(cmd, "BUMPUP")) {
ans = "reg = ++paper[";
return ans + remove(cmd, "BUMPUP") + "]; \n";
}
if (contain(cmd, "BUMPDN")) {
ans = "reg = --paper[";
return ans + remove(cmd, "BUMPDN") + "]; \n";
}
return cmd + "\n";
}
int main()
{
for (int i = 0; i < sizeof(hr) / sizeof(string); i++)cout << translate(hr[i]);
return 0;
}
然后新增指针指令:
#include<iostream>
#include<string>
#include<map>
#include<algorithm>
using namespace std;
string hr[] = {
"a:",
"b:",
"INBOX",
"JUMPN d",
"INBOX",
"JUMPN e",
"c :",
"COPYFROM 4",
"OUTBOX",
"JUMP b",
"d :",
"INBOX",
"JUMPN c",
"e :",
"COPYFROM 5",
"OUTBOX",
"JUMP a"
};
bool contain(string s1, string s2)
{
if (s1.length() < s2.length())return false;
for (int i = 0; i < s2.length(); i++)if (s1[i] != s2[i])return false;
return true;
}
string remove(string s1, string s2)
{
int keyLen = s2.length();
string ans = s1.substr(keyLen, s1.length() - keyLen);
while(ans[0]==' ')ans = ans.substr(1, ans.length() - 1);
return ans;
}
string primerOrNot(string s)// 1 12 [1] [12] 四种情况
{
if (s.length() < 3)return s;
return "paper" + s;
}
string translate(string cmd)
{
string ans;
if (cmd == "INBOX") {
return "cin >> reg;\n";
}
if (cmd == "OUTBOX") {
return "cout<<reg;\n";
}
if (contain(cmd, "COPYFROM")) {
ans = "reg = paper[";
return ans + primerOrNot(remove(cmd, "COPYFROM")) + "]; \n";
}
if (contain(cmd, "COPYTO")) {
ans = "paper[";
return ans + primerOrNot(remove(cmd, "COPYTO")) + "] = reg; \n";
}
if (contain(cmd, "ADD")) {
ans = "reg += paper[";
return ans + primerOrNot(remove(cmd, "ADD")) + "]; \n";
}
if (contain(cmd, "SUB")) {
ans = "reg -= paper[";
return ans + primerOrNot(remove(cmd, "SUB")) + "]; \n";
}
if (contain(cmd, "JUMPZ")) {
ans = "if(reg == 0)goto ";
return ans + remove(cmd, "JUMPZ") + "; \n";
}
if (contain(cmd, "JUMPN")) {
ans = "if(reg < 0)goto ";
return ans + remove(cmd, "JUMPZ") + "; \n";
}
if (contain(cmd, "JUMP")) {
ans = "goto ";
return ans + remove(cmd, "JUMP") + "; \n";
}
if (contain(cmd, "BUMPUP")) {
ans = "reg = ++paper[";
return ans + primerOrNot(remove(cmd, "BUMPUP")) + "]; \n";
}
if (contain(cmd, "BUMPDN")) {
ans = "reg = --paper[";
return ans + primerOrNot(remove(cmd, "BUMPDN")) + "]; \n";
}
return cmd + "\n";
}
int main()
{
for (int i = 0; i < sizeof(hr) / sizeof(string); i++)cout << translate(hr[i]);
return 0;
}
以第29关为例:
string hr[] = {
"a:",
"INBOX",
"COPYTO 12",
"COPYFROM[12]",
"OUTBOX",
"JUMP a"
};
换掉hr数组之后执行,输出:
a:
cin >> reg;
paper[12] = reg;
reg = paper[paper[12]];
cout<<reg;
goto a;
3,字符
这部分也不重要,字符和整型本就是本质一样的。
至于翻译程序,应该用char和int的互转再加点重载就行。