赛狗日源码分享 《Head First C#》第三版
ORB-SLAM2 论文&代码学习 —— 单目初始化
媒介
这个赛狗日,是给个框架让本身写。以为难度有点大,语言和控件不熟。读他的申明和程序构造读了两三遍。末了才邃晓要干啥。写是写出来了,然则我以为还可以优化,优化在末了申明,线来看下结果
结果展现
步骤
熟读任务申明
写一个程序第一步就是要邃晓,它要干啥,他怎样完成。而不是一遍写一遍想,写写改改,如许贫苦不说而且还很捞,我们这类新手平常都没有哪一个本领一写就过。这本书很好,给了程序的构造和逻辑,只需本身想要领完成 就好了。所以要先读清晰任务申明,以防止越写越乱。
搭界面
书上给的网站应该换地点了,进去不是的,是他们公司官网。无法网上找不到适宜的图片。只要本身画了,用PPT简朴画一个。
然后就根据书上的界面搭建一个。
图片网上好找。拍好规划,设置好控件的属性就OK,不想调图片尺寸,我就用的 背景图片添补,然后背景图片设为自适应。
入手下手代码
根据书上的构造代码分为一下四个部份:
- Form:界面控件的逻辑掌握。
- Greyhound:赛狗的对象,每一个对象掌握一条狗。
- Guy:赌徒对象,一个赌徒有一个对应的一个对象。
- 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;
}
}
}
}
写在背面的话
本次碰见的一些问题
论坛给了这么好的交换平台,固然要交换下本身的问题。作为初学者更应该交换。
- 书要细致,最入手下手遗漏了一个bet按钮,书上也不显眼,纠结了良久Raadiobutton功用写不好,总不满意。末了一看下注那句话内里藏个按钮。。。如许就好办了。
- 末了推断完胜利者,从新初始化狗的位置时总有偏移。
然后我输出图片的位置检察一下初始化时图片的位置发明没缺点。然后我以为是电脑有问题了,直到一次0号狗跑了第一和一次3号狗跑了第一,一对比才想到,没有掌握好完毕的逻辑,完毕后不实用break初始化后还会挪用背面狗的Run(),从而发作偏移。
关于优化
可以设定狗的特征
可以参照游戏设定狗的一些特征,让竞赛随机,但又可以预感。
去掉Bet类
我以为哪一个Bet类显得有点碍事,让程序有点庞杂。可以直接合并到Guy类内里。==这个只是个人见解,如不准确还望大神指导==。
本身的不足
我写完后本身有看了遍代码,虽然完成了书上的功用,然则以为本身也有写偏的。比方:
- Bet类默许都建立,我以为书上得意义是,这局赌了才会建立一个Bet对象,而我是默许都建立了。同时还增加了过剩的推断前提。
- 关于label的跟新我都是依靠Bet类内里的GetDiscreaption()来取得文本,整体我以为不好。
大概另有很多不足的处所,愿望有大佬看出来可以交换下,我今后防止再犯如许的毛病。️
2020-2-24
使用docker创建MySQL容器,并在springboot中使用