Skip to main content

4月日 游戏

关键词检测(str.Contains())

请编写一个 C# 控制台程序,实现以下功能:

题目要求:

  1. 提示用户输入一段文本(字符串)

  2. 提示用户输入一个关键词

  3. 使用 Contains() 方法判断该文本中是否包含该关键词

  4. 输出结果:

    • 如果包含,输出:包含该关键词
    • 如果不包含,输出:不包含该关键词
  5. 进阶要求:忽略大小写进行判断(例如 Lovelove 也算匹配)

运行:

请输入一段文本:
I love programming in C#

请输入关键词:
love

输出:
包含该关键词

代码

using System;

class Program
{
static void Main()
{
Console.WriteLine("请输入一段文本:");
string text = Console.ReadLine() ?? string.Empty;

Console.WriteLine("请输入关键词:");
string keyword = Console.ReadLine() ?? string.Empty;

// 忽略大小写进行判断
bool contains = text.ToLower().Contains(keyword.ToLower());

if (contains)
{
Console.WriteLine("包含该关键词");
}
else
{
Console.WriteLine("不包含该关键词");
}
}
}

查找关键词位置(IndexOf())

请编写一个 C# 控制台程序,实现以下功能:

  1. 提示用户输入一段文本(字符串)

  2. 提示用户输入一个关键词

  3. 使用 IndexOf() 方法查找关键词第一次出现的位置

  4. 输出结果:

    • 如果找到,输出:关键词第一次出现的位置是:X
    • 如果未找到,输出:未找到该关键词

运行:

请输入一段文本:
Hello C# world

请输入关键词:
C#

输出:
关键词第一次出现的位置是:6

进阶挑战(建议一定尝试):

👉 查找关键词所有出现的位置

例如:

文本:abcabcabc
关键词:abc
输出:
出现位置:0
出现位置:3
出现位置:6

提示:

  • IndexOf() 找不到时返回 -1
  • 可以配合循环继续查找后面的内容,例如:
int index = str.IndexOf(keyword);
while (index != -1)
{
Console.WriteLine(index);
index = str.IndexOf(keyword, index + keyword.Length);
}

基础需求

using System;

class Program
{
static void Main()
{
Console.WriteLine("请输入一段文本:");
string text = Console.ReadLine() ?? string.Empty;

Console.WriteLine("请输入关键词:");
string keyword = Console.ReadLine() ?? string.Empty;

// 查找关键词第一次出现的位置
int index = text.IndexOf(keyword);

if (index != -1)
{
Console.WriteLine($"关键词第一次出现的位置是:{index}");
}
else
{
Console.WriteLine("未找到该关键词");
}
}
}

进阶需求

using System;

class Program
{
static void Main()
{
Console.WriteLine("请输入一段文本:");
string text = Console.ReadLine() ?? string.Empty;

Console.WriteLine("请输入关键词:");
string keyword = Console.ReadLine() ?? string.Empty;

// 如果关键词为空,直接结束
if (string.IsNullOrEmpty(keyword))
{
Console.WriteLine("关键词不能为空。");
return;
}

Console.WriteLine($"\n在文本中查找所有 \"{keyword}\" 的位置:");

int index = 0;
int count = 0;

// 循环查找,直到 IndexOf 返回 -1
while ((index = text.IndexOf(keyword, index)) != -1)
{
Console.WriteLine($"出现位置:{index}");
index += keyword.Length; // 从该关键词之后继续查找
count++;
}

if (count == 0)
{
Console.WriteLine("未找到该关键词。");
}
else
{
Console.WriteLine($"\n总共找到 {count} 次。");
}
}
}

string.StartsWith()

题目要求

