日期:2014-05-20  浏览次数:21211 次

【编程游戏】划拳机器人,前面一贴的机器人都集中来了,继续PK。谨慎路过。
参考上一贴:【编程游戏】编写一个会划拳的机器人参加擂台赛,规则内详。路过有分。
不过上一帖的楼太高、打开太慢,所以我把那些机器人集中到这PK
打败对手最多的机器人获胜!奖励200分,其余酌情散掉。。。

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

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

  只要继承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、打擂容易守擂难,大家自由发挥吧! 

谢谢关注

先帖调试代码:
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 出现异常