IT教程 ·

赛狗日源码分享 《Head First C#》第三版

ORB-SLAM2 论文&代码学习 —— 单目初始化

 

媒介

这个赛狗日,是给个框架让本身写。以为难度有点大,语言和控件不熟。读他的申明和程序构造读了两三遍。末了才邃晓要干啥。写是写出来了,然则我以为还可以优化,优化在末了申明,线来看下结果

结果展现

 

步骤

熟读任务申明

写一个程序第一步就是要邃晓,它要干啥,他怎样完成。而不是一遍写一遍想,写写改改,如许贫苦不说而且还很捞,我们这类新手平常都没有哪一个本领一写就过。这本书很好,给了程序的构造和逻辑,只需本身想要领完成 就好了。所以要先读清晰任务申明,以防止越写越乱。

搭界面

书上给的网站应该换地点了,进去不是的,是他们公司官网。无法网上找不到适宜的图片。只要本身画了,用PPT简朴画一个。

然后就根据书上的界面搭建一个。

图片网上好找。拍好规划,设置好控件的属性就OK,不想调图片尺寸,我就用的 背景图片添补,然后背景图片设为自适应。

入手下手代码

根据书上的构造代码分为一下四个部份:

  1. Form:界面控件的逻辑掌握。
  2. Greyhound:赛狗的对象,每一个对象掌握一条狗。
  3. Guy:赌徒对象,一个赌徒有一个对应的一个对象。
  4. Bet:赌局对象(个人明白),掌握一个赌徒本局的下注状况。

