确定印度拉米纸牌是否为获胜牌 - Java

2024-02-08

我正在寻找一种有效的解决方案来确定一手牌是否是印度拉米纸牌中的获胜手牌。印度拉米纸牌在混合方面与金罗米纸牌类似。人们可以融合相同花色的序列(顺子)或融合一组相同的值。序列和集合都应至少包含 3 张牌。与金罗米牌不同,印度拉米牌一手牌由 13 张牌组成。一手获胜牌应包含至少两个序列,并且这些序列中至少一个必须是纯序列。纯粹,我的意思是该序列不应该在小丑(通配符)的帮助下制作。手牌的其余部分可以由带有或不带有小丑的序列和集合组成。注意:除了一副牌中的 2 张王牌(52 + 2)外,牌组中还有一张随机牌用作王牌。例如,如果随机选择黑桃 5 作为小丑,则牌组中其他花色的剩余 3 个 5 可以用作 2 个常规小丑之上的小丑。

以下是一些不使用小丑的有效获胜手牌的示例:

  • A,K,Q,J(黑桃)|2,3,4(红心)|2,2,2(黑桃,梅花,方块)|3,4,5(方块)
  • A,K,Q,J,10(黑桃)|4,5,6,7,8(梅花)|9,9,9(方块,梅花,黑桃)
  • A,K,Q,J,10,9,8,7,6,5(黑桃)|4,3,2(黑桃)

以下是一些使用小丑赢得牌局的例子。假设 6(黑桃)是从牌堆中随机挑选的小丑;所以剩下的所有 6 都可以用作小丑。

  • A,K,Q,J(黑桃;纯序列)|7,7,7(方块,梅花,黑桃)|3,3,6(方块,梅花,梅花;与百搭组合)|A,2,6(俱乐部,俱乐部,红心)
  • A,2,3(红桃)|4,5,6(红桃)|7,7,7,7(黑桃,梅花,方块,红桃)|8,6,10,小丑(黑桃,方块,黑桃;序列与小丑、6 和普通小丑)

以下是一些示例:NOT获胜的一手牌:

  • A,2,Joker(红心)|4,5,Joker(红心)|7,7,7,7(所有花色)|9,9,9(梅花,方块,红心)(这不是有效牌,因为它不包含纯序列)
  • A,2,3,4(红心)|7,7,7(梅花,钻石,红心)|8,8,8(梅花,钻石,红心)|9,9,9(梅花,钻石,红心) (这是无效的,因为它不包含第二个序列)

我希望这已经解释了什么是获胜牌。下面的模型代表一张卡:

public class Card {

public final static int SPADES = 0,
        HEARTS = 1,
        DIAMONDS = 2,
        CLUBS = 3;

public final static int ACE = 1,
        JACK = 11,
        QUEEN = 12,
        KING = 13,
        JOKER = 0;

private final int suit;

private final int value;

public Card(int theValue, int theSuit) {
    value = theValue;
    suit = theSuit;
}

public int getSuit() {
    return suit;
}

public int getValue() {
    return value;
}

public String getSuitAsString() {
    switch ( suit ) {
        case SPADES:   return "Spades";
        case HEARTS:   return "Hearts";
        case DIAMONDS: return "Diamonds";
        case CLUBS:    return "Clubs";
        default:       return "??";
    }
}

public String getValueAsString() {
    switch ( value ) {
        case 1:   return "Ace";
        case 2:   return "2";
        case 3:   return "3";
        case 4:   return "4";
        case 5:   return "5";
        case 6:   return "6";
        case 7:   return "7";
        case 8:   return "8";
        case 9:   return "9";
        case 10:  return "10";
        case 11:  return "Jack";
        case 12:  return "Queen";
        case 13:  return "King";
        default:  return "JOKER";
    }
}

@Override
public String toString() {
    return getValueAsString().equals("JOKER") ? "JOKER" : getValueAsString() + "(" + getSuitAsString() + ")";
}

@Override
public boolean equals(Object card) {
    return suit == ((Card) card).getSuit() && value == ((Card) card).getValue();
}

}

我还编写了一些函数来获取卡中可能的序列和集合。 getSequences 函数中的参数 (List) 已按花色排序,然后按值排序。对于 getSets 函数中的参数,卡片仅按值排序。两个函数中第二个参数 (min) 的值为 3。

