2015华为软赛(八)——动作二

点滴记录总结,一天一打鸡血。

2015年5月华为组织了一次软件精英挑战赛,赛题是德州扑克手牌AI~

环境及测试说明:http://pan.baidu.com/s/1dD2dL0P

最后一节吧,真心觉得贴代码没意思,反正自己不会去看代码了,只想把中间一些感触写下来,时间一长加上一忙,感觉找不到了。这时候的感触是,有货趁早写,别拿忙开脱,就是懒!这一节先别贴代码,来点鸡汤解渴先~

在能玩牌的基础上,想玩好可不太简单,特别是程序本身就是死的,这就需要策略具备一定灵活性,说到这就不由自主往机器学习上靠,其实没那么复杂,由于每次游戏有上限600局,加上决策时间有限500ms,使得机器学习在这里很难凑效的。但是,策略模型是要的,对手模型也是要的。这两个,很重要,你可以ifelse垒起来,尽管效率不太高;也可以基于一些比较成熟的算法模型,这样最好,但是需要理论基础了。

你的策略会综合很多指标,比如筹码数、玩家数、跟注额、座次顺序等,大部分玩家都是在这一点下足功夫了,因为这样简单高效。至于对手模型,我个人觉得这才是高端玩家的分水岭,像马云说的,其他不重要,了解人需求最重要,由于大部分玩家程序比较刻板,这给建立对手模型带来契机,当知道对手套路,加注弃牌收放自如。比赛中真看到的,有这样的人。赛后还调侃,打个牌都算,还怎么玩。。。

写到这打住吧,说说我的响应动作。在HOLD圈,一般不会出现随便跟注的情况,要么自己是大盲注(要咋唬),要么就是拿大牌,就加注,一般不会跟注,除非对手加注金额比较高。在之后的圈,就判断自己是否是咋唬,咋唬一套,非咋唬一套,总之只要自己加了,就不会轻易弃牌。设定加注满足一定条件就弃牌的策略,这样真的不好,初赛看这样的比赛真是虐心。。。
给出HOLD圈的正常代码吧:

char* HoldOne() {
    float p = Uniform();
    int card[2] = {0};
    card[0] = gameInfo.card[0] % 14;    
    card[1] = gameInfo.card[1] % 14;

    int pairs = 0;  
    if (card[0] == card[1])
        pairs = card[0];

    int len = strlen(opponent.bigid);
    if (pairs >= 11) {
        bigcall = 0;
        if (gameInfo.total_call > 420)
            return "check";
        else if (gameInfo.total_call > 300)
            return Raise(3);
        else if (gameInfo.total_call > 120)
            return Raise(4);
        return Raise(8);
    }


    if (pairs >= 8) {
        if (len > 0) {
            bigcall = 1;
            return Raise(2);
        }
        if (gameInfo.total_call < 125)
            return Raise(3);
        else if (gameInfo.total_call < 200)
            return Raise(2);
        return "check";
    }


    if (card[0] >=11 && card[1] >= 11) {
        if (len > 0) {
            bigcall = 1;
            return Raise(2);
        }
        if (gameInfo.total_call < 125)
            return Raise(3);
        else if (gameInfo.total_call < 200)
            return Raise(2);
        return "check";
    }

    return FoldDecision();

}

最后有个FoldDecision(),这样写的好处之前说过,此外,还可以判断自己是否第一个出牌,第一个就可以让牌,没必要弃牌的。
下面给出RIVER圈的代码:

char*   RiverOne(int detaCall) {

    float p = Uniform();
    int card[7] = {0};
    card[0] = gameInfo.card[0] % 14;
    card[1] = gameInfo.card[1] % 14;
    card[2] = common_cards[0] % 14;
    card[3] = common_cards[1] % 14;
    card[4] = common_cards[2] % 14;
    card[5] = common_cards[3] % 14;
    card[6] = common_cards[4] % 14;
    int max_card = Max(Max(Max(card[2], card[3]), Max(card[4], card[5])), card[6]);

    if (cardType.my_type >= FOUR)//straight four
    {
        if (cardType.four.com > 0) 
            return ComFourDecision();

        if (detaCall < 80)
            return Raise(3);
        else if (detaCall <= 200)
            return Raise(2);
        return  "check";
    }
    else if (cardType.my_type == FULLHOUSE)//fullhouse
    {
        return FullHouseDecision(card, detaCall);
    }
    else if (cardType.my_type >= STRAIGHT) //s_card.flush
    {
        if (HasComPair(game_circle+2) >= 2) {
            if (detaCall <= 120)
                return "check";
            return FoldDecision();
        }
        if (cardType.s_card.own == 5) {
            if (cardType.s_card.com <= 3) {
                if (detaCall < 80)
                    return Raise(3);
                else if (detaCall <= 200)
                    return Raise(2);
                return  "check";
            }
            return "check";
        }
        if (cardType.f_card.own == 5) {
            if (cardType.s_card.com <= 3) {
                if (detaCall < 80)
                    return Raise(3);
                else if (detaCall <= 200)
                    return Raise(2);
                return  "check";

            }
            return "check";
        }
    }

    if (cardType.s_card.com >= 4 || cardType.f_card.com >= 4) 
        if (detaCall > 120)
            return FoldDecision();


    if (cardType.my_type == THREE) {//three
        if (card[0] == cardType.three || card[1] == cardType.three) {

            if (detaCall < 70)
                return Raise(3);
            else if (detaCall <= 120)
                return Raise(2);
            return  "check";
        }
        if (card[0] >= 12 || card[1] >= 12) {
            if (detaCall < 240)
                return "check";
            return FoldDecision();
        }
        if (detaCall > 100)
            return FoldDecision();
        return FoldDecision();
    }
    //under TwoPairDecision
    return TwoPairDecision(card, detaCall, max_card);

    return FoldDecision();

}

上面有个TwoPairDecision(card, detaCall, max_card);这样写的好处是提高代码复用率了,因为后面三个押注圈都会有这样的策略。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值