From.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Day_at_the_Races
{
    public partial class Form1 : Form
    {
        Greyhound[] greyhounds = new Greyhound[4];//声明一个数组治理Grehound对象
        Guy[] guys = new Guy[3];//声明一个数组治理Guy对象
        Random random = new Random();//建立一个Random对象。

        public Form1()
        {
            InitializeComponent();

            initDog();//初始化狗
            initGuy();//初始化赌徒和对应的赌注。

        }


        /// <summary>
        /// 初始化竞赛的狗:绑定狗的图片对象,赛道的长度,出发点位置,随机Random对象;同时,初始化狗的位置。
        /// </summary>

        public void initDog()
        {
            //建立对象,同时对属性赋值。
            greyhounds[0] = new Greyhound()
            {
                MypictureBox = dog1,
                StartingPosition = raceRoad.Left,
                RacetrackLength = raceRoad.Width,
                randomizer = random
            };
            //重置狗的位置
            greyhounds[0].TakeStaringPosition();
            //Console.WriteLine("0号狗位置"+ greyhounds[0].StartingPosition);
            //Console.WriteLine("0号狗图片左侧位置" + greyhounds[0].MypictureBox.Left);
            greyhounds[1] = new Greyhound()
            {
                MypictureBox = dog2,
                StartingPosition = raceRoad.Left,
                RacetrackLength = raceRoad.Width,
                randomizer = random
            };
            greyhounds[1].TakeStaringPosition();
            //0Console.WriteLine("1号狗位置" + greyhounds[1].StartingPosition);
            //Console.WriteLine("1号狗图片左侧位置" + greyhounds[1].MypictureBox.Left);
            greyhounds[2] = new Greyhound()
            {
                MypictureBox = dog3,
                StartingPosition = raceRoad.Left,
                RacetrackLength = raceRoad.Width,
                randomizer = random
            };
            greyhounds[2].TakeStaringPosition();
            //Console.WriteLine("2号狗位置" + greyhounds[2].StartingPosition);
            //Console.WriteLine("2号狗图片左侧位置" + greyhounds[2].MypictureBox.Left);
            greyhounds[3] = new Greyhound()
            {
                MypictureBox = dog4,
                StartingPosition = raceRoad.Left,
                RacetrackLength = raceRoad.Width,
                randomizer = random
            };
            greyhounds[3].TakeStaringPosition();
            //Console.WriteLine("3号狗位置" + greyhounds[3].StartingPosition);
            //Console.WriteLine("3号狗图片左侧位置" + greyhounds[3].MypictureBox.Left);
        }

        /// <summary>
        /// 初始化赌徒,姓名 ,赌资,radio button,和label;末了建立每一个的赌注(bet)对象;
        /// </summary>
        public void initGuy()
        {
            guys[0] = new Guy()
            {
                Name = "卢本伟",
                Cash = 50,
                MyRadio = radiolbw,
                Mylabel = lablbwInfo
            };

            guys[1] = new Guy()
            {
                Name = "孙笑川",
                Cash = 60,
                MyRadio = radsxc,
                Mylabel = labsxcInfo
            };


            guys[2] = new Guy()
            {
                Name = "大司马",
                Cash = 20,
                MyRadio = raddsm,
                Mylabel = labdsmInfo
            };

            initbet();
        }

        /// <summary>
        /// 初始化bet对象,默许以0未初始化。
        /// </summary>
        public void initbet()
        {
            guys[0].UpdateLabel();
            guys[0].PlaceBet(0, 0);

            guys[1].UpdateLabel();
            guys[1].PlaceBet(0, 0);

            guys[2].UpdateLabel();
            guys[2].PlaceBet(0, 0);
        }

        /// <summary>
        /// timer挪用的要领,每次挪用都举行四条狗的Run函数,检测到有true返回就入手下手举行Guy的Collect(),结算。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer1_Tick(object sender, EventArgs e)
        {
            for (int i = 0; i < 4; i++)
            {

                if (greyhounds[i].Run())
                {
                    timer1.Stop();
                    for (int j = 0; j < 3; j++)
                    {
                        guys[j].Collect(i);

                    }
                    //显现提醒信息
                    MessageBox.Show("本局" + i + "号狗取得胜利!");
                    //开释每一个狗的对象
                    for (int k = 0; k < 4; k++)
                    {
                        greyhounds[k] = null;
                    }
                    //初始化狗
                    initDog();
                    //初始化赌注,赌注对象已经在Collect()内里删除。
                    initbet();
                    //将面板组件激活,举行下次赌局。
                    groupBox1.Enabled = true;
                    //重置单选框
                    radiolbw.Checked = false;
                    radsxc.Checked = false;
                    raddsm.Checked = false;
                    money.Text = "0";//下注输入框重置
                    dog.Text = "0";
                    break;//一定要加上,完毕轮回,假如不加初始化后还会挪用greyhounds[i].Run(),就会不在原点。
                }

            }
        }

        /// <summary>
        /// 点击后举行最下方Label跟新和两个输入框的革新。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void radiolbw_Click(object sender, EventArgs e)
        {

            labguy.Text = "卢本伟压注";
            money.Text = "0";
            dog.Text = "0";
        }

        private void raddsm_Click(object sender, EventArgs e)
        {
            labguy.Text = "大司马压注";
            money.Text = "0";
            dog.Text = "0";
        }

        private void radsxc_Click(object sender, EventArgs e)
        {
            labguy.Text = "孙笑川压注";
            money.Text = "0";
            dog.Text = "0";
        }

        /// <summary>
        /// 竞赛入手下手按钮,激活计时器。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_start_Click(object sender, EventArgs e)
        {

            //考证本局是不是有人下注
            if (guys[0].Mybet.Amount == 0 && guys[1].Mybet.Amount == 0 && guys[2].Mybet.Amount == 0)
            {
                MessageBox.Show("暂无选手下注!");
            }
            else
            {
                groupBox1.Enabled = false;//禁用下注面板
                timer1.Interval = 100;//设置计时器的时刻间隔为100ms。
                timer1.Start();//入手下手计时器
            }
        }

        /// <summary>
        /// 确认下注按钮,跟新Guy的bet对象,跟新label
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_ok_Click(object sender, EventArgs e)
        {
            //假如此时选中的是卢本伟的单选按钮。
            if (radiolbw.Checked)
            {
                if (Int32.Parse(money.Text) < 5)
                {
                    MessageBox.Show("下注金额最少为5元!");
                }
                else if (Int32.Parse(dog.Text) < 0 || Int32.Parse(dog.Text) > 3)
                {
                    MessageBox.Show("没有" + Int32.Parse(dog.Text) + "号狗!");
                }
                else
                {
                    guys[0].PlaceBet(Int32.Parse(money.Text), Int32.Parse(dog.Text));//更新bet对象
                    guys[0].UpdateLabel();//更新label
                }

            }
            //假如此时选中的是孙笑川的单选按钮。
            if (radsxc.Checked)
            {
                if (Int32.Parse(money.Text) < 5)
                {
                    MessageBox.Show("下注金额最少为5元!");
                }
                else if (Int32.Parse(dog.Text) < 0 || Int32.Parse(dog.Text) > 3)
                {
                    MessageBox.Show("没有" + Int32.Parse(dog.Text) + "号狗!");
                }
                else
                {
                    guys[1].PlaceBet(Int32.Parse(money.Text), Int32.Parse(dog.Text));
                    guys[1].UpdateLabel();
                }

            }
            //假如此时选中的是大司马的单选按钮。
            if (raddsm.Checked)
            {
                if (Int32.Parse(money.Text) < 5)
                {
                    MessageBox.Show("下注金额最少为5元!");
                }
                else if (Int32.Parse(dog.Text) < 0 || Int32.Parse(dog.Text) > 3)
                {
                    MessageBox.Show("没有" + Int32.Parse(dog.Text) + "号狗!");
                }
                else
                {
                    guys[2].PlaceBet(Int32.Parse(money.Text), Int32.Parse(dog.Text));
                    guys[2].UpdateLabel();
                }

            }
        }
    }
}

