假设我正在开发纸牌游戏(由于无法透露原始项目的详细信息,因此我在进行类比)。
考虑以下结构:
Dealer1
91 // Card 9 of spades (Second digit represents card type, check the legend below)
Rejectors:
John
A2 // Ace of hearts
Rejectors:
Rowan
J3
K2
Rejectors:
David
33
Dealer2
43
52
Rejectors:
David
13
Dealer3
44
83
93
// 1: spades ♠, 2: hearts ♥, 3 diamonds 4: clubs ♣.
发牌人发一张牌(它被添加到他的列表中),一次只有一个玩家有一次机会拉牌,看它并保留或拒绝它(将其放回卡组中)。如果该卡被拒绝,我们会标记玩家的名字(所以下次他不能拉它)。
如果保留该卡,则将其从上面的列表中删除。
如果任何牌手正在查看该牌,则不会将其计入其他牌手列表(我们可以暂时将其从列表中删除)。
我希望能够随时向玩家显示还剩多少张卡可供他拉出。
例如,如果约翰问还给发牌人1和发牌人2多少张卡,答案将是7张卡(A2,J3,K2、33、43、52、13),请记住,卡91先前已被约翰拒绝。
现在,如果汉娜(Hanna)询问同一家经销商有多少张卡,答案将是8(她之前没有拒绝过任何卡,因此她的名字不在任何经销商列表中)
规则:
在Redis中保存此内容的最佳方法是什么?集?散列?
第一次尝试,我只是保存了一个序列化对象,如下所示(不一定与上面的列表相同):
// Key 1
"Dealer1": [
{
"Card": "A1",
"Rejecters": [
"John"
]
},
{
"Card": "K2",
"Rejecters": [
"David"
]
}
]
// Key 2
"Dealer2": [
{
"Card": "31",
"Rejecters": [
"Adam"
]
},
{
"Card": "Q2",
"Rejecters": [
"David"
]
}
]
关键是发牌人ID,值是对象的序列化数组,每个对象代表一张卡及其“拒绝者”(也许不是最好的名字)列表。我知道这不是很有效,因为每次我需要查询玩家可用卡的数量时,我都要循环查询所要求的发牌人的 key ,获取其整个列表,计算(客户端)游戏中有多少个对象。列出玩家名称为而没有的位置。
PS:我正在使用ServiceStack.Redis C#客户端(但是我可以处理原始的Redis命令/数据类型,并且可以将它们转换为C#代码)。
最佳答案
为每个发卡机构创建一个redis集。
例如,
"dealer_1_set" : ["91,"A1"]
"dealer_2_set" : ["A2,"A3"]
"dealer_3_set" : ["B9,"B10","36"]
对于John拒绝的每张卡,都要为他设置一个Redis。
"cards_rejected_by_john_set" : ["91","A3","36"]
现在计算约翰的发牌人1和发牌人2可获得的卡
使用redis命令
SINTER dealer_1_set dealer_2_set ... (add more dealer sets if you want)
您得到新的设置,例如temp_set [“91”,“A1”,“A2,” A3“]
然后使用redis命令
SDIFF temp_set cards_rejected_by_john_set
然后得到[“A1”,“A2”],这就是结果。
上面的操作应该很快。但是要使上述操作具有原子性,您需要编写一个Lua脚本。
关于data-structures - 如何在Redis中表示此结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62908466/