编写一个 C# 控制台程序,实现字符串前缀校验功能,完整覆盖 StartsWith() 核心用法:

  1. 提示用户输入一段主字符串(任意文本);
  2. 提示用户输入一个前缀字符串(要判断的开头内容);
  3. 实现3个核心功能:
    • 功能1:严格匹配(区分大小写)判断主字符串是否以前缀开头;
    • 功能2:忽略大小写匹配判断主字符串是否以前缀开头;
    • 功能3:批量判断:预设3个固定前缀,检查主字符串是否以其中任意一个开头;
  4. 清晰输出每一步的判断结果。

核心知识点

StartsWith() 两个关键用法:

  1. 主字符串.StartsWith(前缀)区分大小写 匹配;
  2. 主字符串.StartsWith(前缀, StringComparison.OrdinalIgnoreCase)忽略大小写 匹配。

完整参考代码

using System;

class StringStartsWithExercise
{
static void Main()
{
// 1. 获取用户输入
Console.WriteLine("===== StartsWith() 方法训练程序 =====");
Console.Write("请输入主字符串:");
string mainStr = Console.ReadLine();

Console.Write("请输入要判断的前缀字符串:");
string prefix = Console.ReadLine();
Console.WriteLine("-------------------------------------");

// 2. 功能1:区分大小写判断(基础用法)
bool isStrictMatch = mainStr.StartsWith(prefix);
Console.WriteLine($"【严格匹配(区分大小写)】是否以前缀开头:{isStrictMatch}");

// 3. 功能2:忽略大小写判断(进阶用法)
bool isIgnoreCaseMatch = mainStr.StartsWith(prefix, StringComparison.OrdinalIgnoreCase);
Console.WriteLine($"【忽略大小写匹配】是否以前缀开头:{isIgnoreCaseMatch}");
Console.WriteLine("-------------------------------------");

// 4. 功能3:批量前缀判断(综合应用)
string[] prefixArray = { "C#", "Hello", "Test" };
bool hasAnyPrefix = false;

// 遍历数组,用StartsWith判断任意匹配
foreach (string item in prefixArray)
{
if (mainStr.StartsWith(item, StringComparison.OrdinalIgnoreCase))
{
hasAnyPrefix = true;
break; // 找到匹配项直接退出循环
}
}

Console.WriteLine($"【批量判断】是否以 C# / Hello / Test 任意一个开头:{hasAnyPrefix}");
}
}

测试示例(验证你的程序是否正确)

输入1:

主字符串:C#编程练习 前缀字符串:c#

输出结果: 【严格匹配(区分大小写)】是否以前缀开头:False 【忽略大小写匹配】是否以前缀开头:True 【批量判断】是否以 C# / Hello / Test 任意一个开头:True

输入2:

主字符串:HelloWorld 前缀字符串:He

输出结果:

【严格匹配(区分大小写)】是否以前缀开头:True 【忽略大小写匹配】是否以前缀开头:True 【批量判断】是否以 C# / Hello / Test 任意一个开头:True

总结

  1. 基础用法 StartsWith(前缀) 必须大小写完全一致才会返回 true
  2. 忽略大小写必须搭配 StringComparison.OrdinalIgnoreCase
  3. 批量判断用循环+StartsWith,是实际开发中最常用的场景。

你可以先尝试自己编写,写完后对照参考代码检查,有问题随时问我!

EndsWith()

题目要求

编写一个 C# 控制台程序,实现文件类型校验功能

  1. 提示用户输入一个文件名(例如:photo.jpgdocument.pdfnotes.TXT);
  2. 使用 EndsWith() 方法判断该文件是否为图片类型;
  3. 图片类型定义为:以 .jpg.jpeg.png.gif 结尾;
  4. 匹配规则:不区分大小写(例如 .TXT.JPG 都要能识别);
  5. 输出清晰的结果:告诉用户输入的是图片还是非图片。

核心知识点

EndsWith() 关键用法:

  1. 字符串.EndsWith(后缀)区分大小写 匹配;
  2. 字符串.EndsWith(后缀, StringComparison.OrdinalIgnoreCase)忽略大小写 匹配(本题重点)。
using System;