Greyhound.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Day_at_the_Races
{
    public class Greyhound
    {
        public int StartingPosition;//出发点位置,我设置的是以赛道的左侧为出发点
        public int RacetrackLength;//赛道长度,就是赛道图片的with宽度,因为我算尽头的宽度,我量的是100个像素,所以盘算的时刻要减去95(营建冲线假象)
        public PictureBox MypictureBox = null;//狗的图片
        public int Location = 0;//狗跑出的间隔,再次间隔上举行位置叠加
        public Random randomizer;

        public bool Run()
        {
            bool isWin = false;//胜负的标志变量

            Location += randomizer.Next(0,20);//随机对象,随机挪动0-20个像素。

            MypictureBox.Left = StartingPosition + Location;//位置更新
            if(MypictureBox.Left>= (RacetrackLength-95) - MypictureBox.Width)//推断是不是冲线,95在上方属性有诠释。
            {
                isWin = true;
            }
            
            return isWin;
        }

        //初始狗的位置
        public void TakeStaringPosition()
        {
            this.MypictureBox.Left = StartingPosition;
            this.Location = 0;
        }
        
    }
}

Guy.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Day_at_the_Races
{
    public class Guy
    {
        public string Name;//姓名
        public Bet Mybet;//赌注对象
        public int Cash;//赌资

        public RadioButton MyRadio;//radio button对象
        public Label Mylabel;//label对象

        //跟新radio button对象
        public void UpdateLabel()
        {
            MyRadio.Text = Name + "有" + Cash + "元";

        }

        //消灭赌局对象
        public void ClearBet()
        {
            Mybet = null;
        }

        //建立赌局对象
        public bool PlaceBet(int BetAmount,int DogTOWin)
        {
            if (Mybet != null)//为空就初始化
            {
                //if (BetAmount < 5)
                //{
                //    MessageBox.Show("下注金额最少为5元!");  //已经在入手下手按钮处推断
                //    return false;
                //}
                if(BetAmount > Cash){
                    MessageBox.Show(Name+"的金额不足"+BetAmount+"!");
                    
                    return false;
                }
                else
                {
                    //举行行赌局对象属性的更新
                    Console.WriteLine("下注胜利!");
                    Mybet.Amount = BetAmount;
                    Mybet.dog = DogTOWin;
                    Mylabel.Text = Mybet.GetDiscreaption();
                    return true;
                }
                
            }
            else
            {
                //初始化
                Mybet = new Bet() { Amount = BetAmount, Better = this, dog = DogTOWin };
                Mylabel.Text = Mybet.GetDiscreaption();
                return false;
            }
            
        }

        //举行赌局结算,更新资产,radio button的笔墨,删除上局的bet对象。
        public void Collect(int Winner)
        {
            Cash += Mybet.Payout(Winner);
            ClearBet();
            MyRadio.Text= Name + "有" + Cash + "元";
        }
        
    }
}

Bet.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Day_at_the_Races
{
    public class Bet
    {
        public int Amount;//下注金额
        public int dog;//压得狗
        public Guy Better;//赌徒

        //赌徒在本局一个形貌
        public string GetDiscreaption()
        {
            string dis = "";
            if (Amount == 0)
            {
                dis = Better.Name + "没有下注";
            }
            else
            {
                
                dis = Better.Name + "下注" + Amount + "元,赌" + dog + "号狗会赢";
                
            }
            return dis;

        }

        //返回本局的胜负金额
        public int Payout(int Winner)
        {
            if (dog == Winner)
            {
                return Amount;
            }
            else
            {
                return -Amount;
            }

        }
    }
}

写在背面的话

本次碰见的一些问题

论坛给了这么好的交换平台,固然要交换下本身的问题。作为初学者更应该交换。

  1. 书要细致,最入手下手遗漏了一个bet按钮,书上也不显眼,纠结了良久Raadiobutton功用写不好,总不满意。末了一看下注那句话内里藏个按钮。。。如许就好办了。
  2. 末了推断完胜利者,从新初始化狗的位置时总有偏移。
    然后我输出图片的位置检察一下初始化时图片的位置发明没缺点。

    然后我以为是电脑有问题了,直到一次0号狗跑了第一和一次3号狗跑了第一,一对比才想到,没有掌握好完毕的逻辑,完毕后不实用break初始化后还会挪用背面狗的Run(),从而发作偏移。

关于优化

可以设定狗的特征

可以参照游戏设定狗的一些特征,让竞赛随机,但又可以预感。

去掉Bet类

我以为哪一个Bet类显得有点碍事,让程序有点庞杂。可以直接合并到Guy类内里。==这个只是个人见解,如不准确还望大神指导==。

本身的不足

我写完后本身有看了遍代码,虽然完成了书上的功用,然则以为本身也有写偏的。比方:

  • Bet类默许都建立,我以为书上得意义是,这局赌了才会建立一个Bet对象,而我是默许都建立了。同时还增加了过剩的推断前提。
  • 关于label的跟新我都是依靠Bet类内里的GetDiscreaption()来取得文本,整体我以为不好。

    大概另有很多不足的处所,愿望有大佬看出来可以交换下,我今后防止再犯如许的毛病。‍️

2020-2-24

使用docker创建MySQL容器,并在springboot中使用

参与评论