private List<List<Card>> getSequences(List<Card> hand, int min) {
    List<List<Card>> sequences = new ArrayList<>();
    List<Card> sequence = new ArrayList<>();
    for(int i=1; i<hand.size(); i++) {
        if(hand.get(i).getSuit() == hand.get(i-1).getSuit() &&
                (hand.get(i).getValue() - hand.get(i-1).getValue()) == 1) {
            sequence.add(hand.get(i-1));
            if(hand.get(i).getValue() == 13) {
                int j = i;
                while(hand.get(j).getSuit() == hand.get(i).getSuit()) {
                    j--;
                    if(hand.get(j).getValue() == 1) {
                        sequence.add(hand.get(j));
                    }
                }
            }
            if(i == hand.size() -1) {
                sequence.add(hand.get(i));
                sequences.add(sequence);
            }
        } else {
            sequence.add(hand.get(i-1));
            if(sequence.size() >= min) {
                sequences.add(sequence);
            }
            sequence = new ArrayList<>();
        }
    }
    return sequences;
}

private List<List<Card>> getSets(List<Card> hand, int min) {
    List<List<Card>> sets = new ArrayList<>();
    List<Card> set = new ArrayList<>();
    for(int i=1; i<hand.size(); i++) {
        if(hand.get(i).getValue() != joker.getValue()) {
            if(hand.get(i).getValue() == hand.get(i-1).getValue()) {
                set.add(hand.get(i-1));
                if(i == hand.size() -1) {
                    set.add(hand.get(i));
                }
            } else {
                set.add(hand.get(i-1));
                if(set.size() >= min) {
                    sets.add(set);
                }
                set = new ArrayList<>();
            }
        }
    }
    return sets;
}

我不认为这是查找序列和集合的最优雅的方法。因此,我欢迎任何关于如何改进它的建议。但我真正需要帮助的是我下一步该怎么做?集合和序列之间可能存在重叠。例如,如果有以下卡:

  • A,2,3(黑桃)|4,4,4(黑桃,梅花,红桃) 我的 getSequences 函数将返回 A,2,3,4(黑桃) 作为序列。我应该避免在我的序列中包含 4 个黑桃,以便将其用于 4 组中。

请提供如何有效确定获胜手牌的建议。

P.S:在判定胜手牌时,玩家手上有14张牌。融合 13 张牌后,第 14 张牌将作为终结牌被丢弃。


我已经实现了 Rummikub 的 java 版本(具有类似约束的游戏)。

我的方法是为每张卡赋予一个隐藏的整数属性(质数)。

然后每个有效的组合都可以唯一地表示为一个整数。 可以预先计算形成有效融合的精确整数并将其放入Set<Long>当然。

然后,检查一手牌是否仅包含有效的组合就简化为检查给定的长整型是否可以写为一组给定数字的乘积。 (可以使用递归和动态规划)

具体例子(1):

  • 红桃 A => 2
  • 两颗红心 => 3
  • 红心三 => 5

Set<Long> validMelds = {30, .., ..}

如果手牌(值 = 60),那么我们知道它包含 2 个有效的组合。

具体例子(2)

  • 1 球杆 = 2
  • 2 梅花 = 3
  • 3 梅花 = 5
  • 4 梅花 = 7
  • 红心 4 = 179
  • 4 颗钻石 = 181

已知有效融合 = {30, 210, 226793, ..}

手牌价值 = 6803790

简单(递归)算法:

  1. 6803790 能被 30 整除
  2. (6803790 / 30 = ) 226793 能被 226793 整除
  3. 递归算法得出结论这是一个有效的分支

    选择

  4. 6803790 能被 210 整除

  5. (6803790 / 210) = 32399 不能被任何有效的融合数整除
  6. 递归算法结束分支到此停止

    如果您需要能够处理部分手牌并不总是有效组合的一部分的情况,您可能希望研究一下线性代数 http://pds2.egloos.com/pds/200611/17/89/solving%20rummikub%20problems%20by%20integer%20linear%20programming.pdf.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

