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 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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《Head First C》是一本由大卫·格里芬(David Griffiths)和保罗·巴里(Paul Barry)合著的C语言编程入门教程。与一般的编程书籍不同,《Head First C》尝试采用非传统的、有趣的方式来阐述C语言编程基础,使初学者能够更容易地理解和掌握这门语言。 该书内容涵盖了C语言的基本语法、数据类型、运算符、控制结构、函数、数组等方面的知识。在讲解这些知识点时,书中采用了许多大量图解、示例代码、练习题等形式,帮助读者更深入地了解和掌握编程的基本概念和技巧。 此外,《Head First C》还介绍了一些编程的最佳实践,如调试技巧、内存管理等方面的知识,以及如何使用C语言编写程序中的常见问题。这些内容对于初学者来说非常有用,可以帮助他们在编程中更加规范和高效。 总而言之,《Head First C》是一本非常适合初学者入门的C语言编程书籍。它不仅讲解全面,而且内容有趣,对于初学者来说既易于理解又容易上手。如果你想要学习C语言编程,并且想要找一本好的入门书籍,那么《Head First C》肯定是一本值得推荐的书籍。 ### 回答2: 《Head First C》是一本由MIT学院和耶鲁大学教育背景的作者所编写的C语言学习教材,旨在通过生动有趣的图表、插图、问题和实践展示C语言的基础。这本书的特点是利用了大量的视觉元素,其中包括强调、颜色和图标,以吸引读者的注意力和加强记忆。作者通过讲解文字和图片,以及需要学习的主要工具和技术,帮助读者理解C语言的重点概念、语法和数据类型,同时提供了较丰富的示例代码以供实践。 《Head First C》不仅适用于初学者学习C语言,同时也适合有一定经验的开发人员用于回顾和提高技能。本书分为15章,涵盖了从C语言的基础知识到高级主题的内容。其中也包括了大量真实世界中的示例,使读者了解在实际应用中如何利用C语言编写程序。通过本书的学习,读者将可以系统性地学习C语言,丰富自己的编程经验,提高自己的编程技能。 总之,《Head First C》是本富有启发性和诙谐幽默的学习教材,可以帮助读者快乐地学习C语言,同时学到一些有趣的编程技巧,成为优秀的程序员。 ### 回答3: Head First C是一本面向初学者的C语言学习指南,由Kathy Sierra和Bert Bates撰写而成。它以一种简单易懂且生动有趣的方式,引导读者了解C语言的核心概念和基础知识,并提供了丰富的实例和练习,帮助读者增强对C语言的理解和掌握。 本书被广泛认为是一本优秀的教学材料,其中融入了最新的教学技巧和原则。相对于传统的教材,Head First C通过图表、概念映射和故事情节等手段来讲解C语言,以便更深入、更生动地吸引读者。 其重点涵盖了C语言的基础语法、数据类型、指针、函数等各个方面。此外,Head First C还指导读者使用GCC编译器、调试程序和阅读C代码的能力,这些对于日后的编程工作非常重要。 总的来说,Head First C是一本适合所有想要深入了解C语言的读者的好书,既可以作为日常学习的参考,也可以作为初次学习编程的工具书。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值