我们来玩一个类似“Robocode”的游戏。
划拳规则看完了,那我们就开始写一个会划拳的机器人吧! 那么一个会划拳的机器会做什么事情呢?其实就是两件:
第一件、出拳,即:自己出几个手指?自己猜合计是多少。
第二件、知道划拳的结果,即:对方出几个手指,对方猜合计是多少,是否获胜还是平局还是其他。 只要继承Drunkard这个类,重载Come()和Outcome()方法那么你就拥有了一个会划拳的机器人,参与这个游戏了!【游戏规则】
1、比赛共1000局,即:出现胜负算一局,如出拳100次没有结果也算一局并双方均不得分;
2、赢一局得1分、输不扣分;
3、机器人执行中每出现一次异常,扣100分、对方加1分、记一局;
4、机器人执行中反应超时1000毫秒直接判负,每超时100毫秒,扣1分,超时10次以上直接判负;
5、自己得分高于对手并大于600分判胜;
6、自己得分为正数对手得分为负数判胜;
7、其他情况则判平。
具体执行的过程,算法的过程请参考Drunkery<T1, T2>类的实现【入门提示】
1、机器人的命名建议是:<自己的id> + <第几个> + "号",如:Zswang一号、Zswang二号,当然你也可以用“长江七号”
2、不允许修改Drunkard和Drunkery<T1, T2>;
3、机器人必须从Drunkard继承;
4、分析擂主代码是战胜擂主的关键;
5、打擂容易守擂难,大家自由发挥吧!【擂台赛规则】
1、第一个打败擂主的机器人奖励20分,并成为新的擂主;
2、自己不能挑战自己编写的机器人;
3、最后一个擂主获得200专家分,发帖另付;
4、其余分数酌情散掉。标准代码和比赛规则有什么不妥或者建议欢迎讨论,谢谢关注(调试代码参考后面两帖,-_-!!!代码有点多,先别抢沙发。)
划拳规则看完了,那我们就开始写一个会划拳的机器人吧! 那么一个会划拳的机器会做什么事情呢?其实就是两件:
第一件、出拳,即:自己出几个手指?自己猜合计是多少。
第二件、知道划拳的结果,即:对方出几个手指,对方猜合计是多少,是否获胜还是平局还是其他。 只要继承Drunkard这个类,重载Come()和Outcome()方法那么你就拥有了一个会划拳的机器人,参与这个游戏了!【游戏规则】
1、比赛共1000局,即:出现胜负算一局,如出拳100次没有结果也算一局并双方均不得分;
2、赢一局得1分、输不扣分;
3、机器人执行中每出现一次异常,扣100分、对方加1分、记一局;
4、机器人执行中反应超时1000毫秒直接判负,每超时100毫秒,扣1分,超时10次以上直接判负;
5、自己得分高于对手并大于600分判胜;
6、自己得分为正数对手得分为负数判胜;
7、其他情况则判平。
具体执行的过程,算法的过程请参考Drunkery<T1, T2>类的实现【入门提示】
1、机器人的命名建议是:<自己的id> + <第几个> + "号",如:Zswang一号、Zswang二号,当然你也可以用“长江七号”
2、不允许修改Drunkard和Drunkery<T1, T2>;
3、机器人必须从Drunkard继承;
4、分析擂主代码是战胜擂主的关键;
5、打擂容易守擂难,大家自由发挥吧!【擂台赛规则】
1、第一个打败擂主的机器人奖励20分,并成为新的擂主;
2、自己不能挑战自己编写的机器人;
3、最后一个擂主获得200专家分,发帖另付;
4、其余分数酌情散掉。标准代码和比赛规则有什么不妥或者建议欢迎讨论,谢谢关注(调试代码参考后面两帖,-_-!!!代码有点多,先别抢沙发。)
解决方案 »
- dateTimePicker的错误
- 长生的radiobutton控件居然不存在,是什么原因
- 请教个C#的问题(本人正在学习C#中,请大家帮忙了)
- socket.receive中,如果服务器总大小小于缓冲区的大小会引发异常吗
- 一个关于反射的问题
- 各位前辈 怎么才能在窗体界面上添加滚动性文字
- 在C#中字体信息保存问题
- 在一个工程里引用另一个工程,怎么才能debug跟进去呢?
- 我写的一段读写文件的代码 编译通过但是运行报错 请高手指点
- MVP Summit 2004: Indigo, WSE2.0,XP SP2,WhiteHorse技术预览
- 如何在Winform 中,实现打印,打印预览
- [winform] 如何将二进制流转换成pdf 文件
using System.Collections.Generic;
using System.Text;namespace Huaquan
{
/// <summary>
/// 划拳结果
/// </summary>
public enum Result
{
/// <summary>
/// 未知,还没开始判断
/// </summary>
Unknown,
/// <summary>
/// 平局,结果一致
/// </summary>
Dogfall,
/// <summary>
/// 胜,猜中结果
/// </summary>
Win,
/// <summary>
/// 负,对方猜中结果,自己没有猜中
/// </summary>
Lost,
/// <summary>
/// 犯规,
/// </summary>
Foul,
/// <summary>
/// 超时,反应时间超出100毫秒
/// </summary>
Overtime
} /// <summary>
/// 酒鬼类
/// </summary>
public abstract class Drunkard
{
/// <summary>
/// 出拳
/// </summary>
/// <param name="ANumber">出的手指数</param>
/// <param name="ASum">猜的合计</param>
abstract public void Come(out int AFinger, out int ASum); /// <summary>
/// 接收结果
/// </summary>
/// <param name="AOtherFinger">对方出的手指数</param>
/// <param name="AOtherSum">对方猜的合计</param>
/// <param name="AOtherResult">对方划拳的结果</param>
/// <param name="ASelfFinger">自己出的手指数</param>
/// <param name="ASelfSum">自己猜的合计</param>
/// <param name="ASelfResult">自己划拳的结果</param>
abstract public void Outcome(int AOtherFinger, int AOtherSum, Result AOtherResult,
int ASelfFinger, int ASelfSum, Result ASelfResult);
} public class Zswang一号 : Drunkard
{
public override void Come(out int AFinger, out int ASum)
{
AFinger = 5; // 每次都出5
ASum = 10; // 每次都猜10
} public override void Outcome(int AOtherFinger, int AOtherSum, Result AOtherResult,
int ASelfFinger, int ASelfSum, Result ASelfResult)
{
/* 这机器人不关心比赛结果 */
}
} public class Zswang二号 : Drunkard
{
private Random random;
public Zswang二号()
{
random = new Random();
} public override void Come(out int AFinger, out int ASum)
{
ASum = random.Next(10 + 1); //0-10
if (ASum < 5) // 别犯规
AFinger = random.Next(ASum + 1);
else AFinger = random.Next(ASum - 5, 5 + 1);
} public override void Outcome(int AOtherFinger, int AOtherSum, Result AOtherResult,
int ASelfFinger, int ASelfSum, Result ASelfResult)
{
/* 这机器人也不关心比赛结果 */
}
} /// <summary>
/// 酒馆类
/// </summary>
/// <typeparam name="T1">划拳机器人1</typeparam>
/// <typeparam name="T2">划拳机器人2</typeparam>
public class Drunkery<T1, T2>
where T1 : Drunkard, new()
where T2 : Drunkard, new()
{
/// <summary>
/// 东家
/// </summary>
private Drunkard eastPlayer;
/// <summary>
/// 西家
/// </summary>
private Drunkard westPlayer;
/// <summary>
/// 东家积分
/// </summary>
private int eastTotal;
/// <summary>
/// 西家积分
/// </summary>
private int westTotal;
/// <summary>
/// 东家超时次数
/// </summary>
private int eastOvertime;
/// <summary>
/// 西家超时次数
/// </summary>
private int westOvertime;
/// <summary>
/// 划拳次数
/// </summary>
public const int comeCount = 1000;
/// <summary>
/// 超时罚分
/// </summary>
public const int overtimePenalty = 1;
/// <summary>
/// 异常罚分
/// </summary>
public const int catchPenalty = 100;
/// <summary>
/// 开始比赛
/// </summary>
public void Play()
{
#region 初始化
long vEastTick = Environment.TickCount; // 东家初始化的时间
eastPlayer = new T1();
vEastTick = Environment.TickCount - vEastTick; long vWestTick = Environment.TickCount; // 西家初始化的时间
westPlayer = new T2();
vWestTick = Environment.TickCount - vWestTick; eastTotal = 0; westTotal = 0; eastOvertime = 0; westOvertime = 0; #region 超时处理
if (vEastTick > 1000 || vWestTick > 1000)
{
if (vEastTick > 1000)
Console.WriteLine("{0}初始化严重超时", typeof(T1).Name);
if (vWestTick > 1000)
Console.WriteLine("{0}初始化严重超时", typeof(T2).Name);
return;
}
if (vEastTick > 100)
{
eastTotal -= overtimePenalty;
eastOvertime++;
}
if (vWestTick > 100)
{
westTotal -= overtimePenalty;
westOvertime++;
}
#endregion 超时处理
#endregion 初始化 #region 猜拳过程
for (int i = 0; i < comeCount; i++)
{
for (int j = 0; j < 100; j++)
{
int vEastFinger = 0, vWestFinger = 0;
int vEastSum = 0, vWestSum = 0;
Result vEastResult = Result.Unknown;
Result vWestResult = Result.Unknown; #region 出拳
bool vEastCatch = false;
vEastTick = Environment.TickCount; // 东家出拳的时间
try
{
eastPlayer.Come(out vEastFinger, out vEastSum);
}
catch // 出现异常
{
vEastCatch = true;
}
vEastTick = Environment.TickCount - vEastTick; bool vWestCatch = false;
vWestTick = Environment.TickCount; // 西家出拳的时间
try
{
westPlayer.Come(out vWestFinger, out vWestSum);
}
catch // 出现异常
{
vWestCatch = true;
}
vWestTick = Environment.TickCount - vWestTick;
#endregion 出拳 #region 出现异常
if (vEastCatch || vWestCatch)
{
if (vEastCatch)
{
eastTotal -= catchPenalty;
westTotal++;
}
if (vWestCatch)
{
westTotal -= catchPenalty;
eastTotal++;
}
break;
}
#endregion 出现异常
#region 超时处理
if (vEastTick > 1000 || vWestTick > 1000)
{
if (vEastTick > 1000)
Console.WriteLine("{0}出拳严重超时", typeof(T1).Name);
if (vWestTick > 1000)
Console.WriteLine("{0}出拳严重超时", typeof(T2).Name);
return;
} if (vEastTick > 100)
{
vEastResult = Result.Overtime;
eastOvertime++;
}
if (vWestTick > 100)
{
vWestResult = Result.Overtime;
westOvertime++;
}
#endregion 超时处理 #region 判断谁犯规
if (vEastResult == Result.Unknown)
if (vEastSum < 0 || vEastSum > 10 ||
vEastFinger < 0 || vEastFinger > 5 ||
vEastSum - 5 > vEastFinger || vEastFinger > vEastSum)
vEastResult = Result.Foul;
if (vWestResult == Result.Unknown)
if (vWestSum < 0 || vWestSum > 10 ||
vWestFinger < 0 || vWestFinger > 5 ||
vWestSum - 5 > vWestFinger || vWestFinger > vWestSum)
vWestResult = Result.Foul;
#endregion 判断谁犯规 #region 有一个人犯规
if (vEastResult == Result.Foul ^ vWestResult == Result.Foul)
{
#region 如犯规判则对方赢
if (vEastResult == Result.Foul)
vWestResult = Result.Win;
else if (vWestResult == Result.Foul)
vEastResult = Result.Win;
#endregion 如犯规判则对方赢
}
#endregion 有一个人犯规 #region 划拳比较
if (vEastResult == Result.Unknown)
if (vEastFinger + vWestFinger == vEastSum)
vEastResult = Result.Win; if (vWestResult == Result.Unknown)
if (vEastFinger + vWestFinger == vWestSum)
vWestResult = Result.Win;
#endregion 划拳比较 #region 平局
if (vEastResult == vWestResult)
{
vEastResult = Result.Dogfall;
vWestResult = Result.Dogfall;
}
#endregion 平局 #region 出现胜负
if (vEastResult == Result.Win || vWestResult == Result.Win)
{
if (vEastResult == Result.Win)
{
eastTotal++;
vWestResult = Result.Lost;
}
else if (vWestResult == Result.Win)
{
westTotal++;
vEastResult = Result.Lost;
}
}
#endregion 出现胜负 #region 通知划拳的结果
vEastTick = Environment.TickCount;
vEastCatch = false;
try
{
eastPlayer.Outcome(vWestFinger, vWestSum, vWestResult,
vEastFinger, vEastSum, vEastResult);
}
catch
{
vEastCatch = true;
}
vEastTick = Environment.TickCount - vEastTick; vWestTick = Environment.TickCount;
vWestCatch = false;
try
{
westPlayer.Outcome(vEastFinger, vEastSum, vEastResult,
vWestFinger, vWestSum, vWestResult);
}
catch
{
vWestCatch = true;
}
vWestTick = Environment.TickCount - vWestTick;
#endregion 通知划拳的结果 #region 出现异常
if (vEastCatch || vWestCatch)
{
if (vEastCatch)
{
eastTotal -= catchPenalty;
westTotal++;
}
if (vWestCatch)
{
westTotal -= catchPenalty;
eastTotal++;
}
break;
}
#endregion 出现异常 #region 超时处理
if (vEastTick > 1000 || vWestTick > 1000)
{
if (vEastTick > 1000)
Console.WriteLine("{0}接收结果严重超时", typeof(T1).Name);
if (vWestTick > 1000)
Console.WriteLine("{0}接收结果严重超时", typeof(T2).Name);
return;
} if (vEastTick > 100)
{
eastTotal -= overtimePenalty;
eastOvertime++;
}
if (vWestTick > 100)
{
westTotal -= overtimePenalty;
westOvertime++;
}
if (eastOvertime > 10 || westOvertime > 10)
{
if (eastOvertime > 10)
Console.WriteLine("{0}超时十次以上", typeof(T1).Name);
if (westOvertime > 10)
Console.WriteLine("{0}超时十次以上", typeof(T2).Name);
return;
}
#endregion 超时处理 #region 出现胜负
if (vEastResult == Result.Win || vWestResult == Result.Win)
break;
#endregion 出现胜负
}
}
#endregion 猜拳过程 #region 输出结果
Console.WriteLine("{0}得分:{1}, {2}得分:{3}",
typeof(T1).Name, eastTotal,
typeof(T2).Name, westTotal);
Console.ReadLine();
#endregion 输出结果
}
} class Program
{
static void Main(string[] args)
{
new Drunkery<Zswang一号, Zswang二号>().Play();
}
}
}
{
private Random random;
public Zswang二号()
{
random = new Random();
} public override void Come(out int AFinger, out int ASum)
{
ASum = random.Next(10 + 1); //0-10
if (ASum < 5) // 别犯规
AFinger = random.Next(ASum + 1);
else AFinger = random.Next(ASum - 5, 5 + 1);
} public override void Outcome(int AOtherFinger, int AOtherSum, Result AOtherResult,
int ASelfFinger, int ASelfSum, Result ASelfResult)
{
/* 这机器人也不关心比赛结果 */
}
}
目前“Zswang二号”是第一个擂主!现在游戏开始!
new Drunkery<Zswang二号, 长江七号>().Play();
LZ好强
向LZ学习
比赛弄成Web Services
让我们做的机器人在本地通过Web Services就可以跟其他机器人比赛
public class zhangenter : Drunkard
{
private Random random;
int[] betterFinger = new int[] { 0, 0, 5, 5 };
int[] betterSum = new int[] { 0, 5, 5, 10 };
int lastIndex = 0; public zhangenter()
{
random = new Random();
} public override void Come(out int AFinger, out int ASum)
{
AFinger = betterFinger[lastIndex];
ASum = betterSum[lastIndex];
} public override void Outcome(int AOtherFinger, int AOtherSum, Result AOtherResult,
int ASelfFinger, int ASelfSum, Result ASelfResult)
{
if (ASelfResult != Result.Win)
{
int newIndex;
while ((newIndex = random.Next(4)) != lastIndex)
lastIndex = newIndex;
}
}
}
能问下LZ, public class Drunkery<T1, T2>
where T1 : Drunkard, new()
where T2 : Drunkard, new()这个是做什么吗?在自己的编码过程中怎么使用?
你可以参考40楼提交的代码,依照这个编写就可以了
where T1 : Drunkard, new()
where T2 : Drunkard, new()怎么理解吗?
擂主的代码是透明的,知己知彼可百战百胜
分析他的代码,很明显,他只会出手指0和5,只会猜结果是0,5,10
int[] betterFinger = new int[] { 0, 0, 5, 5 };
int[] betterSum = new int[] { 0, 5, 5, 10 };那我就出1个手指,他的结果(0,5,10)永远不会出现。
只要不犯规,就能可以完胜(得分1000)。
public class zhangenter_Killer : Drunkard
{
public override void Come(out int AFinger, out int ASum)
{
AFinger = 1;
ASum = 6;
} public override void Outcome(int AOtherFinger, int AOtherSum, Result AOtherResult,
int ASelfFinger, int ASelfSum, Result ASelfResult)
{ }
}
public class Zswang三号 : Drunkard
{
private Random random;
private int lessFour;
private int lassFour;
public Zswang三号()
{
random = new Random();
lessFour = 0;
lassFour = 0;
}
private int Finger()
{
int finger = 0;
if(lessFour>=lassFour)
finger = random.Next(5 + 1); //0-10
if(lessFour< lassFour)
finger = 5;
return finger;
}
public override void Come(out int AFinger, out int ASum)
{
AFinger = Finger(); //0-10
if(AFinger<=4)
ASum = 4;
else ASum = 10;
} public override void Outcome(int AOtherFinger, int AOtherSum, Result AOtherResult,
int ASelfFinger, int ASelfSum, Result ASelfResult)
{
/* 这机器人关心比赛结果 */
if(ASelfResult == Result.Win)
{
if(ASelfSum==4) lessFour++;
else lassFour++;
}
}
}俺们那里有个人猜拳很强悍,只猜4和10,大部分都能赢。
俺写的很菜,表骂俺...
D:\>2
Zswang二号得分:473, Zswang三号得分:527
D:\>2
Zswang二号得分:522, Zswang三号得分:478
D:\>2
Zswang二号得分:480, Zswang三号得分:520
D:\>2
Zswang二号得分:498, Zswang三号得分:502
D:\>2
Zswang二号得分:492, Zswang三号得分:508
D:\>2
Zswang二号得分:488, Zswang三号得分:512
public class Yuwenge : Drunkard
{
private Random random;
public Zswang二号()
{
random = new Random();
} public override void Come(out int AFinger, out int ASum)
{
AFinger = 2;
ASum = 2 + random.Next(99)%5+1;
}
public override void Outcome(int AOtherFinger, int AOtherSum, Result AOtherResult,
int ASelfFinger, int ASelfSum, Result ASelfResult)
{
/* 这机器人不关心比赛结果 */
}
}
{
AFinger=random.Next(6);
if (AFinger==5)
{
ASum = random.Next(10 + 1);
}
else
ASum = 5;
}好吃亏,输大了
public class Linxu一号 : Drunkard
{
public override void Come(out int AFinger, out int ASum)
{
ASum = 1;
AFinger = 1;
} public override void Outcome(int AOtherFinger, int AOtherSum, Result AOtherResult,
int ASelfFinger, int ASelfSum, Result ASelfResult)
{
/* 这机器人也不关心比赛结果 */
} }
但是结果:
Linxu一号得分:621, Zswang二号得分:379
Linxu一号得分:618, Zswang二号得分:382
Linxu一号得分:625, Zswang二号得分:375
Linxu一号得分:631, Zswang二号得分:369
现在这样要想赢还是只能靠运气啊
能加上界面图形我想就更好了,每个人的机器人做成dll的形式由一个Game.exe自己选择调用,加载图形界面,加载两个dll进行PK
最终显示结果
public class yunfeng007 : Drunkard
{
private Random random;
private int lessFour;
private int lassFour;
private int otherlessFour;
private int otherlassFour;
public yunfeng007()
{
random = new Random();
lessFour=0;
lassFour=0;
otherlessFour=0;
otherlassFour=0;
}
private int Finger()
{
int finger = 0;
if(lessFour>=lassFour)
finger = 1 + random.Next(3 + 1); //0-10
if(lessFour< lassFour)
finger = 5;
return finger;
}
public override void Come(out int AFinger, out int ASum)
{
AFinger = Finger(); //0-10
if(AFinger<=4)
ASum = 4;
else ASum = 10;
} public override void Outcome(int AOtherFinger, int AOtherSum, Result AOtherResult,
int ASelfFinger, int ASelfSum, Result ASelfResult)
{
if(AOtherFinger<=4) ++otherlessFour;
else ++otherlassFour;
/* 这机器人关心比赛结果 */
if(ASelfResult == Result.Win)
{
if(ASelfSum==4) ++lessFour;
else ++lassFour;
}
if(ASelfResult == Result.Lost || ASelfResult == Result.Unknown)
{
if(ASelfSum==4 && otherlessFour<=otherlassFour)
{--lessFour;++lassFour;}
else {--lassFour;++lessFour;}
}
}
}我这个虽然不好赢zswang二号,但赢现在的Linxu一号还是绰绰有余的吧??
做一下统计,伴水二号出0个手指和5个手指的几率最大。
合计(sum)概率均等
手指(finger)概率是向大小两头增加
因为出手指是有条件的,必须满足finger <= sum && finger >= sum - 5