程序猿玩游戏——用c语言求游戏《计算器——游戏》的解法

  1. /*
    编写人@wonder
    版本:v0.1
    
    因为对这个游戏感兴趣,想到用编程求解法,
    固编写了本程序。
    本程序用来求游戏《计算器-游戏》的解法。
    
    输入:
    开始数字start,最大步数step,目标数字target,
    为三个数字,
    (如123 3 321)
    与可用的计算按钮
    为若干字符串,用空格隔开,输入e结束。
    (如r13 *-15 r < e)。
    
    输出:
    所有可行的按键顺序,可能有多个输出。
    
    目前集成的运算有:
    +n
    -n
    *n
    /n
    <n______<<去掉最后一位
    n_______在最后加上数字n
    n=》m___将所有数字n换为数字m
    ^n______幂运算
    !_______+/-
    r_______reverse
    s_______sum
    {_______<shift
    }_______>shift
    m_______mirror
    共14种运算
    可以求出131关以内的解
    
    
    基本算法:
    1.输入数据
    2.用递归找出所有可能的操作,生成一操作顺序码
    3.对每个操作码计算,如果可行就输出
    
    以后应优化一下算法,每次递归进行一次运算
    继续增加运算,求出所有关卡。
    */
    #include<stdio.h>
    #include<stdlib.h>
    #define R 10
    
    int start,step,target;
    int OPNumber=0;
    char operate[6][R];
    int debug = 0;//将值设为1开启debug模式
    
    
    
    
    void inputDate()
    {
    	char OPstring[R];
    	int i,j;
    	printf("input start,step,target=");
    	scanf("%d%d%d",&start,&step,&target);
    	printf("input operate:\n");
    	for(i=0;i<6;i++){
    		scanf("%s",&OPstring);
    		if(OPstring[0] == 'e')break;
    		for(j=0;j<R;j++){
    			operate[i][j] = OPstring[j];
    		}
    		OPNumber++;
    	}
    	system("cls");//输入结束,清屏
    	printf("start=%d,step=%d,target=%d\n",start,step,target);
    	printf("all operate are:\n");
    	for(i=0;i<OPNumber;i++){
    		printf(operate[i]);
    		printf("\n");
    	}
    
    	printf("\n");
    	printf("\n");
    }//输入数据
    
    void outDate(int n){
    	int i=1;
    	printf("result:\n");
    	while(n!=0){
    		printf("step %d : %s\n",i,operate[n%10-1]);
    		n /= 10;
    		i++;
    	}
    	printf("\n");
    	printf("\n");
    }//对符合要求的结果输出
    //比较复杂的运算放在单独的方法里
    
    void OPadd(int *result,int number){
    	int lv=10;
    	for(number;number>lv-1;lv*=10);
    	if(*result<0)number = -number;
    	*result = *result * lv + number;
    }
    
    void OPchange(int *result,int n){
    	int number1=0,number2=0;
    	int number0 = *result;
    	int i;
    	int lv0=1,lv1=1,lv2=1;
    
    	*result = 0;
    
    	for(i=1;'0'<=operate[n%10-1][i]&&operate[n%10-1][i]<='9';i++){
    		number1 = number1*10+operate[n%10-1][i]-'0';
    		lv1 *= 10;
    	}
    	i++;
    	for(i;'0'<=operate[n%10-1][i]&&operate[n%10-1][i]<='9';i++){
    		number2 = number2*10+operate[n%10-1][i]-'0';
    		lv2 *= 10;
    	}
    
    	for(number0;number0!=0;){
    		if(number0%lv1==number1){
    			number0 /= lv1;
    			*result = *result + number2*lv0;
    			lv0 *= lv2;
    		}
    		else{
    			*result = *result + number0%10*lv0;
    			lv0 *= 10;
    			number0 /= 10;
    		}
    	}
    	//printf("number1=%d,number2=%d,lv1=%d,lv2=%d\n",number1,number2,lv1,lv2);
    	//printf("result=%d\n",result);
    	//printf("number1=%s,number2=%s",number1,number2);
    }//目前最复杂的运算,替换数字
    
    void OPreverse(int *result){
    	int some;
    	some = *result;
    	*result = 0;
    	for(some;some!=0;some /=10)
    		*result = *result * 10 + some%10;
    }//反转数字
    
    void OPsum(int *result){
    	int sum=0;
    	for(*result;*result!=0;*result/=10)
    		sum += *result % 10;
    	*result = sum;
    }//对所有数字求和
    
    void OPpow(int *result,int number){
    	int end=1;
    	int i;
    	for(i=0;i<number;i++)
    		end *= *result;
    	*result = end;
    }//幂运算
    
    void OPshift(int *result,int p){//p为标识位,0表示{,1表示}
    	int lv=10;
    	int end;
    	for(*result;*result>lv-1;lv*=10);
    	lv /= 10;
    	if(p)
    		end = *result / 10 + *result % 10 * lv;//}
    	else
    		end = *result % lv * 10 + *result / lv;//{
    	*result = end;
    }//将数字左移或右移
    
    void OPmirror(int *result){
    	int lv=1,x; 
    	for(lv;lv<*result+1;lv*=100){
    		x = *result % (lv*10) / lv;
    		*result = *result * 10 + x;
    	}
    }//镜像复制,将各数字反过来接在原数后面
    
    
    void calculate(int code){
    	char OP;
    	int number;
    	int n = code;
    	int result = start;
    	int i;
    
    	while(n!=0){
    		OP = operate[n%10-1][0];
    		number = 0;
    		i=1;
    
    		if(operate[n%10-1][1]=='-')i++;//解析出正负
    		for(i;'0'<=operate[n%10-1][i]&&operate[n%10-1][i]<='9';i++){
    			number = number*10+operate[n%10-1][i]-'0';
    		}//解析出操作中数字
    		if(operate[n%10-1][1]=='-')
    			number = -number;//解析出正负
    		if(OP == '+')//分支判断出改进行什么操作
    			result += number;
    		else if(OP == '-')
    			result -= number;
    		else if(OP == '*')
    			result *= number;
    		else if(OP == '/'){
    			if(result % number == 0)
    				result /= number;
    			else
    				break;
    		}//当除法结果为小数时,判为失败
    		else if(OP == '<')
    			result /= 10;
    		else if(OP == 'a')
    			OPadd(&result,number);
    		else if(OP == '>')
    			OPchange(&result,n);
    		else if(OP == '^')
    			OPpow(&result,number);
    		else if(OP == '!')
    			result = -result;
    		else if(OP == 'r')
    			OPreverse(&result);
    		else if(OP == 's')
    			OPsum(&result);
    		else if(OP == '{')
    			OPshift(&result,0);
    		else if(OP == '}')
    			OPshift(&result,1);
    		else if(OP == 'm')
    			OPmirror(&result);
    		n /= 10;
    		if(debug)printf("result=%d\n",result);//测试用
    		if(result >9999999)break;//当结果超限时判为异常
    
    		if(result == target)
    			outDate(code);	//结果正确输出
    	}
    
    }//根据操作码计算,关键函数
    
    void allCode(int n,int s)
    {
    	if(n==0){
    		if(debug)printf("\ncode=%d\n",s);//测试用,显示操作码
    		calculate(s);
    	}
    	else
    		for(int i=1;i<=OPNumber;i++)
    			allCode(n-1,s*10+i);
    }//利用递归,找出所有可能的操作顺序,算出操作码,交给calculate函数计算
    //注意操作是从最后一位向前操作
    
    
    void renew(){
    	OPNumber = 0;
    }
    
    int main()
    {
    	while(true){
    		renew();
    		inputDate();
    		allCode(step,0);
    	}
    	return 0;
    }//主函数


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值