我们来玩一个类似“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、其余分数酌情散掉。标准代码和比赛规则有什么不妥或者建议欢迎讨论,谢谢关注(调试代码参考后面两帖,-_-!!!代码有点多,先别抢沙发。)

解决方案 »

  1.   

    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 出现异常
      

  2.   


                        #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();
            }
        }
    }
      

  3.   

    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二号”是第一个擂主!现在游戏开始!
      

  4.   

    可以这样调试自己的代码,擂主:T1、挑战者:T2
    new Drunkery<Zswang二号, 长江七号>().Play();
      

  5.   

    很有意思, 呵呵建议将完整的工程放到 csdn 下载区,这样才好编写新的机器人
      

  6.   

    收藏~学习~
    LZ好强
    向LZ学习
      

  7.   

    建议楼主做一个框架
    比赛弄成Web Services
    让我们做的机器人在本地通过Web Services就可以跟其他机器人比赛
      

  8.   

    随机性太高了,感觉根本没办法守擂,打擂也要靠一点随机,抛砖引玉了
    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;
                }
            }
        }
      

  9.   

    看完了代码,一个字,爽,
    能问下LZ,    public class Drunkery<T1, T2>
            where T1 : Drunkard, new()
            where T2 : Drunkard, new()这个是做什么吗?在自己的编码过程中怎么使用?
      

  10.   

    感谢40提供的代码,但是没有获得600分以上,不能打败擂主这是泛型,指定T1、T2必须从Drunkard继承
    你可以参考40楼提交的代码,依照这个编写就可以了
      

  11.   

    看完代码,很爽LZ能讲解一下    public class Drunkery<T1, T2>
            where T1 : Drunkard, new()
            where T2 : Drunkard, new()怎么理解吗?
      

  12.   

    提示一下:Random是一个伪随机^o^
    擂主的代码是透明的,知己知彼可百战百胜
      

  13.   

    比如攻击40楼的机器人:
    分析他的代码,很明显,他只会出手指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)
        {    }
    }
      

  14.   


    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
      

  15.   

    当然zhangenter_Killer如果当上擂主也将不堪一击目前擂主还是“Zswang二号”
      

  16.   


    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)
        {
            /* 这机器人不关心比赛结果 */
        }
    }
      

  17.   

    有时间把此代码应用在winform中!!先搜藏下!
      

  18.   

            public override void Come(out int AFinger, out int ASum)
            {
                AFinger=random.Next(6);
                if (AFinger==5)
                {
                    ASum = random.Next(10 + 1);
                }
                else
                    ASum = 5;
            }好吃亏,输大了
      

  19.   


        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)
            {
                /* 这机器人也不关心比赛结果 */
            }    }
      

  20.   

    Linxu一号能打败Zswang二号,现在“Linxu一号”擂主 // 不过守擂不了多久。
      

  21.   

    不知道为什么
    但是结果:
    Linxu一号得分:621, Zswang二号得分:379
    Linxu一号得分:618, Zswang二号得分:382
    Linxu一号得分:625, Zswang二号得分:375
    Linxu一号得分:631, Zswang二号得分:369
      

  22.   

    网上没找到random.next的算法,楼主知道吗?
    现在这样要想赢还是只能靠运气啊
      

  23.   

    不错的想法
    能加上界面图形我想就更好了,每个人的机器人做成dll的形式由一个Game.exe自己选择调用,加载图形界面,加载两个dll进行PK
    最终显示结果
      

  24.   


    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一号还是绰绰有余的吧??
      

  25.   


    做一下统计,伴水二号出0个手指和5个手指的几率最大。
    合计(sum)概率均等
    手指(finger)概率是向大小两头增加
    因为出手指是有条件的,必须满足finger <= sum && finger >= sum - 5