从书中删除扑克代码清理......不太正确

时间:2009-06-15 18:08:28

标签: c++ c

通过更多书籍示例 - 这是一个部分扑克计划 - 这一部分直接涉及....

首先给出的内容 - 只有相关部分....如果需要,将提供完整的代码......

int suits[5]; //index 1..4- value start at 1
int values[14]; //index 1..13- value same as rank, A = 1, K = 13

cin.get(rankCh);
switch (toUpper(rankCh)) {
case 'A': values = 1; break;
case '2': values = 2; break;
case '3': values = 3; break;
case '4': values = 4; break;
case '5': values = 5; break;
case '6': values = 6; break;
case '7': values = 7; break;
case '8': values = 8; break;
case '9': values = 9; break;
case 'T': values = 10; break;
case 'J': values = 11; break;
case 'Q': values = 12; break;
case 'K': values = 13; break;
default:
badCard = true;
}

其他功能:

bool isFlush(int suits[]) {
    for(i = 1; i <= 4; i++)
        if (suits[i] == 5)       //5 here is Number of Cards 
            return true;
    return false;
}

是的,我知道数组声明但是它是如何定义的 - 在文本中很好地证明它...开始编号为1 我希望我的直接手能够同时处理高位和低位,因为上面的A值很低......

两个版本:第一个看起来不确定是否正确低......

CODE

bool isStraight(int values[]) //Version one only straight- low aces only
{
    int count = 0;

    for (i = 1; i <= 13; i++) {
        if (values[i] != 1) {
            count++;
        } else
            count = 0;

        if (count == 5) //5 is NUMCARDS
            return true;
    }
    return false;
}

现在这是我需要一些建议的地方:有一个功能来处理ace高和低:

bool isStraight(int values[]) //Version handles both high and low
{
    int count = 0;

    for (i = 1; i <= 13; i++) {
        if (values[i] != 1) {
            count++;
            // if(i == 1 && values[1] != 0) //Check for high and low
            // count++;
        } else
            count = 0;

        if (count == 5) //5 is NUMCARDS
            return true;
    }
    return false;
}

我在评论中的作用是否能够同时处理高等和高等......

由于i = 1表示为ace并且不确定哪些值[1]是正确的应该是值[13]还是......可能类似

if (i == 1)
   values[13] //not sure... 

建议 -

  • 不要批量改变 - 只是对我所拥有的东西进行微小的改变......我不想用强力进行分类或解决,例如值[1] == 1&amp;&amp;值[2] == 1你得到了点 - 文本已经做到了但是我试图用这种方式重写它......

谢谢...希望我能够完成修改,我希望...

2 个答案:

答案 0 :(得分:2)

编辑:我想我会先直接回答你的问题。让我们首先了解原始算法的工作原理。基本上它从1到13循环,并且每次它看到该插槽中的卡时,它会增加计数。如果有任何事情打破了序列,它会重置计数器。最后,如果计数器达到5,你就会有一个直线。

如果你的解决方案有效,我不能说是手头,我说试一试。但是,对原版的简单快速补丁可能会是这样的:

//Version handles both high and low
bool isStraight(int values[]) {
    int count = 0;

    for (i = 1; i <= 13; i++) {
        if (values[i] != 1) {
                count++;
        } else
                count = 0;

        if (count == 5) //5 is NUMCARDS
                return true;
    }

        // handle ace high.
        if(count == 4 && values[1] != 0) {
            return true;
        }

    return false;
}

基本上它的作用是说“如果我们已经连续4个,我们只看了最后一张牌(循环结束了),然后检查一下是否有牌,如果有,我们确实有直的,它是高的“。

原始回答: 我认为处理高位和低位的最简单方法是让“获得等级”功能有两种模式,一种返回ace高,另一种返回ace低。然后只计算每个案例的手值并采取更好的一个。

此外,您的获得排名可能更简单:-P。

int get_rank(char card) {
    static const char *cards = "A23456789TJQK";
    char *p = strchr(cards, toupper(card));
    if(p) {
        return (p - cards) + 1; 
    } else {
        return -1;
    }
}

所以如果你想拥有一个带有ace_high或ace_low的get_rank,你可以这样做:

int get_rank(char card, bool ace_high) {
    static const char *cards_high = "23456789TJQKA";
    static const char *cards_low = "A23456789TJQK";

    const char *cards = ace_high ? cards_high : cards_low;

    char *p = strchr(cards, toupper(card));
    if(p) {
        return (p - cards) + 1; 
    } else {
        return -1;
    }
}

修改

为了好玩,我做了一个快速而又脏的程序来检测直道(处理高和低的ace)。它相当简单,但可能更短(同时请注意,这些阵列没有尝试缓冲安全性,生产质量应该使用更安全的东西,例如std::vector

#include <algorithm>
#include <iostream>
#include <cstring>

int get_rank(char card, bool ace_high) {
    static const char *cards_high = "23456789TJQKA";
    static const char *cards_low = "A23456789TJQK";
    const char *cards = ace_high ? cards_high : cards_low;

    char *p = strchr(cards, toupper(card));
    if(p) {
        return (p - cards) + 1; 
    } else {
        return -1;
    }
}

bool is_rank_less_low(int card1, int card2) {
    return get_rank(card1, false) < get_rank(card2, false);
}

bool is_rank_less_high(int card1, int card2) {
    return get_rank(card1, true) < get_rank(card2, true);
}

bool is_straight(int hand[], bool ace_high) {

    std::sort(hand, hand + 5, ace_high ? is_rank_less_high : is_rank_less_low);
    int rank = get_rank(hand[0], ace_high);
    for(int i = 1; i < 5; ++i) {
        int new_rank = get_rank(hand[i], ace_high);
        if(new_rank != rank + 1) {
            return false;
        }
        rank = new_rank;
    }
    return true;
}

bool is_straight(int hand[]) {
    return is_straight(hand, false) || is_straight(hand, true);
}

int main() {
    int hand1[5] = { 'T', 'J', 'Q', 'K', 'A' };
    int hand2[5] = { 'A', '2', '3', '4', '5' };
    std::cout << is_straight(hand1) << std::endl;
    std::cout << is_straight(hand2) << std::endl;
}

答案 1 :(得分:1)

通过更改最终测试可以找到存在ace-high笔直的情况:

if (count == 5 || count == 4 && values[1] == 1) // 2nd case handles ace-high straight
    return true;

这是一个特例,所以必须单独处理。