Head First C# 实验室 赛狗日

2024-03-05 03:30

本文主要是介绍Head First C# 实验室 赛狗日,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

话说这是第一次用Markdown编辑器,代码的高亮方式好奇怪,谁来帮帮我?

本人正在新学C#,这是Head First C# (第二版)的第一个实验,要求写一个模拟赛狗的程序(为什么是赛狗而不是赛马 =_=)。题目我就不多介绍了,因为我假定你已经知道题目了,要不然你也不会来看这篇博客。

首先来一张程序的界面

赛狗日程序界面

这个程序需要自己创建三个类,Greyhound,Guy,和Bet,要搞清楚这三个类分别是干什么的。

Greyhound就是狗啦,它主要用来控制四条狗的位置。其中TakeStartingPosition()是将狗放回起点位置;而Run()则是让狗移动,类型为bool,如果这条狗到达了终点,就返回true。在后面的使用中,要用一个数组来放四条狗。狗每跑一步,都要检测Run()的返回值,一旦为true了,就结束比赛,同时把当前这条狗记为冠军。

Guy类是人,下注的人。而Bet类则表示一个下注。这两个类有些麻烦,因为Guy类中包含一个Bet类字段MyBet,而Bet类中也包含一个Guy类字段Bettor,真是晕。让我来慢慢解释。

首先Guy类,它包含字段Name,Cash,分别指人的名字以及他所拥有 的现金,而MyBet则表示一次下注。如果他还没有下注,则MyBet=null;如果他下了注,MyBet类就会引用一个Bet类实例。另外MyRadioButton和MyLabel分别为了引用界面上的RadioButton和Label标签。Guy类的几个方法,UpdateLabels()就是更新界面上显示的信息的;PlaceBet()就是让MyBet新建一个实例,表示这个下注了;相反,ClearBet()则是把MyBet引用的内容释放掉,在C#中只要让MyBet=null就可以了,终于不需要C++里的delete了;最后的Collect()方法,就是根据这个人是赢了还是输了来改变他的现金Cash。

至于Bet类,它并不是指某一样东西,而是指一件事情,即下注。所以它有字段Amount和Dog,分别下注的金额以及押的狗的编号。而它包含一个Guy类Bettor,这是指这个注是谁下的。例如,假设已经有了一个实例化的Guy类叫Joe,然后Joe下了一个注,为了方便,给这个“注”取个名字叫Bet1(我随便取的名字),那么就有这样一种关系

Joe.MyBet = Bet1;
Bet1.Bettor = Joe;

上面的只是关系示例,只是为了搞明白关系,具体代码中是没Bet1这种名字的。Joe下注这个操作写成代码是 Joe.PlaceBet(),这里面的实现代码是Joe.MyBet = new Bet(); 当然,要加上参数Amount和Dog,我这里省略了。然后再让MyBet.Bettor = this。其中的this在这里就是指Joe。在C#里可以用列表初始化类,所以在这个PlaceBet()方法里可以直接写成

MyBet = new Bet { Amount = Amount, Dog = Dog, Bettor = this };

Bet里的GetDescription()方法,是返回一个字符串描述,指出是谁在下注,他押的是哪条狗。而PayOut(int Winner)方法,如果Winner等于当前Bet实例里的Dog,表示押中了,就返回Amount,否则返回-Amount,这是为了给Guy类的Collect()方法调用的。

下面是Greyhound类的代码:

using System;
using System.Windows.Forms;
using System.Drawing;namespace DogRace
{class Greyhound{public int StartingPosition = 12;       //Where my PictureBox startspublic int RacetrackLength = 525;       //How long the racetrack ispublic PictureBox MyPictureBox = null;      //My PictureBox objectpublic int Location = 0;        //My Location on the racetrackpublic Random Randomizer;       //An instance fo Randompublic bool Run(){/* Move forward either 1, 2, 3 or 4 spaces at random* Update the position of my PictureBox on the form* Return true if I won the race*/Point p = MyPictureBox.Location;p.X += Randomizer.Next(20);MyPictureBox.Location = p;Location = p.X - StartingPosition;if (Location >= RacetrackLength){return true;}else{return false;}}public void TakeStartingPosition(){//Reset my location to the start linePoint p = MyPictureBox.Location;p.X = StartingPosition;MyPictureBox.Location = p;}}
}

Guy类的代码:

using System.Windows.Forms;namespace DogRace
{class Guy{public string Name;     //The guy's namepublic Bet MyBet;       //An instance of Bet() that has his betpublic int Cash;        //How much cash he has//The last two fields are the guy's GUI controls on the formpublic RadioButton MyRadioButton;   //My RadioButtonpublic Label MyLabel;   //My Labelpublic void UpdateLabels(){//Set my label to my bet's description, and the label on my radio button to show my cash ("Joe has 43 bucks")if (MyBet != null){MyLabel.Text = MyBet.GetDescription();}else{MyLabel.Text = Name + " hasn't placed a bet";}MyRadioButton.Text = Name + " has " + Cash + " bucks";}//Reset my bet so it's zeropublic void ClearBet(){MyBet = null;UpdateLabels();}public bool PlaceBet(int Amount, int Dog){//Place a new bet and store it in my bet field//Return true if the guy had enough money to betif (Amount <= Cash && Amount > 0){MyBet = new Bet { Amount = Amount, Dog = Dog, Bettor = this };return true;}else{return false;}}public void Collect(int Winner){//Ask my bet to pay outCash += MyBet.PayOut(Winner);}}
}

Bet类的代码:

namespace DogRace
{class Bet{public int Amount;      //The amount of cash that was betpublic int Dog;         //The number of the dog the bet is onpublic Guy Bettor;      //The guy who placed the betpublic string GetDescription(){//Return a string that says who placed the bet, how much cash was bet, and which dog he bet on ("Joe bets 8 on dog #4"). If the amount is zero, no bet was placed ("Joe hasn't placed a bet").if (Amount > 0){return Bettor.Name + " bets " + Amount + " on dog #" + Dog;}else{return Bettor.Name + " hasn't placed a bet";}}public int PayOut(int Winner){//The parameter is the winner of the race. If the dog won, return the amount bet. Otherwise, return the negative of the amount bet.if (Winner == Dog){return Amount;}else{return -Amount;}}}
}

然后是界面的代码,我用的名字还是Form1.....

using System;
using System.Windows.Forms;namespace DogRace
{public partial class Form1 : Form{Greyhound[] dogs;Guy[] bettors;public Form1(){InitializeComponent();Random random = new Random();dogs = new Greyhound[4]{new Greyhound() {MyPictureBox=pictureBox0, Randomizer=random },new Greyhound() {MyPictureBox=pictureBox1, Randomizer=random },new Greyhound() {MyPictureBox=pictureBox2, Randomizer=random },new Greyhound() {MyPictureBox=pictureBox3, Randomizer=random }};bettors = new Guy[3]{new Guy() {Name="Joe", Cash=50, MyLabel=lblJoeBet, MyRadioButton=radioJoe },new Guy() {Name="Bob", Cash=75, MyLabel=lblBobBet, MyRadioButton=radioBob },new Guy() {Name="Al",  Cash=45, MyLabel=lblAlBet,  MyRadioButton=radioAl }};foreach (var guy in bettors){guy.UpdateLabels();}}private void radioJoe_CheckedChanged(object sender, EventArgs e){labName.Text = "Joe";numericUpDown1.Maximum = bettors[0].Cash;}private void radioBob_CheckedChanged(object sender, EventArgs e){labName.Text = "Bob";numericUpDown1.Maximum = bettors[1].Cash;}private void radioAl_CheckedChanged(object sender, EventArgs e){labName.Text = "Al";numericUpDown1.Maximum = bettors[2].Cash;}private void btnBets_Click(object sender, EventArgs e){foreach (var bettor in bettors){if (bettor.MyRadioButton.Checked){bettor.PlaceBet((int)numericUpDown1.Value, (int)numericUpDown2.Value);bettor.UpdateLabels();}}}private void btnRace_Click(object sender, EventArgs e){//先检查是否所有人都下注bool allGuysBet = true;foreach (var bettor in bettors){if (bettor.MyBet == null){allGuysBet = false;}}if (!allGuysBet){MessageBox.Show("Someone hasn't bet");return;}//如果都下注,就开始比赛this.btnRace.Enabled = false;this.btnBets.Enabled = false;bool hasAWinner = false;int winner = -1;while (!hasAWinner){for (int i = 0; i < 4; i++){hasAWinner = dogs[i].Run();if (hasAWinner){winner = i + 1;MessageBox.Show("dog #" + winner + " win!");break;}System.Threading.Thread.Sleep(20);Application.DoEvents();}}//比赛结束,统计结果并将狗复位foreach (var bettor in bettors){bettor.Collect(winner);bettor.ClearBet();bettor.UpdateLabels();}foreach (var dog in dogs){dog.TakeStartingPosition();}this.btnRace.Enabled = true;this.btnBets.Enabled = true;}}
}

至于界面设计部分的代码,我就不放了,太长了,并不是重点。

更新:我把完整的代码放在了我的Github上,欢迎访问 DogRace

这篇关于Head First C# 实验室 赛狗日的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/775193

相关文章

C#提取PDF表单数据的实现流程

《C#提取PDF表单数据的实现流程》PDF表单是一种常见的数据收集工具,广泛应用于调查问卷、业务合同等场景,凭借出色的跨平台兼容性和标准化特点,PDF表单在各行各业中得到了广泛应用,本文将探讨如何使用... 目录引言使用工具C# 提取多个PDF表单域的数据C# 提取特定PDF表单域的数据引言PDF表单是一

C#实现添加/替换/提取或删除Excel中的图片

《C#实现添加/替换/提取或删除Excel中的图片》在Excel中插入与数据相关的图片,能将关键数据或信息以更直观的方式呈现出来,使文档更加美观,下面我们来看看如何在C#中实现添加/替换/提取或删除E... 在Excandroidel中插入与数据相关的图片,能将关键数据或信息以更直观的方式呈现出来,使文档更

C#实现系统信息监控与获取功能

《C#实现系统信息监控与获取功能》在C#开发的众多应用场景中,获取系统信息以及监控用户操作有着广泛的用途,比如在系统性能优化工具中,需要实时读取CPU、GPU资源信息,本文将详细介绍如何使用C#来实现... 目录前言一、C# 监控键盘1. 原理与实现思路2. 代码实现二、读取 CPU、GPU 资源信息1.

在C#中获取端口号与系统信息的高效实践

《在C#中获取端口号与系统信息的高效实践》在现代软件开发中,尤其是系统管理、运维、监控和性能优化等场景中,了解计算机硬件和网络的状态至关重要,C#作为一种广泛应用的编程语言,提供了丰富的API来帮助开... 目录引言1. 获取端口号信息1.1 获取活动的 TCP 和 UDP 连接说明:应用场景:2. 获取硬

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

C#使用yield关键字实现提升迭代性能与效率

《C#使用yield关键字实现提升迭代性能与效率》yield关键字在C#中简化了数据迭代的方式,实现了按需生成数据,自动维护迭代状态,本文主要来聊聊如何使用yield关键字实现提升迭代性能与效率,感兴... 目录前言传统迭代和yield迭代方式对比yield延迟加载按需获取数据yield break显式示迭

c# checked和unchecked关键字的使用

《c#checked和unchecked关键字的使用》C#中的checked关键字用于启用整数运算的溢出检查,可以捕获并抛出System.OverflowException异常,而unchecked... 目录在 C# 中,checked 关键字用于启用整数运算的溢出检查。默认情况下,C# 的整数运算不会自

C#实现获得某个枚举的所有名称

《C#实现获得某个枚举的所有名称》这篇文章主要为大家详细介绍了C#如何实现获得某个枚举的所有名称,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考一下... C#中获得某个枚举的所有名称using System;using System.Collections.Generic;usi

C# 读写ini文件操作实现

《C#读写ini文件操作实现》本文主要介绍了C#读写ini文件操作实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录一、INI文件结构二、读取INI文件中的数据在C#应用程序中,常将INI文件作为配置文件,用于存储应用程序的

C#实现获取电脑中的端口号和硬件信息

《C#实现获取电脑中的端口号和硬件信息》这篇文章主要为大家详细介绍了C#实现获取电脑中的端口号和硬件信息的相关方法,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 我们经常在使用一个串口软件的时候,发现软件中的端口号并不是普通的COM1,而是带有硬件信息的。那么如果我们使用C#编写软件时候,如