点滴记录总结,一天一打鸡血。
2015年5月华为组织了一次软件精英挑战赛,赛题是德州扑克手牌AI~
环境及测试说明:http://pan.baidu.com/s/1dD2dL0P
本来想吧副标题写成”决策“的,既然是if-else得来,那怎配得上那二字。接下来两节就是个人打牌策略了,这一节说说打牌总体思路,以及一些准备工作。
全程我用了三个动作:fold/raise/check,因为一个check发过去,要是不合理服务器会自动转的,具体参考环境及测试说明。这样就省事了(这是有多累,想到了十万个冷笑话)。。。
raise的金额有一定随机性,这样也可以达到吓唬人的效果,但是有个比较尴尬的场合就是,这一轮raise了很多,对手再raise后,就fold了,这样不太合理,所以,一般没大牌不要raise,要么就是咋唬!要raise就跟到底咯。这就要求第一圈加注或跟注必须十分谨慎,不要把自己套进去了。
动作的代码:
char* Decision(int flag) {
char *result = NULL;
//这里会对自己手牌分两种极端,一种吓唬型bigcall=1,一种灰常大牌型bigcall==0
if (flag > HOLD )
if (bigcall == 0) {
if (gameInfo.total_call < 300 + game_circle*200) {
return Raise(3);
return "check";
}
if (bigcall == 1)
return "check";
}
switch(flag) {
case HOLD:
result = HoldDecision();break;
case FLOP:
result = FlopDecision();break;
case TURN:
result = TurnDecision();break;
case RIVER:
result = RiverDecision();break;
}
if (result == NULL)
return FoldDecision();
return result;
}
再作一点说明,在发送动作消息时,不要把字符串写死了,比如这样:”raise 119“,有可能下一个是这样”riase 119“,这样发过去服务器会认为你掉线咯,所以动作用函数实现就好,比如Raise(xx),只需要在函数内把字符串写正确,这也是编程中的细节吧。
每个动作的代码类似,以HoldDecision为例给出:
char* HoldDecision() {
int players = gameInfo.players -gameInfo.folds;
//只有我一个人再玩,让吧。
if (players <= 1)
return "check";
//我吓人,人家不惧,跟吧
if (intimidate >= HOLD) {
return "check";
}
//我是最后一个出牌,前面的人很猥琐,那我只好吓吓他们咯
if (strcmp(gameInfo.b_blind, reg_id) == 0) {
if (gameInfo.total_call <= 120){
intimidate = HOLD;
return Raise(5);
}
return HoldOne();
}
//正常程序,这节不给出
return HoldOne();
}
上面的代码也是不很规范,比如return “check”,写的时候都是心惊肉跳,担心出问题,这个没改是因为来不及改了!比赛前一天还在改策略,既然没掉线的问题就放着了,一直到今天。
基本解释在代码中给出,正常程序是最后一行,根据手牌、公牌来出牌。
其他圈类似,不一一给出,下一节详细说说每圈的动作。