流程:1、系统产生四个随机数 1-13 J Q K 计算的内容是1
四个随机数字是打印在屏幕上的(可以重复)
2、用户输入算式,算式结果是24
3、由电脑计算算式的结果是否正确,如果正确,继续出4个数字,
根据上一步来的,每一步都会有新的算式,
4、用户退出, 输入q可以退出
或者发牌之前做用户询问,是否继续发牌.(y/n)
循环结构
找到循环变量,循环变量还需要初始化,判断出循环条件
可以用户确认发牌作为循环控制量,如果循环发牌变量为n,可以退出.
Char s=’y’;
While(s!=’n’){
}
用for循环
for(char s=’y’;s!=’n’;){
}
这两种方式的编程,必须把变量控制的逻辑理清楚,才能控制流程。
如果用char接收 nextChar,很可能会报错
遇到游戏类的编程,循环外层直接套一个死循环
(规定:游戏类退出一般都是主角生命值或者用户的某种操作决定,否则一直在游戏中)
While(true){
空间做任何游戏逻辑
String ch=Scanner.next();
If (ch.equals(“y”)){
}
}
这样节省存储空间
编写游戏类程序的思维:
- 确定基本架构(游戏的架构:死循环中套用一个退出条件)
- 确定全局变量
每个游戏类程序,都会有一个用户玩家名字, username全局
只要有交互的内容,Scanner ,直接把Scanner算作全局
- 实现逻辑
5 3 2 K
(5+2+K)*3
5 5 10 4
(+
合法性:只能通过正则判断
^[(,),1-10,J,Q,K][1-10,J,Q,K,+,-,*,/]$
无法统一
两个
^([1-10,J,Q,K][+,-,*,/][1-10,J,Q,K][),1-10,J,Q,K]$
只要算式中有括号,很难判断合法性
数学方法: 先算括号里面,再算括号外面
先找括号里面的找出来
字符串操作中,indexOf
计算括号里面的思维
public class test_indexOf {
public static void main(String[] args) {
//这个字符串长度为8,第一个值0,最后一个位置7
//注意特殊数字10,10分成两位是1和0,两位代表一个数字
//作业:
//考虑1\没有括号,2\有1个括号
//3\两个括号
//(5+3)*(1+2)
//2+2+2*10
//其它情况
// String biaoda="5*6*8/10";
// String biaoda="(5+2+K)*3";
String biaoda="2+2+2*10";
System.out.println(biaoda.indexOf("("));
//indexOf输出字符串中的第0个位置,可以输出右括号在字符串的位置,这个位置从0开始
//把字符串拆开,每一个是一个字符,就是char,在字符串有函数charAt(位置)
System.out.println(biaoda.indexOf(")"));
//这里把(开始位置定义变量,把)结束位置定义变量,中间的可以进行有效性判断和计算
int index_first=biaoda.indexOf("(");
// if(index_first==-1){
// index_first=-1;
// }
int index_last=biaoda.indexOf(")");
if(index_last==-1){
//字符串有长度函数length()
index_last=biaoda.length();
}
//和差积商的计算结果有一值放在循环外
int num1=0;
//把记录的flag做一个全局,给flag一个没有的符号初始化
char flag='|';
//全局有传有收
num1=test_for(index_first+1,index_last,num1,biaoda,flag);
if(index_last<biaoda.length()){
num1=test_for(index_last+1,biaoda.length(),num1,biaoda,flag);
}
//再计算括号外面的结果
//循环计算结束,打印全局的num1
System.out.println(num1);
}
//函数需要根据flag来做事情,所以传入flag,凡是出现变量报错,证明这段函数需要变量,再把变量做参数传入,
//函数中缺少计算的量,采用传参就可以
//这个函数中有主函数中的全局,num1是主函数的全局,只要有全局,把全局返回
//默认返回是void,是空,把void改成返回全局的int
public static int test_switch(char flag,int num1,int num2){
// System.out.println("---------------------");
// System.out.println(num2);
//如果num2传入一个0,证明num2之前的数字1,num1已加过一个1
switch(flag){
case '|':
//证明没有操作
if (num2==0) {
num1 += 9;
}else{
num1=num2;
}
break;
case '+':
//加减乘除=后面的数值还是需要变化,不是固定的1
if (num2==0){
num1+=9;
}else{
num1+=num2;
}
break;
case '-':
if (num2==0){
num1-=9;
}else{
num1-=num2;
}
break;
case '*':
//num2是0,不能做乘法
if(num2!=0){
num1*=num2;
}else{
num1*=10;
}
break;
case '/':
//num2,不能做除法
if(num2!=0){
num1/=num2;
}else{
num1/=10;
}
}
//如果有全局,在计算中还有全局变量参与,最后返回全局
return num1;
}
//复制后,错的标红的作输入变量,
//函数里:如果大括号没有错误,看一下返回值
public static int test_for(int start,int end,int num1,String biaoda,char flag) {
// for(int i=index_first+1;i<index_last;i++){
for (int i = start; i < end; i++) {
// System.out.println(biaoda.charAt(i));
//()内的字符全部取出,碰到数字记录,一个加法的和是由被加数和加数决定的
//这是记录加数和被加数的;也可以sum和num的关系,num是记数的,sum是求和的
//charAt(i)输出的字符可能是J ,Q,K。如果直接接收整型不合适,这里用一个中间变量
//这里把num1记录当前的字符
// int num1=0;
char num1_mid = biaoda.charAt(i);
//记录操作的标志位,放在循环里面,每次循环flag定义一次,每次循环flag变化,不能让flag发生变化,
//记录的操作在遇到第二个操作数之前都是有效的。所以flag应该是全局
//记录标志位后,只有再有一个数,就可以使用
//如果是J,Q,K就转化成1
switch (num1_mid) {
case 'J':
//把后面的switch复制到每一个switch里面,这段代码才能一直有效
//这里简化操作,把这段不断重复,影响结构的代码提出来,变成一个函数,函数名不能是main,前面的内容一致
//注意test_switch有结果返回,有结果返回就要接收,使用全局来接收
num1 = test_switch(flag, num1, 1);
// num1+=1;
break;
case 'Q':
num1 = test_switch(flag, num1, 1);
// num1+=1;
break;
case 'K':
num1 = test_switch(flag, num1, 1);
// num1+=1;
break;
case '+':
//当加减乘除任一开始操作时,只有一个数存在,不能做任何运算,只能等另一个数过来,才能运算
//遇到这类问题,你把这个符号当作标志位
flag = '+';
break;
case '-':
//只记录,不能计算
flag = '-';
break;
case '*':
flag = '*';
break;
case '/':
flag = '/';
break;
default:
// System.out.println(Integer.parseInt(num1_mid+""));
num1 = test_switch(flag, num1, Integer.parseInt(num1_mid + ""));
//把char型加上一个字符,只不过这个字符是""
// num1+=Integer.parseInt(num1_mid+"");
}
//一个一个打印,看错误的原因
// System.out.println(num1);
//如果碰到加减乘除,就把这两个数计算
}
return num1;
}
}