class FileChecker
{
static void Main()
{
// 1. 获取用户输入
Console.WriteLine("===== 文件类型检查器 =====");
Console.Write("请输入文件名:");
string fileName = Console.ReadLine();

// 2. 定义需要检查的图片后缀
string[] imageExtensions = { ".jpg", ".jpeg", ".png", ".gif" };
bool isImage = false;

// 3. 循环判断:是否以任意一个图片后缀结尾(忽略大小写)
foreach (string ext in imageExtensions)
{
if (fileName.EndsWith(ext, StringComparison.OrdinalIgnoreCase))
{
isImage = true;
break; // 找到匹配就停止
}
}

// 4. 输出结果
if (isImage)
{
Console.WriteLine("✅ 这是一个图片文件");
}
else
{
Console.WriteLine("❌ 这不是图片文件");
}
}
}

测试示例(验证你的程序)

输入1:

selfie.JPG
输出:✅ 这是一个图片文件

输入2:

report.pdf
输出:❌ 这不是图片文件

输入3:

animation.Gif
输出:✅ 这是一个图片文件

总结

  1. EndsWith() 专门判断字符串结尾内容;
  2. 忽略大小写必须加 StringComparison.OrdinalIgnoreCase
  3. 批量后缀判断 = 循环 + EndsWith,是工作中高频用法。

str.Repalce()

题目要求

编写一个 C# 控制台程序,实现文本内容替换功能

  1. 提示用户输入一段原始文本(可以包含脏话、敏感词);
  2. 预设 2 个敏感词:笨蛋垃圾
  3. 使用 Replace() 方法,把所有敏感词全部替换***
  4. 输出替换前替换后的文本,清晰对比效果;
  5. 支持连续替换(多个敏感词都能替换)。

核心知识点

Replace() 方法作用:把字符串中所有指定的旧内容,替换成新内容

语法:

新字符串 = 原字符串.Replace("旧内容", "新内容");

完整参考代码

using System;

class SensitiveWordReplace
{
static void Main()
{
// 1. 输入原始文本
Console.WriteLine("===== 敏感词替换工具 =====");
Console.Write("请输入需要过滤的内容:");
string original = Console.ReadLine();

// 2. 替换敏感词(连续使用 Replace())
string result = original.Replace("笨蛋", "***") // 替换笨蛋
.Replace("垃圾", "***"); // 替换垃圾

// 3. 输出结果
Console.WriteLine("\n替换前:" + original);
Console.WriteLine("替换后:" + result);
}
}

测试示例

输入:

你真是个笨蛋,不要乱扔垃圾!

输出:

替换前:你真是个笨蛋,不要乱扔垃圾!
替换后:你真是个***,不要乱扔***!

总结

  1. Replace(旧文本, 新文本) 会替换所有出现的旧内容;
  2. 可以链式调用str.Replace(a,b).Replace(c,d) 连续替换;
  3. 替换后会生成新字符串,原字符串不会改变。

非常简单但超级常用!试着自己敲一遍就能完全掌握~

str.Substring()提取身份证号

背景

中国的居民身份证号码(18位)包含了丰富的信息:前6位是地址码,第7-14位是出生日期,第17位是性别(奇数男性,偶数女性),第18位是校验码。本题要求你编写一个 C# 控制台程序,从身份证号中提取指定省份、出生日期、性别,并计算年龄。

任务描述

编写一个程序,完成以下功能:

  1. 输入身份证号:提示用户输入一个18位身份证号码。
  2. 验证省份:使用 Substring() 提取前6位地址码,判断该身份证是否属于河北省、山东省、河南省之一。若不属于,输出 "该身份证不属于河北、山东或河南。" 并结束程序。
    • 河北地址码范围:130000-139999
    • 山东地址码范围:370000-379999
    • 河南地址码范围:410000-419999
  3. 提取出生年月日:使用 Substring() 提取第7-14位(共8位),格式为 yyyyMMdd,并以 yyyy-MM-dd 格式输出。
  4. 提取性别:使用 Substring() 提取第17位(1位),根据数字奇偶性判断性别:奇数 → 男性,偶数 → 女性。输出性别。
  5. 计算年龄:以当前系统日期为基准,计算周岁年龄(即生日已过则年龄+1,否则不加)。输出年龄。
  6. 异常处理:如果用户输入的身份证长度不是18位,或包含非数字字符(除最后一位可能是X外),应提示错误并要求重新输入。

