1. 前言
其实这是我在大一第一学期CSharp的课程设计,要求编写一个模拟双色球彩票的控制台应用程序,用以实现简单的模拟选购彩票。 但最近我重新看我的博客时感觉之前写的代码还是有很多不足之处,比如变量的命名,方法的命名,整体代码风格等差强人意,毕竟是入门是写的代码,所以今天稍微修改一下,让命名更规范,注释更明确。当然,更重要的还是:不是吧代码拿来即用,而是让刚开始入门的小伙伴能够快速地对编程感兴趣,对.net平台感兴趣,对CSharp这门语言感兴趣,我们大家共同把国内的.net发展起来。
1.1 你会学到什么?
简单地运用CSharp语言和.net平台,如变量、方法、类、数组、字典、系统函数、规范的注释、控制台输出、文件的读写、程序怎样设计等。
1.2 开发环境或运行环境
- Win10或Win11系统,Visual Studio 2022 开发环境;
- .net6,CSharp10;
2. 程序设计
2.1 流程图
2.2 有哪些功能?
- 产生模拟奖池;
- 生成自定义购号记录;
- 打印数据,读取数据;
- 界面输出优化;
- 保护用户隐私;
- 程序结束后可继续查看中奖记录等。
2.3 运行展示
2.3.1 双色球规则
2.3.2 充值或提现
2.3.3 自动购号
自动购号在去重后会自动排序展示出来。
2.3.4 手动购号
可以看到,手动购号比系统购号稍微复杂了一点点,会有多次范围检测和重复检测,并且还要提示哪个球重复……完成购号后,自动购号和手动购号的记录就会在程序运行目录保存。
打开是这样的:
其实,数据保存方法经过了多次设计,最开始只是为了记录,后来做到开奖时不易拆分,一次次改进而来。设计过程如下:
代码语言:javascript复制====第1次设计====
用普通数据记录
第【01】注:红色球:01 02 03 04 05 06 蓝色球:07 【系统购号】时间:2019.06.12 22:02:01
第【02】注:红色球:06 14 15 22 29 32 蓝色球:11 【手动购号】时间:2019.06.12 22:02:07
====第2次设计====
去掉固定字符
01_01_02_03_04_05_06_07_系统购号_2019.06.12 22:02:01
02_06_14_15_22_29_32_11_手动购号_2019.06.12 22:02:07
====第3次设计====
用标记值 _
01_01_02_03_04_05_06_07_2019.06.12 22:02:01
02_06_14_15_22_29_32_11_2019.06.12 22:02:07
====第4次设计====
用标记值 N R B T
N01R020615182426B14T2022-05-02 下午 11:51:55
N02R011316172426B12T2022-05-02 下午 11:52:18
2.3.5 开奖
开奖时会先检测是否有购号记录:没有记录对本程序来说开奖的意义不大,就不开奖;有开奖记录会产生开奖号码,并产生模拟奖池和模拟奖池累计奖金,从而产生奖金总额。
开奖后,按照自动购号、手动购号的次序进行对比购号记录,有中奖时,记录中将号码和相应的中奖金额便于查看,然后将奖金自动发放到账户余额。之后,删除之前的所有购号记录。
具体信息如下:
2.3.6 开奖后的操作
开奖后你可以继续选择充值、提现、购号等。
3. 核心代码
3.1 程序入口
3.1.1入口
Program.cs
代码语言:javascript复制// ----------------------------------------------------------------
// Copyright ©2022 ZhaiFanhua All Rights Reserved.
// FileName:Program
// Guid:372ee8df-d0d5-4ceb-b033-613860c6257c
// Author:zhaifanhua
// Email:me@zhaifanhua.com
// CreatTime:2022-05-02 上午 08:11:21
// ----------------------------------------------------------------
using System.Runtime.InteropServices;
using TwoColorBall.Main;
namespace TwoColorBall;
/// <summary>
/// 程序入口
/// </summary>
public class Program
{
private const int _windowHeight = 50;
private const int _windowWidth = 150;
/// <summary>
/// 程序开始
/// </summary>
/// <param name="args"></param>
/// <exception cref="Exception"></exception>
public static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException = UnhandledExceptionTrapper;
try
{
// 设置窗口宽高
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Console.WindowHeight = _windowHeight;
Console.WindowWidth = _windowWidth;
}
Console.ResetColor();
Console.WriteLine($"tttt Copyright (C){DateTime.Now.Year} ZhaiFanhua All Rights Reserved.");
Console.WriteLine("你好!欢迎你进入摘繁华的模拟双色球程序!");
Console.WriteLine("===================================================程序开始===================================================");
// 入口标记
int entranceMark = 1;
while (entranceMark != 0)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("请输入以下按键选择:【Q/q】查看规则;【W/w】进入模拟;【E/e】结束程序;");
Console.ResetColor();
string selectKey = Console.ReadLine() ?? "";
switch (selectKey.ToUpper())
{
case "Q":
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("t你选择了查看规则;");
Console.ResetColor();
Rule rule = new();
rule.Start();
break;
case "W":
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("t你选择了进入模拟;");
Console.ResetColor();
Ball ball = new();
ball.Play();
break;
case "E":
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("t你选择了结束程序!");
Console.ResetColor();
entranceMark = 0;
break;
default:
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("t你的输入有误,请重新选择!");
Console.ResetColor();
break;
}
}
Console.WriteLine("===================================================程序结束===================================================");
Console.WriteLine("程序结束,请按任意键退出。");
Console.WriteLine($"tttt Copyright (C){DateTime.Now.Year} ZhaiFanhua All Rights Reserved.");
_ = Console.ReadKey(true);
}
catch (Exception ex)
{
throw new Exception("程序出错!错误消息:n" ex.Message);
}
}
/// <summary>
/// 全局异常处理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public static void UnhandledExceptionTrapper(object sender, UnhandledExceptionEventArgs e)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(e.ExceptionObject.ToString());
Console.ResetColor();
Console.WriteLine("请按任意键退出!");
_ = Console.ReadLine();
Environment.Exit(1);
}
}
3.2 Main命名空间
3.2.1 选择模拟开始
Ball.cs
代码语言:javascript复制// ----------------------------------------------------------------
// Copyright ©2022 ZhaiFanhua All Rights Reserved.
// FileName:Ball
// Guid:25182033-35b8-414c-8e5a-2d88a9677ab0
// Author:zhaifanhua
// Email:me@zhaifanhua.com
// CreatTime:2022-05-02 上午 08:20:21
// ----------------------------------------------------------------
namespace TwoColorBall.Main;
/// <summary>
/// 模拟双色球
/// </summary>
public class Ball
{
private BallAutomatic _ballAutomatic = new();
private BallManual _ballManual = new();
private Lottery _lottery = new();
private Wallet _wallet = new();
/// <summary>
/// 开始模拟
/// </summary>
public void Play()
{
Console.WriteLine(" =======================================模拟双色球开始=======================================");
// 新用户充值
Promotion();
// 入口标记
int entranceMark = 1;
while (entranceMark != 0)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("请选择:【Q/q】自动购号;【W/w】手动购号;【E/e】对已购双色球开奖;【R/r】充值或提现;【T/t】返回主菜单;");
Console.ResetColor();
string selectKey = Console.ReadLine() ?? "";
switch (selectKey.ToUpper())
{
case "Q":
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("t你选择了自动购号;");
Console.ResetColor();
_ballAutomatic.Automatic();
break;
case "W":
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("t你选择了手动购号;");
Console.ResetColor();
_ballManual.Manual();
break;
case "E":
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("t你选择了对已购买双色球开奖;");
Console.ResetColor();
_lottery.Prize();
break;
case "R":
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("t你选择了充值或提现;");
Console.ResetColor();
_wallet.RechargeOrConsumptManual();
break;
case "T":
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("t你选择了返回主菜单;");
Console.ResetColor();
entranceMark = 0;
break;
default:
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("t你的输入有误,请重新输入!");
Console.ResetColor();
break;
}
}
Console.WriteLine(" =======================================模拟双色球结束=======================================");
Console.WriteLine();
}
/// <summary>
/// 新用户赠送余额
/// </summary>
private void Promotion()
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("t为了你的首次体验,系统已为你赠送100.00元用于购买双色球!n");
_wallet.RechargeOrConsumptAutomatic((decimal)100.00);
Console.ResetColor();
}
}
3.2.2 规则
Rule.cs
代码语言:javascript复制// ----------------------------------------------------------------
// Copyright ©2022 ZhaiFanhua All Rights Reserved.
// FileName:Rule
// Guid:5c7ad5a7-2239-4327-b82f-f14df6fb1f69
// Author:zhaifanhua
// Email:me@zhaifanhua.com
// CreatTime:2022-05-02 上午 08:22:01
// ----------------------------------------------------------------
namespace TwoColorBall.Main;
/// <summary>
/// 游戏规则
/// </summary>
public class Rule
{
/// <summary>
/// 开始
/// </summary>
public void Start()
{
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine(@"一、玩法及说明
双色球投注区分为红球号码区和蓝球号码区,红球号码范围为01~33,蓝球号码范围为01~16。双色球每期从33个红球中
开出6个号码,从16个蓝球中开出1个号码作为中奖号码,双色球玩法即是竞猜开奖号码的6个红球号码和1个蓝球号码,顺
序不限。");
Console.WriteLine(@"二、设奖及中奖
|------|-----------|--------|-----------------------------------------------------------------|--------|
| | 中奖条件 | | | |
| 奖级 |-----------|中奖说明| 单注奖金 |单注赔率|
| | 红球 |蓝球| | | |
|------|------|----|--------|-----------------------------------------------------------------|--------|
| | | | |当奖池资金低于1亿元时,奖金总额为当期高等奖奖金的75%与奖池中累积 | |
| | | | |的奖金之和,单注奖金按注均分,单注最高限额封顶1000万元。 | |
| | | | |当奖池资金高于1亿元(含)时,奖金总额包括两部分,一部分为当期高等奖| |
|一等奖|RRRRRR| B | 中6 1 |奖金的55%与奖池中累积的奖金之和,单注奖金按注均分,单注最高限额封| —— |
| | | | |顶1000万元;另一部分为当期高等奖奖金的20%,单注奖金按注均分,单注 | |
| | | | |最高限额封顶1000万元。 | |
|------|------|----|--------|-----------------------------------------------------------------|--------|
|二等奖|RRRRRR| | 中6 0 | 当期高等奖奖金的25%,单注最高限额封顶500万元。 | —— |
|------|------|----|--------|-----------------------------------------------------------------|--------|
|三等奖|RRRRR | B | 中5 1 | 单注奖金额固定为3000元 | 1:1500 |
|------|------|----|--------|-----------------------------------------------------------------|--------|
| |RRRRR | | 中5 0 | | |
|四等奖|------|----|--------| 单注奖金额固定为200元 | 1:100 |
| |RRRRR | B | 中4 1 | | |
|------|------|----|--------|-----------------------------------------------------------------|--------|
| |RRRR | | 中4 0 | | |
|五等奖|------|----|--------| 单注奖金额固定为10元 | 1:5 |
| |RRR | B | 中3 1 | | |
|------|------|----|--------|-----------------------------------------------------------------|--------|
| |RR | B | 中2 0 | | |
| |------|----|--------| | |
|六等奖|R | B | 中1 1 | 单注奖金额固定为5元 | 1:2.5 |
| |------|----|--------| | |
| | | B | 中0 1 | | |
|------|------|----|--------|-----------------------------------------------------------------|--------|");
Console.WriteLine(@"注:
1、高等奖奖金=奖金总额-固定奖奖金。
2、当奖池奖金超过1亿元(含)时,下期一等奖奖金总额包括两部分,一部分为高等奖奖金的55% 与奖池奖金之和,单注
奖金按注均分,封顶1000万元;另一部分为高等奖奖金的20%,单注奖金按注均分,封顶1000万元。
3、奖池奖金在1亿元以下时,单注奖金封顶500万元。");
Console.ResetColor();
Console.WriteLine("你已查看完双色球规则!n");
}
}
3.2.3 账户余额
Wallet.cs
代码语言:javascript复制// ----------------------------------------------------------------
// Copyright ©2022 ZhaiFanhua All Rights Reserved.
// FileName:Wallet
// Guid:bbf94a5b-f7f3-4202-a11c-aba3dac239c3
// Author:zhaifanhua
// Email:me@zhaifanhua.com
// CreatTime:2022-05-02 上午 08:23:35
// ----------------------------------------------------------------
namespace TwoColorBall.Main;
/// <summary>
/// 账户钱包
/// </summary>
public class Wallet
{
// 余额
private static decimal _balance = 0;
public decimal Balance
{
get => _balance;
set => _balance = value >= 0 ? value : 0;
}
/// <summary>
/// 手动充值或消费
/// </summary>
public void RechargeOrConsumptManual()
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("请输入你的账户存取额(正为充值,负为提现):");
Console.ResetColor();
decimal money = decimal.Parse(Console.ReadLine() ?? string.Format("0"));
RechargeOrConsumptAutomatic(money);
}
/// <summary>
/// 自动充值或消费
/// </summary>
/// <param name="money"></param>
public void RechargeOrConsumptAutomatic(decimal money)
{
decimal moneyabs = Math.Abs(money);
if (money >= 0)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("t充值或奖励金额为:{0}元;", FormatMoneyToDecimal(moneyabs));
Balance = moneyabs;
Console.ResetColor();
}
else
{
if (Math.Abs(money) > Balance)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("t账户余额不足此提现或消费;");
Console.ResetColor();
}
else
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("t提现或消费金额为:{0}元;", FormatMoneyToDecimal(moneyabs));
Balance -= moneyabs;
Console.ResetColor();
}
}
//输出账户余额
Console.WriteLine("t你的账户的余额为:{0}元;", FormatMoneyToDecimal(Balance));
}
/// <summary>
/// 格式化金额(1234,5678.90)
/// </summary>
/// <param name="money"></param>
/// <returns></returns>
public string FormatMoneyToDecimal(decimal money)
{
try
{
string moneyStr = money.ToString();
string moneyRes = string.Empty;
string moneyInt = string.Empty;
string moneyDecimal = string.Empty;
if (moneyStr.Contains('.'))
{
moneyInt = moneyStr.Split('.')[0].ToString();
moneyDecimal = "." moneyStr.Split('.')[1].ToString();
moneyRes = FormatMoneyToInt(moneyInt);
}
else
{
moneyRes = FormatMoneyToInt(moneyStr);
}
string FormatMoneyToInt(string moneyint)
{
if (moneyint.ToString().Length > 4)
{
string moneyNotFormat = moneyint.Substring(0, moneyint.Length - 4);
string moneyFormat = moneyint.Substring(moneyint.Length - 4, 4);
if (moneyNotFormat.Length > 4)
{
return FormatMoneyToInt(moneyNotFormat) "," moneyFormat;
}
else
{
return moneyNotFormat "," moneyFormat;
}
}
else
{
return moneyint;
}
}
return moneyRes moneyDecimal;
}
catch (Exception)
{
throw;
}
}
}
3.2.4 自动购号
BallAutomatic.cs
代码语言:javascript复制// ----------------------------------------------------------------
// Copyright ©2022 ZhaiFanhua All Rights Reserved.
// FileName:BallAutomatic
// Guid:8c918fa6-8fdb-486d-a214-ce7627c70fd8
// Author:zhaifanhua
// Email:me@zhaifanhua.com
// CreatTime:2022-05-02 上午 08:24:53
// ----------------------------------------------------------------
using TwoColorBall.Common;
namespace TwoColorBall.Main;
/// <summary>
/// 自动购号
/// </summary>
public class BallAutomatic
{
private Wallet _myWallet = new();
private WriteData _writeData = new();
private Random _random = new();
private int[] _balls = new int[7];
/// <summary>
/// 自动购号
/// </summary>
public void Automatic()
{
Console.WriteLine();
Console.WriteLine(" =============================自动购号开始=============================");
int buytimes = CheckWallet();
Buy(buytimes);
Console.WriteLine(" =============================自动购号结束=============================");
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine(" (你可以选择继续购号或开奖)");
Console.ResetColor();
Console.WriteLine();
}
/// <summary>
/// 确认购买注数并判断余额是否可用
/// </summary>
/// <returns></returns>
private int CheckWallet()
{
int times = 0;
int entranceMark = 1;
while (entranceMark != 0)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("请输入你要购买几注双色球:");
Console.ResetColor();
times = int.Parse(Console.ReadLine() ?? "0");
if ((decimal)times * 2 > _myWallet.Balance)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("t你的账户余额不够购买{0}注双色球,请充值;", times);
Console.ResetColor();
_myWallet.RechargeOrConsumptManual();
}
else
{
entranceMark = 0;
break;
}
}
return times;
}
/// <summary>
/// 购买下注
/// </summary>
/// <param name="buytimes"></param>
private void Buy(int buytimes)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("t系统正在为你购买【{0}】注双色球...", buytimes);
Console.ResetColor();
for (int sequence = 1; sequence <= buytimes; sequence )
{
Console.Write("第【{0,2}】注:", sequence.ToString("D2"));
Red();
Blue();
Console.Write("t【自动购号】");
string time = DateTime.Now.ToString();
Console.Write("时间:{0}", time);
_writeData.RecordBall(this.GetType().Name, sequence.ToString("D2"), _balls, time);
Console.WriteLine();
}
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("t系统已为你完成购买【{0,2}】注双色球!", buytimes);
Console.ResetColor();
_myWallet.RechargeOrConsumptAutomatic(-(decimal)buytimes * 2);
}
/// <summary>
/// 红色球
/// </summary>
public void Red()
{
int[] redballs = new int[6];
// 重复检验
for (int i = 0; i < redballs.Length; i )
{
int ball = _random.Next(1, 34);
for (int j = 0; j < i; j )
{
while (ball == redballs[j])
{
ball = _random.Next(1, 34);
}
}
redballs[i] = ball;
}
// 数字排序
for (int i = 0; i < redballs.Length - 1; i )
{
for (int j = 0; j < redballs.Length - 1 - i; j )
{
if (redballs[j] > redballs[j 1])
{
int max = redballs[j];
redballs[j] = redballs[j 1];
redballs[j 1] = max;
}
}
}
// 显示记录
Console.Write("红色球:");
for (int i = 0; i < redballs.Length; i )
{
Task.Delay(50).Wait();
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("{0,2:D2} ", redballs[i]);
_balls[i] = redballs[i];
Console.ResetColor();
}
}
/// <summary>
/// 蓝色球
/// </summary>
public void Blue()
{
int blueball = _random.Next(1, 17);
Console.Write("蓝色球:");
Task.Delay(50).Wait();
Console.ForegroundColor = ConsoleColor.Blue;
Console.Write("{0,2:D2} ", blueball);
_balls[6] = blueball;
Console.ResetColor();
}
}
3.2.5 手动购号
BallManual.cs
代码语言:javascript复制// ----------------------------------------------------------------
// Copyright ©2022 ZhaiFanhua All Rights Reserved.
// FileName:BallManual
// Guid:63af13fc-5ad7-4a56-9631-85cbd96ce4bd
// Author:zhaifanhua
// Email:me@zhaifanhua.com
// CreatTime:2022-05-02 上午 08:25:58
// ----------------------------------------------------------------
using TwoColorBall.Common;
namespace TwoColorBall.Main;
/// <summary>
/// 手动购号
/// </summary>
public class BallManual
{
private Wallet _myWallet = new();
private WriteData _writeData = new();
private int[] _balls = new int[7];
/// <summary>
/// 手动购号
/// </summary>
public void Manual()
{
Console.WriteLine();
Console.WriteLine(" =============================手动购号开始=============================");
int buytimes = CheckWallet();
Buy(buytimes);
Console.WriteLine(" =============================手动购号结束=============================");
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine(" (你可以选择继续购号或开奖)");
Console.ResetColor();
Console.WriteLine();
}
/// <summary>
/// 确认购买注数并判断余额是否可用
/// </summary>
/// <returns></returns>
private int CheckWallet()
{
int times = 0;
int entranceMark = 1;
while (entranceMark != 0)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("请输入你要购买几注双色球:");
Console.ResetColor();
times = int.Parse(Console.ReadLine() ?? "0");
if ((decimal)times * 2 > _myWallet.Balance)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("t你的账户余额不够购买{0}注双色球,请充值;", times);
Console.ResetColor();
_myWallet.RechargeOrConsumptManual();
}
else
{
entranceMark = 0;
break;
}
}
return times;
}
/// <summary>
/// 购买下注
/// </summary>
/// <param name="buytimes"></param>
private void Buy(int buytimes)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("t你正在手动购买【{0}】注双色球...", buytimes);
Console.ResetColor();
for (int sequence = 1; sequence <= buytimes; sequence )
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("请输入第[{0,2}]注你要选择的(1 - 33之间的)6个[红色球]号码:", sequence.ToString("D2"));
Console.ResetColor();
Red();
Blue();
Display(sequence);
Console.Write("t【手动购号】");
string time = DateTime.Now.ToString();
Console.Write("时间:{0}", time);
_writeData.RecordBall(this.GetType().Name, sequence.ToString("D2"), _balls, time);
Console.WriteLine();
}
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("t系统已为你完成购买【{0,2}】注双色球!", buytimes);
Console.ResetColor();
_myWallet.RechargeOrConsumptAutomatic(-(decimal)buytimes * 2);
}
/// <summary>
/// 红色球
/// </summary>
private void Red()
{
int[] redballs = new int[6];
for (int ballth = 0; ballth < redballs.Length; ballth )
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Write("第{0}个红色球:", ballth 1);
Console.ResetColor();
// 当前球
int currentball = int.Parse(Console.ReadLine() ?? "0");
// 检查
currentball = Inspect(ballth, currentball);
// 赋值当前球
redballs[ballth] = currentball;
}
// 数字排序
for (int i = 0; i < redballs.Length - 1; i )
{
for (int j = 0; j < redballs.Length - 1 - i; j )
{
if (redballs[j] > redballs[j 1])
{
int max = redballs[j];
redballs[j] = redballs[j 1];
redballs[j 1] = max;
}
}
}
// 赋值
for (int i = 0; i < _balls[0..6].Length; i )
{
_balls[i] = redballs[i];
}
// 检查数字是否符合
int Inspect(int iballth, int icurrentball)
{
// 判断当前球是否在(1-33)范围内,若不是,重新输入,若是,赋值
while (!(icurrentball >= 1 && icurrentball <= 33))
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("第{0}个红色球:(输入范围错误![{1}]超出了输入范围,请重新输入(1-33之间)的数)", iballth 1, icurrentball);
Console.ResetColor();
icurrentball = int.Parse(Console.ReadLine() ?? "0");
icurrentball = Inspect(iballth, icurrentball);
break;
}
// 重复序号
int repeatSeq = 0;
// 重复个数
int repeatNum = 0;
// 重复标记
int repeatMark = 1;
// 判断当前数字与已选择数字是否有重复
for (int ith = 0; ith < iballth; ith )
{
if (icurrentball == redballs[ith])
{
repeatSeq = ith;
repeatNum ;
}
}
// 若有重复,则重新输入
if (repeatNum != 0)
{
// 提示第几个数重复
while (repeatMark != 0)
{
string repeatTips = "除";
for (int i = 0; i < iballth; i )
{
// 重复数字
string repeatNums = string.Empty;
for (int t = 0; t <= i; t )
{
repeatNums = "[" Convert.ToString(redballs[t]) "]";
}
repeatTips = repeatNums;
}
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("第{0}个红色球:(输入重复错误!你购买的第{1}个红色球已存在数字{2},请重新输入(1-33之间)({3})的数)", iballth 1, repeatSeq 1, icurrentball, repeatTips);
icurrentball = int.Parse(Console.ReadLine() ?? "0");
Console.ResetColor();
icurrentball = Inspect(iballth, icurrentball);
repeatMark = 0;
}
}
return icurrentball;
}
}
/// <summary>
/// 蓝色球
/// </summary>
private void Blue()
{
int blueball = 0;
//判断输入数字是否在(1-16)范围内,若是取值,若不是重新输入
while (!(blueball >= 1 && blueball <= 16))
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("请输入你要选择的(1-16之间)1个[蓝色球]号码:");
Console.Write("蓝色球:");
Console.ResetColor();
blueball = int.Parse(Console.ReadLine() ?? "0");
}
_balls[6] = blueball;
}
/// <summary>
/// 显示记录
/// </summary>
private void Display(int sequence)
{
Console.Write("第【{0,2}】注:", sequence.ToString("D2"));
Console.Write("红色球:");
for (int i = 0; i < _balls[0..6].Length; i )
{
Task.Delay(50).Wait();
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("{0,2:D2} ", _balls[i]);
Console.ResetColor();
}
Console.Write("蓝色球:");
Task.Delay(50).Wait();
Console.ForegroundColor = ConsoleColor.Blue;
Console.Write("{0,2:D2} ", _balls[6]);
Console.ResetColor();
}
}
3.2.6 开奖
Lottery.cs
代码语言:javascript复制// ----------------------------------------------------------------
// Copyright ©2022 ZhaiFanhua All Rights Reserved.
// FileName:Lottery
// Guid:1ae901e8-4a3f-4281-a62f-a2c9a9640396
// Author:zhaifanhua
// Email:me@zhaifanhua.com
// CreatTime:2022-05-02 上午 08:38:22
// ----------------------------------------------------------------
using TwoColorBall.Common;
namespace TwoColorBall.Main;
/// <summary>
/// 开奖
/// </summary>
public class Lottery
{
private Wallet _wallet = new();
private ReadData _readData = new();
private WriteData _writeData = new();
private Random _random = new();
// 购号记录是否存在
private Dictionary<string, bool> _ballIsRecord = new();
// 模拟奖池
private decimal _lottery = 0;
// 奖池中累积的奖金之和
private decimal _bonusCumulative = 0;
// 奖金总额
private decimal _bonusTotal = 0;
// 单次中奖金额
private decimal _bonusAmount = 0;
// 总中奖金额
private decimal _bonusAmounts = 0;
// 中奖号码
private int[] _prizeBall = new int[7];
// 中奖总数
private int[] _prizeCount = new int[7];
// 中奖等级
private string _prizeGrade = string.Empty;
/// <summary>
/// 开奖入口
/// </summary>
public void Prize()
{
// 删除开奖记录
_readData.DeleteFile(this.GetType().Name);
_readData.DeleteFile(@"PrizeRecord");
// 判断是否开奖
bool isPrize = WhetherPrize();
// 有购票记录则开奖,没有则不开奖
if (isPrize)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.Write("t存在购号记录,即将开奖!n");
Console.ResetColor();
Console.WriteLine();
Console.WriteLine(" ================模拟开奖开始================");
StartPrize();
ComparativeData();
Console.WriteLine(" ================模拟开奖结束================");
Console.WriteLine();
}
else
{
Console.ForegroundColor = ConsoleColor.Green;
Console.Write("t你没有任何形式的购号记录,请先购号后开奖!n");
Console.ResetColor();
Console.WriteLine();
}
// 删除购号记录
_readData.DeleteFile(typeof(BallAutomatic).Name);
_readData.DeleteFile(typeof(BallManual).Name);
}
/// <summary>
/// 判断是否开奖
/// </summary>
/// <returns></returns>
private bool WhetherPrize()
{
// 删除开奖前创建的模拟开奖历史记录
_readData.DeleteFile(this.GetType().Name);
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("t正在判断是否开奖...");
Console.ResetColor();
// 判断购号记录是否存在
_ballIsRecord = FindData();
bool isFind = _ballIsRecord.ToList().Any(e => e.Value == true);
return isFind;
}
/// <summary>
/// 判断是否存在购号记录
/// </summary>
/// <returns></returns>
private Dictionary<string, bool> FindData()
{
Console.ForegroundColor = ConsoleColor.Green;
Console.Write("t正在判断是否存在购号记录...");
Console.ResetColor();
Dictionary<string, bool> isFind = new Dictionary<string, bool>
{
{ typeof(BallAutomatic).Name,false},
{ typeof(BallManual).Name,false}
};
return _readData.FindData(isFind);
}
/// <summary>
/// 产生开奖号
/// </summary>
private void StartPrize()
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("t正在产生开奖号码...");
Console.ResetColor();
BallAutomatic myBallAutomatic = new BallAutomatic();
Console.Write("【开奖号码】");
Red();
Blue();
Console.Write("t【模拟开奖】");
string time = DateTime.Now.ToString();
Console.Write("时间:{0}", time);
Console.WriteLine();
Console.WriteLine("t开奖号码已产生!");
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Green;
Console.Write("t正在计算奖池金额...");
Console.ResetColor();
// 奖池
_lottery = _random.Next(10000000, 999999999);
// 奖池中累积的奖金之和
_bonusCumulative = _random.Next(1000000, 99999999);
// 奖金总额
_bonusTotal = _lottery _bonusCumulative;
Task.Delay(1000).Wait();
Console.Write("t本次开奖奖池金额为:{0}元;奖池中累积的奖金之和为:{1}元;奖金总额为:{2}元;",
_wallet.FormatMoneyToDecimal(_lottery),
_wallet.FormatMoneyToDecimal(_bonusCumulative),
_wallet.FormatMoneyToDecimal(_bonusTotal));
Console.WriteLine();
// 打印模拟开奖记录
_writeData.RecordLottery(this.GetType().Name, _prizeBall, time,
_wallet.FormatMoneyToDecimal(_lottery),
_wallet.FormatMoneyToDecimal(_bonusCumulative),
_wallet.FormatMoneyToDecimal(_bonusTotal));
}
/// <summary>
/// 红色球
/// </summary>
public void Red()
{
int[] redballs = new int[6];
// 重复检验
for (int i = 0; i < redballs.Length; i )
{
int ball = _random.Next(1, 34);
for (int j = 0; j < i; j )
{
while (ball == redballs[j])
{
ball = _random.Next(1, 34);
}
}
redballs[i] = ball;
}
// 数字排序
for (int i = 0; i < redballs.Length - 1; i )
{
for (int j = 0; j < redballs.Length - 1 - i; j )
{
if (redballs[j] > redballs[j 1])
{
int max = redballs[j];
redballs[j] = redballs[j 1];
redballs[j 1] = max;
}
}
}
// 显示记录
Console.Write("红色球:");
for (int i = 0; i < redballs.Length; i )
{
Task.Delay(50).Wait();
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("{0,2:D2} ", redballs[i]);
_prizeBall[i] = redballs[i];
Console.ResetColor();
}
}
/// <summary>
/// 蓝色球
/// </summary>
public void Blue()
{
int blueball = _random.Next(1, 17);
Console.Write("蓝色球:");
Task.Delay(50).Wait();
Console.ForegroundColor = ConsoleColor.Blue;
Console.Write("{0,2:D2} ", blueball);
_prizeBall[6] = blueball;
Console.ResetColor();
}
/// <summary>
/// 对比数据
/// </summary>
public void ComparativeData()
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("t正在查找数据,请稍候...");
Console.ResetColor();
Console.WriteLine(" ========查看中奖开始========");
// 查找数据
foreach (var br in _ballIsRecord)
{
string tip = br.Key == typeof(BallAutomatic).Name ? "系统购号" : "手动购号";
if (br.Value)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine($"t查找到{tip}数据,正在读取...");
Console.ResetColor();
JudgeData(br.Key);
}
else
{
Console.WriteLine($"t你没有{tip}数据!");
}
}
// 判断总中奖数
if (_prizeCount[6] == 0)
{
Console.WriteLine("t抱歉,你没有中奖!");
}
else
{
Console.WriteLine($"t你共中奖{_prizeCount[6]}注,获得总奖金:{_bonusAmounts}元!其中:"
$"一等奖{_prizeCount[0]}注;"
$"二等奖{_prizeCount[1]}注;"
$"三等奖{_prizeCount[2]}注;"
$"四等奖{_prizeCount[3]}注;"
$"五等奖{_prizeCount[4]}注;"
$"六等奖{ _prizeCount[5]}注;");
}
_wallet.RechargeOrConsumptAutomatic(_bonusAmounts);
_writeData.RecordPrizeAmounts(_prizeCount, _wallet.FormatMoneyToDecimal(_bonusAmounts));
Console.WriteLine(" ========查看中奖结束========");
// 总中奖数清零
Array.Clear(_prizeCount, 0, _prizeCount.Length);
// 总中奖金额清零
_bonusAmounts = 0;
}
/// <summary>
/// 判断数据
/// </summary>
/// <param name="name"></param>
public void JudgeData(string name)
{
// 读取行数
int rows = _readData.GetRowsCount(name);
// 提示
string tip = name == typeof(BallAutomatic).Name ? "系统购号" : "手动购号";
for (int everyrow = 1; everyrow <= rows; everyrow )
{
// 读取数据
string[] datastr = new string[4];
datastr = _readData.ReadBallData(name, everyrow);
// 定义一个读取文件后数组,用于比较是否中奖
int[] databall = new int[7];
// 拆分后的序号
string sequence = datastr[1];
// 拆分后的红球
string redballstr = datastr[2];
for (int i = 0; i < 6; i )
{
databall[i] = int.Parse(redballstr.Substring(i * 2, 2));
}
// 拆分后的蓝球
databall[6] = int.Parse(datastr[3]);
// 拆分后的时间
string time = datastr[4];
// 开奖数字对比之后计数
int red = 0;
int blue = 0;
for (int i = 0; i < _prizeBall.Length; i )
{
if (_prizeBall[i] == databall[i])
{
_ = i < 6 ? red : blue ;
}
}
// 判断中奖
JudgePrize(sequence, databall, time, tip, red, blue);
}
}
/// <summary>
/// 判断中奖
/// </summary>
/// <param name="sequence"></param>
/// <param name="databall"></param>
/// <param name="time"></param>
/// <param name="tip"></param>
/// <param name="red"></param>
/// <param name="blue"></param>
public void JudgePrize(string sequence, int[] databall, string time, string tip, int red, int blue)
{
// 是否输出
bool output = false;
if (red == 6 && blue == 1)
{
_prizeGrade = "一";
_bonusAmount = _bonusTotal * 0.75m;
if (_bonusAmount >= 10000000)
{
_bonusAmount = 10000000;
}
_prizeCount[6] ;
_prizeCount[0] ;
output = true;
}
if (red == 6 && blue == 0)
{
_prizeGrade = "二";
_bonusAmount = _bonusTotal * 0.25m;
if (_bonusAmount >= 10000000)
{
_bonusAmount = 5000000;
}
_prizeCount[6] ;
_prizeCount[1] ;
output = true;
}
if (red == 5 && blue == 1)
{
_prizeGrade = "三";
_bonusAmount = 3000;
_prizeCount[6] ;
_prizeCount[2] ;
output = true;
}
if ((red == 5 && blue == 0) || (red == 4 && blue == 1))
{
_prizeGrade = "四";
_bonusAmount = 200;
_prizeCount[6] ;
_prizeCount[3] ;
output = true;
}
if ((red == 4 && blue == 0) || (red == 3 && blue == 1))
{
_prizeGrade = "五";
_bonusAmount = 10;
_prizeCount[6] ;
_prizeCount[4] ;
output = true;
}
if ((red == 2 && blue == 1) || (red == 1 && blue == 1) || (red == 0 && blue == 1))
{
_prizeGrade = "六";
_bonusAmount = 5;
_prizeCount[6] ;
_prizeCount[5] ;
output = true;
}
if (output)
{
_bonusAmounts = _bonusAmount;
// 中奖输出
Console.Write("第【{0}】注:红色球:", sequence);
Console.ForegroundColor = ConsoleColor.Red;
for (int i = 0; i < 6; i )
{
Console.Write("{0,2:D2} ", databall[i]);
}
Console.ResetColor();
Console.Write("蓝色球:");
Console.ForegroundColor = ConsoleColor.Blue;
Console.Write("{0,2:D2}", databall[6]);
Console.ResetColor();
Console.Write("t【{0}】", tip);
Console.Write("时间:{0}", time);
Console.Write("t[该注中了{0}等奖!获得奖金:{1}元;]", _prizeGrade, _wallet.FormatMoneyToDecimal(_bonusAmount));
_writeData.RecordPrize(sequence, databall, time, tip, _prizeGrade, _wallet.FormatMoneyToDecimal(_bonusAmount));
Console.WriteLine();
}
}
}
3.3 Common命名空间
3.3.1 写数据
WriteData.cs
代码语言:javascript复制// ----------------------------------------------------------------
// Copyright ©2022 ZhaiFanhua All Rights Reserved.
// FileName:WriteData
// Guid:c426bd62-1823-4187-8390-904a85be9d62
// Author:zhaifanhua
// Email:me@zhaifanhua.com
// CreatTime:2022-05-02 上午 08:59:57
// ----------------------------------------------------------------
namespace TwoColorBall.Common;
/// <summary>
/// 记录数据
/// </summary>
public class WriteData
{
/// <summary>
/// 购号记录
/// </summary>
/// <param name="name"></param>
/// <param name="sequence"></param>
/// <param name="balls"></param>
/// <param name="time"></param>
public void RecordBall(string name, string sequence, int[] balls, string time)
{
// 标记值
const string _sequence = "N";
const string _red = "R";
const string _blue = "B";
const string _time = "T";
string filename = name ".txt";
using (StreamWriter file = File.AppendText(filename))
{
string red = string.Empty;
for (int i = 0; i < balls[0..6].Length; i )
{
red = balls[i].ToString("D2");
}
string blue = balls[6].ToString("D2");
string record = _sequence sequence _red red _blue blue _time time;
file.WriteLine(record);
}
}
/// <summary>
/// 开奖记录
/// </summary>
/// <param name="name"></param>
/// <param name="balls"></param>
/// <param name="time"></param>
/// <param name="lottery"></param>
public void RecordLottery(string name, int[] balls, string time, string lottery, string bonusCumulative, string bonusTotal)
{
string filename = name ".txt";
using (StreamWriter file = File.AppendText(filename))
{
string red = string.Empty;
for (int i = 0; i < balls[0..6].Length; i )
{
red = balls[i].ToString("D2") " ";
}
string blue = balls[6].ToString("D2");
string record = "红色球:" red "蓝色球:" blue;
file.Write("【开奖号码】{0}", record);
file.Write("t【模拟开奖】时间:{0}", time);
file.WriteLine();
file.Write("t本次开奖奖池金额为:{0}元;奖池中累积的奖金之和为:{1}元;奖金总额为:{2}元;", lottery, bonusCumulative, bonusTotal);
file.WriteLine();
}
}
/// <summary>
/// 中奖记录和金额记录
/// </summary>
/// <param name="num"></param>
/// <param name="ball"></param>
/// <param name="time"></param>
/// <param name="whichball"></param>
public void RecordPrize(string num, int[] ball, string time, string whichball, string prizeGrade, string prizeAmount)
{
string filename = @"PrizeRecord.txt";
using (StreamWriter file = File.AppendText(filename))
{
file.Write("第【{0}】注:红色球:", num);
for (int i = 0; i < 6; i )
{
file.Write("{0,2:D2} ", ball[i]);
}
file.Write("蓝色球:{0,2:D2}", ball[6]);
file.Write("t【{0}】", whichball);
file.Write("时间:{0}", time);
file.Write("tt[该注中了{0}等奖!获得奖金:{1}元;]", prizeGrade, prizeAmount);
file.WriteLine();
}
}
/// <summary>
/// 中奖概括记录
/// </summary>
/// <param name="name"></param>
/// <param name="prizeCount"></param>
/// <param name="prizeAmounts"></param>
public void RecordPrizeAmounts(int[] prizeCount, string prizeAmounts)
{
string filename = @"PrizeRecord.txt";
using (StreamWriter file = File.AppendText(filename))
{
file.WriteLine($"t你共中奖{prizeCount[6]}注,获得总奖金:{prizeAmounts}元!其中:"
$"一等奖{prizeCount[0]}注;"
$"二等奖{prizeCount[1]}注;"
$"三等奖{prizeCount[2]}注;"
$"四等奖{prizeCount[3]}注;"
$"五等奖{prizeCount[4]}注;"
$"六等奖{ prizeCount[5]}注;");
}
}
}
3.3.2 读数据
ReadData.cs
代码语言:javascript复制// ----------------------------------------------------------------
// Copyright ©2022 ZhaiFanhua All Rights Reserved.
// FileName:ReadData
// Guid:55cd3ffd-3af8-418a-a091-5eb3f6250fb5
// Author:zhaifanhua
// Email:me@zhaifanhua.com
// CreatTime:2022-05-02 上午 08:41:21
// ----------------------------------------------------------------
namespace TwoColorBall.Common;
/// <summary>
/// 读取数据
/// </summary>
public class ReadData
{
/// <summary>
/// 查找文件
/// </summary>
/// <param name="filename"></param>
public bool FindFile(string name)
{
string filename = name ".txt";
return File.Exists(filename);
}
/// <summary>
/// 删除文件
/// </summary>
/// <param name="name"></param>
public void DeleteFile(string name)
{
string filename = name ".txt";
if (File.Exists(filename))
{
File.Delete(filename);
}
}
/// <summary>
/// 查找记录
/// </summary>
/// <param name="ballbuys"></param>
/// <returns></returns>
public Dictionary<string, bool> FindData(Dictionary<string, bool> ballbuys)
{
return ballbuys.ToDictionary(e => e.Key, e => FindFile(e.Key));
}
/// <summary>
/// 获取行数
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public int GetRowsCount(string name)
{
string filename = name ".txt";
int rowsCount = 0;
using (StreamReader read = File.OpenText(filename))
{
string result = read.ReadToEnd();
rowsCount = result.Split('n').Length - 1;
}
return rowsCount;
}
/// <summary>
/// 读取数据
/// </summary>
/// <param name="name"></param>
/// <param name="row"></param>
public string[] ReadBallData(string name, int row)
{
string filename = name ".txt";
string[] data = File.ReadAllLines(filename);
string[] datastr = data[row - 1].Split(new char[4] { 'N', 'R', 'B', 'T' });
return datastr;
}
}
4. 源码分享
4.1 源码分享
github(国际):源码分享
gitlab(国际):源码分享
gitee(国内):源码分享