首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • 【编程游戏】编写一个会划拳的机器人参加擂台赛,规则内详。路过有分。 [已结贴,结贴人:zswang]
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zswang
    • 等级:
    发表于:2008-04-21 17:55:42 楼主
        我们来玩一个类似“Robocode”的游戏。

    划拳介绍    划拳又叫豁拳、猜枚、猜拳、拇战,即饮酒时两人同时伸出手指并各说一个数,谁说的数目跟双方所伸手指的总数相符,谁就算赢,输的人喝酒。此乃我国

    古传至今仍时尚流行的饮酒游戏,它增添酒兴,烘托喜庆,是一种民间的酒令。 其技巧性颇强,给玩者留有神机斗智的余地,且因玩时须喊叫,易让人兴奋,极富竞争性。

      两人同时伸出一只手,用攥起的拳头和伸出一到五个手指,表示从零到五这几个数字,与此同时,嘴里喊出从零到10的数字,如果两人伸出的手指表示的数字相加与其中一个

    人嘴里喊出的数字相同,那么这个人就算赢了这一拳。举例说明:比如一个人伸出了三个手指,另一个人伸出了四个手指,一个人喊了七,另一个喊了六,那么这个人喊七的人就赢

    了;如一个人伸出攥紧的拳头(表示零),嘴里喊出了三,而另一个恰好伸出了三个手指可嘴里喊的七,那么喊三的就赢了。就这么简单。当然,如果自己喊的是“八仙过海”,

    而自己仅伸出了一个手指,那么对方即使伸出五指也不可能凑成八,这种拳就叫臭拳,如果不是事先约定,是要罚酒的。


        划拳规则看完了,那我们就开始写一个会划拳的机器人吧!

        那么一个会划拳的机器会做什么事情呢?其实就是两件:
    第一件、出拳,即:自己出几个手指?自己猜合计是多少。
    第二件、知道划拳的结果,即:对方出几个手指,对方猜合计是多少,是否获胜还是平局还是其他。

      只要继承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、其余分数酌情散掉。

    标准代码和比赛规则有什么不妥或者建议欢迎讨论,谢谢关注

    (调试代码参考后面两帖,-_-!!!代码有点多,先别抢沙发。。。。)
    400  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zswang
    • 等级:
    发表于:2008-04-21 17:56:141楼 得分:0
    C# code
    using System; 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 出现异常
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zswang
    • 等级:
    发表于:2008-04-21 17:56:262楼 得分:0
    C# code
    #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(); } } }
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zswang
    • 等级:
    发表于:2008-04-21 17:57:373楼 得分:0
    C# code
    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) { /* 这机器人也不关心比赛结果 */ } }


    目前“Zswang二号”是第一个擂主!现在游戏开始!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-21 18:00:274楼 得分:1
    沙发。学习跟伴水学习
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-21 18:05:355楼 得分:1
    LZ很厉害!!!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zswang
    • 等级:
    发表于:2008-04-21 18:05:446楼 得分:0
    可以这样调试自己的代码,擂主:T1、挑战者:T2
    C# code
    new Drunkery<Zswang二号, 长江七号>().Play();
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-21 18:08:587楼 得分:1
    立志向楼主学习
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-21 18:10:008楼 得分:1
    真是开眼了!!!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-21 18:20:579楼 得分:1
    在这先标记一下
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-21 18:27:4110楼 得分:1
    路过拿分来了。。的确很有意思。。留个标记
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-21 18:36:0211楼 得分:1
    有意思~ 路过 没时间搞
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-21 18:44:4912楼 得分:1
    路过 mark
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-21 18:51:2913楼 得分:1
    LZ,很厉害,崇拜一个先
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-21 18:53:2814楼 得分:1
    强帖留名而已。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-21 18:55:1715楼 得分:1