技术要求

  • 必须使用 Substring() 方法提取身份证的各部分信息。
  • 使用 DateTime 类处理日期计算。
  • 校验码(第18位)可以不验证,但建议处理可能的 X 字符。
  • Substring() 提取字符串的指定部分。
  • 字符串转换与验证。
  • 日期处理(DateTime)与年龄计算。
  • 条件判断与循环控制。

示例1(正常情况)

请输入18位身份证号:
130101199003076632
省份:河北
出生日期:1990-03-07
性别:男性
年龄:33岁

示例2(性别示例)

请输入18位身份证号:
370202200112121245
省份:山东
出生日期:2001-12-12
性别:女性
年龄:21岁

示例3(非法省份)

请输入18位身份证号:
110101199003076632
该身份证不属于河北、山东或河南。

示例4(非法长度)

请输入18位身份证号:
123456
身份证号长度错误,请输入18位。

参考答案

using System;

class Program
{
static void Main()
{
Console.WriteLine("=== 身份证信息提取器(河北/山东/河南)===");
string id = "";

while (true)
{
Console.Write("\n请输入18位身份证号码:");
id = Console.ReadLine()?.Trim() ?? "";

// 1. 长度校验
if (id.Length != 18)
{
Console.WriteLine("身份证号长度错误,请输入18位。");
continue;
}

// 2. 基本字符校验(前17位必须为数字,第18位可为数字或X)
bool valid = true;
for (int i = 0; i < 17; i++)
{
if (!char.IsDigit(id[i]))
{
valid = false;
break;
}
}
if (!valid || (id[17] != 'X' && id[17] != 'x' && !char.IsDigit(id[17])))
{
Console.WriteLine("身份证号格式错误,前17位需为数字,第18位可为数字或X。");
continue;
}

// 转换大写X便于统一
id = id.ToUpper();

break; // 输入正确,跳出循环
}

// 3. 提取前6位地址码,判断省份
string areaCode = id.Substring(0, 6);
int code = int.Parse(areaCode);
string province = "";

if (code >= 130000 && code <= 139999)
province = "河北";
else if (code >= 370000 && code <= 379999)
province = "山东";
else if (code >= 410000 && code <= 419999)
province = "河南";
else
{
Console.WriteLine($"该身份证不属于河北、山东或河南。");
return;
}

// 4. 提取出生日期 (第7-14位)
string birthStr = id.Substring(6, 8);
DateTime birthDate;
if (!DateTime.TryParseExact(birthStr, "yyyyMMdd", null, System.Globalization.DateTimeStyles.None, out birthDate))
{
Console.WriteLine("出生日期格式无效。");
return;
}

// 5. 提取性别 (第17位)
int genderDigit = int.Parse(id.Substring(16, 1));
string gender = (genderDigit % 2 == 1) ? "男性" : "女性";

// 6. 计算年龄(周岁)
DateTime today = DateTime.Today;
int age = today.Year - birthDate.Year;
if (birthDate.Date > today.AddYears(-age)) // 生日未到,减一岁
age--;

// 7. 输出结果
Console.WriteLine($"省份:{province}");
Console.WriteLine($"出生日期:{birthDate:yyyy-MM-dd}");
Console.WriteLine($"性别:{gender}");
Console.WriteLine($"年龄:{age}岁");
}
}

句子分词与统计str.Split()

题目要求

编写一个 C# 控制台程序,实现文本分割与统计功能

  1. 提示用户输入一句英文句子(单词之间用空格隔开);
  2. 使用 Split() 方法,将句子按空格分割成单词数组
  3. 统计并输出总单词数量
  4. 遍历单词数组,逐行输出每一个单词
  5. 进阶:处理连续空格(例如 hello world 也能正确分割)。

