声明:浅浅探讨,需要一定的基础;当然底子不行的也可以看看只不过是稍有吃力,我力求精简将道理说明白。
要求
随机生成一个英文字母,
输入猜测的字母,
判断输入的字符是否符合规定(52个英文大小写字母),不符合提示“你输入的字母不符合规定,请重新输入:” 然后再次重新输入判断
输入的字母如果符合规定,判断输入的字母和随机生成的字母是否一样
如果不一样 提示“你猜错了,请重新输入:” 再次重新输入 判断
如果一样,询问“恭喜你猜对了!”
询问“是否继续游戏?(y/n)”Game1();
当输入错误的时候,“你猜错了xx次,还是有xx次机会请重新输入:”
如果这个错误的次数到第三次了 “你的机会已全部用完,游戏结束”Game2();
代码
internal class Program
{
static void Main(string[] args)
{Game1();}
static void Game1()
{
//猜对了跳转,选择继续跳转到这
test1:
int count = 1;
Random r = new Random();
int daXie = 65 + r.Next(26);
int xiaoXie = 97 + r.Next(26);
int flag = r.Next(2);
Console.WriteLine(flag);
char danCi = (char)(flag == 1 ? daXie : xiaoXie);
Console.WriteLine(danCi);
while (true)
{
//猜错了要求再次猜测 三次机会
test:
Console.WriteLine("输入猜测的字母");
char c = char.Parse(Console.ReadLine());
if (c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z')
{
if (c == danCi)
{
Console.WriteLine("恭喜你猜对了!");
Console.WriteLine("是否继续游戏?(y/n)");
char k = char.Parse(Console.ReadLine());
if (k == 'y') { goto test1; } else { return; }
}
else
{
Console.WriteLine("你猜错了,请重新输入");
Game2(ref count);
goto test;
}
}
else
{Console.WriteLine("你输入的字母不符合规定,请重新输入:");}
}
}
static void Game2(ref int count)
{
if (count == 3) { Console.WriteLine("你的机会已全部用完,游戏结束"); Environment.Exit(0); }
Console.WriteLine($"你猜错{count}了次,还是有{3 - count}次机会请重新输入:");
count++;
}
}
ref参数
-
定义:
ref
是Reference的缩写,表示引用传递。当使用ref
关键字传递参数时,实际上传递的是参数的引用(即内存地址),而不是参数本身的值。 -
行为:在方法内部对
ref
参数的任何修改都会反映到原始变量上。因此,使用ref
可以允许方法修改其调用者中的变量。 -
使用要求:
-
ref
参数在传递之前必须被初始化。 -
方法定义和调用时都必须显式使用
ref
关键字。
-
goto语句
- 作用域:
goto
语句的作用域仅限于它所在的函数内部。它不能用于跳转到另一个函数中的位置。 - 唯一性:每个
语句标号
在程序中必须是唯一的,不能与其他标识符(如变量名、函数名等)冲突。 - 存在性:
goto
语句中的语句标号
必须在程序中存在,否则编译器会报错。
代码细节解释
定义了count代表出错的次数,当出错时就会返回到test显示重新输入;当猜测成功后,若是选择‘y’(继续)就跳转到test1。顺序不可颠倒。
创建了两个方法是为了解耦,将Game2()嵌入到Game1()中。为什么要用ref count,是因为两个函数之间的作用域不同(即是在栈中的开辟出来的变量作用域不同),将两者之间的共同变量count的地址共享,为了将Game1()出错后的count传入到Game2()中处理。同时goto语句是不能跨函数(方法)的。