确定印度拉米纸牌是否为获胜牌 - Java 的相关文章

  • Android PhoneGap 插件,UI 选项卡栏,调整 WebView 大小

    我正在创建一个美味的 PhoneGap 插件 希望一旦它能被打开 准备好了 插件基本完成了 我只需要一个漂亮的用户界面 相互作用 简而言之 我想创建一个 本机 android 工具栏组件 如果您实现 PhoneGap UIControls
  • Java - 如何将特殊字符放入字符串中

    Java 似乎有很好的字符串处理能力 尽管如此 我还是遇到了最简单的问题 我需要动态字符串 它们在运行时更改 因此字符串类型不是一个好的选择 因为它们是不可变的 所以我使用字符数组 设置起来有点痛苦 但至少它们是可以修改的 我想创建一个字符
  • 使用 HttpUrlConnection Android 将 base64 编码的图像发送到服务器

    我正在尝试使用 HttpUrlConnection 将 base64 编码的图像发送到服务器 我遇到的问题是大多数图像均已成功发送 但有些图像会生成 FileNotFound 异常 我的图像编码代码可以在下面找到 public static
  • Jackson - 反序列化嵌套 JSON

    我有一个 JSON 字符串 其格式如下 response execution status ready report cache hit true created on 2013 07 29 08 42 42 fact cache erro
  • URL.setURLStreamHandlerFactory

    我正在使用带有嵌入式 Jetty 的可执行 jar 开发一个 Web 应用程序 我的jar包含一个依赖jar jar in jar 我参考了JarRsrcLoader and RsrcURLStreamHandlerFactory由 Ecl
  • 将过滤器添加到 Eclipse 中的 Project Explorer

    我想向 Project Explorer 添加一个新的过滤器 以向用户隐藏一些在 Eclipse RCP 应用程序中自动创建的项目 到目前为止我已经找到了两个扩展点 org eclipse ui ide resourceFilters 允许
  • Java 正则表达式 - 字母数字,最多一个连字符,句点或下划线,七个字符长

    我是 Java 正则表达式工具的新手 尽管它们潜力巨大 但我很难完成这项任务 我想编写一个正则表达式来验证遵循以下语法的输入字符串 小写字母和数字的任意组合 仅一个下划线 一个破折号或一个句号 无其他特殊字符 最小长度为 5 我想出了以下解
  • java.lang.LinkageError:尝试重复的类定义

    为什么会发生错误以及如何修复它 02 13 02 pool 4 thread 2 WARN Exception in thread pool 4 thread 2 02 13 02 pool 4 thread 2 WARN java lan
  • 正则表达式获取字符串中的第一个数字和其他字符

    我是正则表达式的新手 想知道如何才能只获取字符串中的第一个数字 例如100 2011 10 20 14 28 55 在这种情况下 我希望它返回100 但该数字也可以更短或更长 我在想类似的事情 0 9 但它单独获取每个数字 100 2001
  • Java Microsoft Excel API [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 从 @JsonProperty 值获取枚举常量

    我有一个标有 JsonProperty 的枚举 用于使用 Jackson 进行 JSON 序列化 反序列化 并且希望获取给定字符串 JsonProperty 的枚举值 public enum TimeBucket JsonProperty
  • 异步迭代器

    我有以下代码 while slowIterator hasNext performLengthTask slowIterator next 由于迭代器和任务都很慢 因此将它们放入单独的线程中是有意义的 这是对迭代器包装器的快速而肮脏的尝试
  • Jenkins 的代码覆盖率 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 我想在java中使用XQuery进行Xml处理

    我想用XQuery用于从 java 中的 Xml 获取数据 但我没有得到需要为此添加哪个 Jar 我在谷歌上搜索了很多 但没有得到任何有用的例子 例如我得到以下链接 https docs oracle com database 121 AD
  • JSch中如何设置文件类型和文件传输模式?

    我使用 Apache Common NetFTPClient并设置了我的ftpClient在上传文件之前使用如下所示的方法 ftpClient setFileType FTP BINARY FILE TYPE ftpClient setFi
  • JavaFX - 为什么多次将节点添加到窗格或不同的窗格会导致错误?

    我现在正在学习基本的 JavaFX 我不明白我正在阅读的书中的这一说法 不 诸如文本字段之类的节点只能添加到一个窗格中一次 将节点添加到多次窗格或不同的窗格将导致运行时错误 我可以从书中提供的UML图看出它是一个组合 但我不明白为什么 库类
  • 使用 secp256r1 曲线和 SHA256 算法生成 ECDSA 签名 - BouncyCastle

    我正在尝试使用带有 secp256r1 曲线 P256 的 ECDSA 和用于消息哈希的 SHA256 算法生成签名 我也在使用 Bouncy Castle 库 下面的代码 public class MyTest param args pu
  • Java中的回调接口是什么?

    SetObserver 接口的代码片段取自有效的Java 避免过度同步第67条 public interface SetObserver
  • 防止Java实例化的正确方法[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 每次我们调用浏览器时,在 selenium 中使用 driver.manage().window().maximize() 是否好?

    We use driver manage window maximize 最大化浏览器 我在网上看到一些使用的例子driver manage window maximize 尽管不需要最大化浏览器 例如 gmail 登录 我还看到使用 se

随机推荐

  • 我可以有一个模板函数指针的 std::vector 吗?

    我有一个模板函数 我想将它的指针存储在std vector 该函数如下所示 template
  • 在easeljs中添加一个简单的图像

    这是我的 html 代码
  • css 字体大小和行高与基线不匹配

    我正在尝试做一些应该非常简单的事情 但我在失败和论坛之间度过了一天 我想调整我的字体以匹配我的基线 在 indesign 中只需点击一下即可 但在 css 中这看起来是地球上最困难的事情 让我们举一个有理值的简单例子 在这张图片上 我每 2
  • SQL 查询检查名称是否以元音开头和结尾

    我想查询名单CITY表中的名称STATION id city longitude latitude 它们的第一个和最后一个字符都是元音 结果不能包含重复项 为此 我写了一个查询 例如WHERE NAME LIKE a 它有 25 个条件 每
  • Webpack启动,导入错误

    我正在开始使用 Webpack 但已经遇到了以下问题 我创建了一个 app index js 文件 如文档中指定的 我还创建了一个 index html 文件 从文档中复制了 HTML 和 CSS 我在 CLI 中运行了正确的命令 包括生成
  • Artifactory 缺少 Android 依赖项

    相关找不到runtime jar android arch lifecycle runtime 1 0 0 https stackoverflow com questions 50563338 could not find runtime
  • 如何仅选择 BLOB 列的一部分

    在 SQLite 数据库中 如何从 BLOB 字段中仅选择 1kb 我想象它是这样的 SELECT PART field name startIndex bytes AS data FROM table 这可能吗 Use substr ht
  • JTextArea 中 setText() 的机制?

    我尝试在我的中显示一些文字JTextArea在运行时 但是当我使用循环时setText按顺序显示文本 它只显示最后一个循环的文本 这是我的代码 private void jButton1ActionPerformed java awt ev
  • 如何仅选择巨大二进制文件(文件)的一部分?

    我的问题是这样的 我有可能将巨大的文件存储在 SQL Server 2008 上的二进制 图像 字段中 gt 1GB 如果我使用常规 select 语句返回整个二进制文件 则查询需要一分钟多的时间才能将结果返回到我的 NET 程序 并且我的
  • Android 11 (R) 文件路径访问

    根据文档 Android R 中授予文件路径访问权限 从 Android 11 开始 具有 READ EXTERNAL STORAGE 权限的应用可以使用直接文件路径和本机库读取设备的媒体文件 这项新功能使您的应用程序能够更顺畅地与第三方媒
  • 如何制作全宽 SwiftUI 列表?

    我想要我的List为全宽 填充是自动添加的 出于我的目的 我不希望这样 这只是示例代码 这是我的代码 struct ViewModel Identifiable let title String let id UUID struct Con
  • jquery在for循环中延迟

    所以我一直在研究 jquery deferred 但在循环中检索数据时遇到问题 延迟部分似乎只处理最终迭代中的数据 如果数组中只有一项 它也会失败 所以我不确定发生了什么 我有各种城市名称 我试图从谷歌地图反向地理编码中获取每个城市的中心坐
  • ImageView的src和background有什么区别

    我对使用感到困惑src or background for an ImageView 我知道前者的意思是这个的内容ImageView后者指的是背景ImageView 但如何决定使用哪一个呢 我看不出有什么区别 所有视图都可以拍摄背景图像 T
  • 如何展平Nuget包内容文件?

    Nuget 包问题 buildAction copyToOutput flatten 被忽略 包项目 ThisProject vbproj Net 标准库 2 0 nuspec 文件
  • 提取单词周围的单词并将结果插入数据框列中

    我有一个数据框 df 有 3 列 如下所示 company year text Apple 2016 The Company sells its products worldwide through its 我想在以下位置搜索 产品 df
  • 如何通过 REST API 创建 Pod

    如何使用 REST API 创建 Pod 我查看了 Kubernetes API 文档 https kubernetes io docs reference generated kubernetes api v1 10 strong wri
  • 我可以使用 vs2010 开发 .net 4.5 应用程序吗

    我已经安装了 net 4 5 框架http www microsoft com en in download details aspx id 30653 http www microsoft com en in download detai
  • 如何使用 Perl 的 XML::Twig 将子元素添加到 XML?

    我有以下 XML 文件
  • 用C#创建QRCode并保存为图像

    我从 Web 应用程序上的 URL 接收数据 该数据是使用 API 响应动态生成的 我必须把它放在一个QRCode并将这个QRCode发送回前端供我的客户下载 我们使用 C 作为后端 使用 React js 作为前端 我尝试过使用ZXIng
  • 确定印度拉米纸牌是否为获胜牌 - Java

    我正在寻找一种有效的解决方案来确定一手牌是否是印度拉米纸牌中的获胜手牌 印度拉米纸牌在混合方面与金罗米纸牌类似 人们可以融合相同花色的序列 顺子 或融合一组相同的值 序列和集合都应至少包含 3 张牌 与金罗米牌不同 印度拉米牌一手牌由 13