核心知识点

Split() 方法作用:把一个字符串,按照指定的分隔符,切割成字符串数组 基础语法: string[] 数组名 = 原字符串.Split(分隔符);

处理空项(推荐用法): str.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

先自己尝试写!

下面是完整参考代码,建议你先动手实现,再对照检查:

using System;

class StringSplitExercise
{
static void Main()
{
// 1. 获取用户输入
Console.WriteLine("===== Split() 方法训练:句子分词 =====");
Console.Write("请输入一句英文(单词用空格隔开):");
string sentence = Console.ReadLine();

// 2. 使用 Split() 分割
// 参数说明:按空格分割 | 自动移除分割后产生的空字符串(解决连续空格问题)
string[] words = sentence.Split(
new char[] { ' ' }, // 分隔符:空格
StringSplitOptions.RemoveEmptyEntries
);

// 3. 统计并输出结果
Console.WriteLine($"\n总单词数:{words.Length}");
Console.WriteLine("--- 分割后的单词列表 ---");

// 4. 遍历输出每个单词
for (int i = 0; i < words.Length; i++)
{
Console.WriteLine($"单词 {i + 1}{words[i]}");
}
}
}

测试示例(验证你的程序)

输入 1(正常空格): I love C# programming

输出:

总单词数:4
--- 分割后的单词列表 ---
单词 1:I
单词 2:love
单词 3:C#
单词 4:programming

输入 2(含连续空格): Hello world !

输出:

总单词数:3
--- 分割后的单词列表 ---
单词 1:Hello
单词 2:world
单词 3:!

总结

  1. Split(分隔符) 会把字符串切成字符串数组
  2. 数组.Length 可以快速获取分割后的元素个数
  3. StringSplitOptions.RemoveEmptyEntries 是处理多余空格、空行的神器,必须掌握。

这个用法在读取 CSV、解析日志、处理文本时超级常用

str.ToCharArray()字符分解与统计

题目要求

编写一个 C# 控制台程序,实现字符串转字符数组功能:

  1. 提示用户输入任意一段文本(英文/中文/符号都可以);
  2. 使用 ToCharArray() 方法,把字符串转换成字符数组
  3. 输出总字符个数
  4. 遍历字符数组,逐行输出每一个字符,并标注序号;
  5. 额外练习:把字符数组重新拼接回字符串

核心知识点

ToCharArray() 作用:把字符串拆分成一个一个字符,返回 char 类型数组 语法: char[] 字符数组 = 字符串.ToCharArray();

完整参考代码

using System;

class ToCharArrayExercise
{
static void Main()
{
// 1. 获取用户输入
Console.WriteLine("===== ToCharArray() 方法训练 =====");
Console.Write("请输入任意字符串:");
string str = Console.ReadLine();

// 2. 字符串 → 字符数组(核心方法)
char[] charArray = str.ToCharArray();

// 3. 输出总长度
Console.WriteLine($"\n总字符数:{charArray.Length}");
Console.WriteLine("------------------------");

// 4. 遍历输出每个字符
Console.WriteLine("【逐字符输出】");
for (int i = 0; i < charArray.Length; i++)
{
Console.WriteLine($"第 {i+1} 个字符:{charArray[i]}");
}

// 5. 进阶:字符数组重新变回字符串
string newStr = new string(charArray);
Console.WriteLine("------------------------");
Console.WriteLine($"字符数组还原成字符串:{newStr}");
}
}

测试示例

输入: Hello2025

输出:

总字符数:9
------------------------
【逐字符输出】
第 1 个字符:H
第 2 个字符:e
第 3 个字符:l
第 4 个字符:l
第 5 个字符:o
第 6 个字符:2
第 7 个字符:0
第 8 个字符:2
第 9 个字符:5
------------------------
字符数组还原成字符串:Hello2025

