c++ - 扑克代码清理修改从书...不太正确

标签 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 高位和低位 - 现在正如上面定义的 A 是低位...

两个版本:第一个似乎不确定正确与低 A...

代码

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 high 和 low:

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;
}

我在评论中的内容是否可以同时处理 ace high 和 low ......

因为 i = 1 表示为 ace 并且不确定 values[1] 是正确的应该是 values[13] 还是什么...也许是类似的东西

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

建议-

  • 不想进行大规模更改 - 只是对我现有的进行微小更改...我不想通过蛮力进行排序或解决,例如 values[1] == 1 && values [2] ==1 你明白了——文本已经做到了这一点,但我正试图以这种方式重写它……

谢谢...希望我能理解我想要的修改...

最佳答案

编辑:我想我会先直接回答你的问题。让我们首先弄清楚原始算法是如何工作的。基本上它从 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 张,并且我们刚刚查看了最后一张牌(循环结束),那么检查是否有 A,如果有,我们确实有顺子,它是 A 高”。

原始答案: 我认为处理 ace high 和 low 的最简单方法是让“get rank”函数有两种模式,一种返回 ace high,另一种返回 ace low。然后只需计算每种情况下的手牌值,然后取较好的。

此外,您的排名可能更简单 :-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;
    }
}

编辑:

为了好玩,我制作了一个快速但肮脏的程序来检测顺子(处理高 A 和低 A)。它相当简单,但可以更短(另请注意,这些数组没有尝试缓冲区安全,生产质量的东西应该使用更安全的东西,例如 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;
}

关于c++ - 扑克代码清理修改从书...不太正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/997498/

相关文章:

c++ - boost::optional 和类型转换

c - 删除C中链表中的头或唯一节点

c - x64 Windows下的快速光纤/协程

c - Lua C API : How to load lua files defined as modules?

c - 是否可以创建具有可变数量元素的数组?

c++ - 如何提取opencv Mat header ?

c++ - 打印所有给定N的偶数或奇数

c++ - 如何消除挑战 'Sam and sub-strings' 中与模数相关的错误?

c - 乘以十六进制 > uint32> 返回十六进制

c++ - g++ makefile 错误 : *. o: 没有那个文件或目录