在数据库中存储一副扑克牌的最佳方式是什么?
我正在研究一个需要在数据库中存储一副牌的应用程序。我不确定什么是在数据库中表示这个最好的方法。在数据库中存储一副扑克牌的最佳方式是什么?
该套牌将被预先分配到4手,每个持有13张牌的应用程序。之后,我需要存储手和额外的数据,如西装配送等...
是最好为每只手创建一个单独的行并将其与甲板关联?或者,将它们保持一排会更好?
另外我不确定是否应该将它们保留为文本或数字。 下面是一个例子:
Sorted by suit and separated by dot
AK.32.6543.AKQ98
或者
(52 = Largest rank or largest suit or 02 = 2 of smallest suit)
405251282717161514
任何想法?
PS:有一个理由来存储卡。我们需要分析手牌分布,高卡点等......
我觉得最自然不过的事情。将创建卡表,这将每张卡片有一张记录,然后是手牌记录,手中每张卡片都有一张记录。如果有整个牌的数据 - 球员的名字?他坐在桌旁?他有多少筹码?无论如何 - 那么你需要一个单独的桌子,而不是手中的牌。我也会创建一个西装的查找表。
(我们可以辩论使用人工键与这里的自然键,但这是另一个主题。)
card (cardid, suitid, rank)
suit (suitid, suitname)
hand (handid, playername, whatever)
handcard (handcardid, handid, cardid)
我第一个冲动是使“等级”一个从1数到13,并翻译1到“Ace”,11到13到“Jack”,“Queen”和“King”。您可以将它们存储为文本,但如果需要这样做,则难以比较排名。即确定13> 10是否容易用于数据库;国王> 10,并非如此。
我绝对不会试图把多张卡的识别放入单个字段中,不管是用句点还是固定长度的ID分开。这样做需要你的程序有代码将这个字段分开来获取你想要的数据,而不是让数据库检索你想要的数据,这是数据库的用途。
我不知道你想用这些卡片手做什么,但你可能想要做的大多数事情都很容易,就像我描述的结构一样,如果你把一个列表卡成一个单一的领域。例如,“谁拥有黑桃王?“很简单:
select playername
from hand
join handcard using (handid)
join card using (cardid)
join suit using (suitid)
where suit.name='Spades' and card.rank=13
或者 ”?有多少牌面没有每个玩家有“
select playername, count(*)
from hand
join handcard using (handid)
join card using (cardid)
where card.rank between 11 and 13
当然, ”没有球员#3有什么卡“,也很容易:
select rank, suitname
from handcard
join card using (cardid)
join suit using (suitid)
where handid=3
做这些查询与打包格式需要棘手的字符串提取的电话。而字符串操作是永远的痛。就像你总是遇到这样的问题,如果我在寻找2名的文本,我怎么排除2的那是 '12'的一部分?等
很棒的答案。谢谢。但我觉得我需要澄清一些观点。首先我不需要选择像你的例子那样的东西。 (虽然现在我可以看到新的潜力)我需要选择的只是整个手牌或只是一个牌手。我这么说是因为它可能会改变数据库的设计。比较等级不应该是一个问题(至少大部分时间)。 – Sinan 2011-04-14 17:12:06
“选择......整只手”是什么意思?你想对数据做什么?如果简短的回答是你想要做的就是显示玩家手中的内容,那么你甚至不需要数据库:只需一个平面文件,每手一行,每一行都包含手的内容显示格式,如“黑桃王牌,3钻石和几张面牌”。但是如果你真的想要以某种方式操纵它,那当然答案会改变。 – Jay 2011-04-18 16:52:19
这取决于你想要做的分析类型。要不是我,我可能会默认为类似(忽略非主约束)
CREATE TABLE card (
card_id NUMBER PRIMARY KEY,
suit VARCHAR2(10) NOT NULL,
value VARCHAR2(1) NOT NULL
);
CREATE TABLE hand (
hand_id NUMBER PRIMARY KEY,
player_id NUMBER NOT NULL
);
CREATE TABLE hand_element (
hand_element_id NUMBER PRIMARY KEY,
hand_id NUMBER NOT NULL,
card_id NUMBER NOT NULL
);
每个HAND
将在HAND_ELEMENT
13行。我不会理会存储有关的诉讼分布的信息,我只是计算手的分布,即
SELECT suit, count(*)
FROM hand JOIN hand_element USING (hand_id)
JOIN card USING (card_id)
WHERE hand_id = :some_hand_id
我也正在为3张牌一个类似的项目。我建立了我这样的SQL:
CREATE TABLE cards
(
id int AUTO_INCREMENT,
suite varchar(30) NOT NULL,
rank int NOT NULL,
dealt BOOLEAN DEFAULT false,
PRIMARY KEY (id)
);
然后运行命令来填充数据库以这样的方式
INSERT INTO cards (suite,rank) VALUES ('spades',1);
这种方式可以遍历数据库和变更处理为“真”作为卡正在处理中。还可以轻松比较排名。
定义 “最好的”。您的意思是“存储最少字节数的手的最佳方式”,还是“存储手的最佳方式,使其易于人类阅读”? – Davidann 2011-04-14 16:21:15
最后,手将被转换为应用程序可读的人类,但更重要的是,我需要能够根据其属性进行分类和检索。我不认为字节数量应该是一个问题。 – Sinan 2011-04-14 16:30:29
为什么有必要在数据库中存储所有枚举?为什么不根据需要生成它们? – Davidann 2011-04-14 16:31:32