总结

  1. 字符串.ToCharArray() 会把一整段文字拆成单个字符
  2. 结果是 char[] 字符数组,可以用下标访问每一个字符;
  3. 想把字符数组变回字符串,用:new string(char数组)

这个方法常用于逐字符处理、加密、反转、校验等场景,非常常用!

str.ToCharArray()字符串反转加密

题目要求

写一个 C# 控制台程序,实现反转加密功能:

  1. 让用户输入任意字符串(明文);
  2. 使用 ToCharArray() 把字符串转成字符数组;
  3. 反转字符数组(加密核心);
  4. 把反转后的字符数组重新变回字符串(密文);
  5. 输出原文和加密后的结果。

核心训练目标

  • 熟练使用 字符串.ToCharArray()
  • 熟练使用 new string(字符数组)
  • 掌握逐个处理字符的思路

参考代码:

using System;

class ReverseEncryption
{
static void Main()
{
// 1. 输入原文
Console.WriteLine("===== 反转加密程序 =====");
Console.Write("请输入要加密的字符串:");
string original = Console.ReadLine();

// 2. 转成字符数组(核心方法)
char[] charArray = original.ToCharArray();

// 3. 反转数组
Array.Reverse(charArray);

// 4. 还原成字符串
string encrypted = new string(charArray);

// 5. 输出结果
Console.WriteLine("\n原文:" + original);
Console.WriteLine("加密后:" + encrypted);
}
}

测试示例

输入:

HelloWorld

输出:

原文:HelloWorld
加密后:dlroWolleH

输入:

123456

输出:

原文:123456
加密后:654321

升级版挑战(不使用 Array.Reverse,自己手动反转)

如果你想彻底练熟 ToCharArray() + 手动遍历,可以做这个进阶版:

using System;

class AdvancedEncryption
{
static void Main()
{
Console.Write("请输入:");
string str = Console.ReadLine();

char[] arr = str.ToCharArray();
char[] reversedArr = new char[arr.Length];

// 手动反转(不用 Array.Reverse)
for (int i = 0; i < arr.Length; i++)
{
reversedArr[i] = arr[arr.Length - 1 - i];
}

string result = new string(reversedArr);
Console.WriteLine("加密:" + result);
}
}

这道题能让你牢牢掌握:

  1. 字符串 → 字符数组ToCharArray()
  2. 字符数组 → 字符串new string(...)
  3. 逐字符处理、加密、解密的基本思路

凯撒密码str.ToCharArray()

题目要求

编写一个 凯撒位移加密程序

  1. 用户输入明文(小写字母)
  2. 使用 ToCharArray() 转成字符数组
  3. 每个字母向后移动 3 位(a→d,b→e,z→c)
  4. 把加密后的字符数组变回字符串
  5. 输出原文 + 密文

核心训练点

  • 必须用:字符串.ToCharArray()
  • 必须用:new string(字符数组)
  • 逐个字符处理、ASCII 码运算

先自己写!写完再看答案

using System;

class CaesarCipher
{
static void Main()
{
Console.WriteLine("===== 凯撒密码加密器 =====");
Console.Write("请输入明文(小写字母):");
string input = Console.ReadLine();

// 1. 转字符数组(核心方法)
char[] charArray = input.ToCharArray();

// 2. 逐个字符加密(位移3位)
for (int i = 0; i < charArray.Length; i++)
{
charArray[i] = (char)(charArray[i] + 3);
}

// 3. 字符数组变回字符串
string secret = new string(charArray);

// 4. 输出结果
Console.WriteLine("\n明文:" + input);
Console.WriteLine("加密后:" + secret);
}
}

测试示例

输入:abc 输出:def

输入:xyz 输出:abc

输入:hello 输出:khoor

你会发现:这个题 100% 依赖 ToCharArray()

因为要逐个修改字符,字符串本身不能直接改,必须先转数组!

这就是 ToCharArray() 最核心的用途

