Head First C# 实验室 赛狗日
来源:互联网 发布:.com.cn是什么域名 编辑:程序博客网 时间:2024/06/05 02:04
话说这是第一次用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 starts public int RacetrackLength = 525; //How long the racetrack is public PictureBox MyPictureBox = null; //My PictureBox object public int Location = 0; //My Location on the racetrack public Random Randomizer; //An instance fo Random public 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 line Point p = MyPictureBox.Location; p.X = StartingPosition; MyPictureBox.Location = p; } }}
Guy类的代码:
using System.Windows.Forms;namespace DogRace{ class Guy { public string Name; //The guy's name public Bet MyBet; //An instance of Bet() that has his bet public int Cash; //How much cash he has //The last two fields are the guy's GUI controls on the form public RadioButton MyRadioButton; //My RadioButton public Label MyLabel; //My Label public 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 zero public 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 bet if (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 out Cash += MyBet.PayOut(Winner); } }}
Bet类的代码:
namespace DogRace{ class Bet { public int Amount; //The amount of cash that was bet public int Dog; //The number of the dog the bet is on public Guy Bettor; //The guy who placed the bet public 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# 实验室 赛狗日
- head first C# 赛狗日
- Head First C# LAB1 赛狗日
- Head First C#(赛狗日)
- Head First C#(赛狗日)
- 【c#入门学习】head first c#赛狗日
- 完成了Head First C# 的赛狗日
- Head First C#中文版(第三页)
- Head First C#中文版 (page 4)
- Head First C# (蜂巢模拟系统)
- Head First C# Save the Humans
- Head First
- Head First
- ?head first ???? ????? ????
- Head First C#中文版 图文皆译 (page5)
- Head First C#中文版 图文皆译 (page6)
- Head First C#中文版 图文皆译 (page7)
- Head First C#中文版 图文皆译 (page8)
- iOS开发 实战篇---Xcode7免费真机测试流程
- 按钮写到UItableView的头视图还是列表之外
- UI资料
- Java的StringBuffer类
- 【codevs 2975】与2,3,5无关的数
- Head First C# 实验室 赛狗日
- C++之为什么对引用变量取地址得到的是被引用变量的地址
- iOS 中数字的格式化处理
- 防止字典参数缺少发生意外崩溃的解决方法
- 采用先进的视觉技术测试图形用户界面:工具、技术和实践
- 静态数组实现栈
- .ini文件转换为.xml文件
- U3D——刀光轨迹插件的改进
- MFC+Direct2D简化坐标缩放