想挑战更完美版本吗?

我可以给你出:

  1. 支持大小写
  2. 支持解密(移回去)
  3. 支持自定义位移数

凯撒密码(无bug)

xyz 直接 +3 会出bug,根本得不到 abc,反而会变成奇怪的符号!

  1. 为什么 xyz +3 会出 bug?

小写字母: a(97) ~ z(122)

  • x = 120 +3 = 123{
  • y = 121 +3 = 124|
  • z = 122 +3 = 125}

所以输入 xyz,会输出: {|} ❌ 大bug!

而我们想要的正确加密应该是: xyzabc

  1. 正确的凯撒密码:必须循环回到开头

公式:

新字符 = (原字符 - 'a' + 位移数) % 26 + 'a';

这样超过 z 就会自动循环回到 a

  1. 修复后的完整正确代码(无bug版)
using System;

class CaesarCipher
{
static void Main()
{
Console.WriteLine("===== 凯撒密码加密器(无bug版) =====");
Console.Write("请输入明文(小写字母):");
string input = Console.ReadLine();

// 核心:转字符数组
char[] charArray = input.ToCharArray();

// 逐个字符加密(循环位移)
for (int i = 0; i < charArray.Length; i++)
{
// 只处理小写字母
if (charArray[i] >= 'a' && charArray[i] <= 'z')
{
// 关键公式:循环位移
charArray[i] = (char)((charArray[i] - 'a' + 3) % 26 + 'a');
}
}

// 字符数组转回字符串
string secret = new string(charArray);

Console.WriteLine("\n明文:" + input);
Console.WriteLine("加密:" + secret);
}
}
  1. 现在测试 xyz 完全正常! 输入: xyz

输出: abc

输入: hello

输出: khoor

  1. 这道题真正训练了什么?
  • ToCharArray() 必须用(逐个修改字符只能用数组)
  • char 运算
  • 循环加密逻辑(真正的凯撒密码)
  • 修复边界bug的思维(x/y/z 越界问题)

石头剪刀布

using System;
using System.Threading;

class Program
{
static void Main()
{
Console.WriteLine("=== 跟电脑玩石头、剪刀、布 ===");
Random r = new Random();
string[] choices = { "石头", "剪刀", "布" };
int playerScore = 0;
int computerScore = 0;

while (true)
{
// 显示当前比分
Console.WriteLine($"\n当前比分:玩家 {playerScore} : {computerScore} 电脑");

// 玩家出拳
Console.WriteLine("你出什么?");
Console.WriteLine("1:石头 2:剪刀 3:布 0:退出游戏");
Console.Write("请选择一个数字: ");
int playerChoice;
if (!int.TryParse(Console.ReadLine(), out playerChoice) || playerChoice < 0 || playerChoice > 3)
{
Console.WriteLine("输入无效,请输入0~3之间的数字。");
Thread.Sleep(1500);
continue;
}
if (playerChoice == 0)
{
Console.WriteLine("游戏结束!最终比分:");
Console.WriteLine($"玩家 {playerScore} : {computerScore} 电脑");
break;
}

// 电脑出拳
int computerChoice = r.Next(1, 4);
Console.WriteLine($"电脑正在出拳...");
Thread.Sleep(800); // 模拟思考过程
Console.WriteLine($"电脑出了:{choices[computerChoice - 1]}");

// 胜负判定
Console.Write("结果:");
Thread.Sleep(800);
if (playerChoice == computerChoice)
{
Console.WriteLine("平局!");
}
else if ((playerChoice == 1 && computerChoice == 2) ||
(playerChoice == 2 && computerChoice == 3) ||
(playerChoice == 3 && computerChoice == 1))
{
Console.WriteLine("胜利!");
playerScore++;
}
else
{
Console.WriteLine("失败!");
computerScore++;
}

// 短暂停顿后进入下一轮
Thread.Sleep(1500);
Console.Clear(); // 清屏,使界面更清爽(可选)
}
}
}