我在Python中有以下代码,它按照他们的级别组织(分组)扑克牌。我是以老派的方式做到这一点,但我确信有更好的方法,因为Python实际上是着名的那种东西。 我怎样才能以更短更优雅的方式做同样的事情?
以下是方法代码:
autocomplete="nope"
这种方法背后的想法是按照他们的RANK(不适合)对牌进行分组。我还决定有4个自变量,因为它比列表更容易使用。 原因很简单:稍后弄清楚手。 按照按行分组的卡片我可以轻松检查图形,例如:
def gatherRanks(self, hand):
self.value1 = []
self.value2 = []
self.value3 = []
self.value4 = []
card1 = hand.cards[0]
self.value1.append(card1)
card2 = hand.cards[1]
if card2.rank == card1.rank:
self.value1.append(card2)
else:
self.value2.append(card2)
card3 = hand.cards[2]
if card3.rank == card1.rank:
self.value1.append(card3)
elif card3.rank == card2.rank:
self.value2.append(card3)
else:
self.value3.append(card3)
card4 = hand.cards[3]
if card4.rank == card1.rank:
self.value1.append(card4)
elif card4.rank == card2.rank:
self.value2.append(card4)
elif card4.rank == card3.rank:
self.value3.append(card4)
else:
self.value4.append(card4)
card5 = hand.cards[4]
if card5.rank == card1.rank:
self.value1.append(card5)
elif card5.rank == card2.rank:
self.value2.append(card5)
elif card5.rank == card3.rank:
self.value3.append(card5)
elif card5.rank == card4.rank:
self.value4.append(card5)
等等,每次检查都需要1-3行代码(Straight除外,需要循环)。
答案 0 :(得分:0)
gatherRanks
代替def gather_ranks(self, hand):
self.value = []
for i in range(4):
self.value.append([])
# The first card always goes to the first hand
self.value[0].append(hand.cards[0])
# Go through the next cards. Foreach card, check
# if the first hands card(s) has / have the same value.
# If so, add it there. Otherwiese go to the next hand.
# If none had the same, add it to the next players hand.
for card_index in [1, 2, 3, 4]:
for i in range(card_index):
if hand.cards[card_index].rank == hand.cards[i].rank:
self.value[i].append(hand.cards[card_index])
break
else:
# loop fell through without break
# Card was not added to any player
if card_index < 5:
self.value[card_index].append(hand.cards[card_index])
所以这是经过调整的代码:
//PK
@Entity
@Table(name="s_c_bur_dtl")
public class SurveyConductBurglaryDetails {
@Id
@GeneratedValue(strategy = GenerationType.AUTO,generator="surveycondbgdtl_seq")
@javax.persistence.SequenceGenerator(name="surveycondbgdtl_seq",sequenceName="surveycondbgdtl_seq",allocationSize=1,initialValue=1)
@Column(name = "nsurveycondbgdtlcd", unique=true, nullable = false, columnDefinition = "bigint")
private BigInteger surveyCondBgDtlCd;
@OneToMany(cascade = CascadeType.ALL,mappedBy="surveyConductBurglaryDetails")
private List<SurveyConductBurglaryProperty> surveyConductBurglaryProperties;
}
//FK
@Entity
@Table(name="s_c_bur_property")
public class SurveyConductBurglaryProperty {
@Id
@GeneratedValue(strategy = GenerationType.AUTO,generator="surveycondbgproperty_seq")
@javax.persistence.SequenceGenerator(name="surveycondbgproperty_seq",sequenceName="surveycondbgproperty_seq",allocationSize=1,initialValue=1)
@Column(name = "nsurveycondbgpropertycd", unique=true, nullable = false, columnDefinition = "bigint")
private BigInteger surveyCondBgPropertyCd;
@ManyToOne
@JoinColumn(name = "nsurveycondbgdtlcd")
private SurveyConductBurglaryDetails surveyConductBurglaryDetails;
}
@Service
class SaveService{
@Autowired DbService dbService;
public void conductSurvey(SurveyConductBurglaryDetails surveyConductBurglaryDetails) throws IllegalAccessException, InvocationTargetException{
dbService.saveOrUpdate(surveyConductBurglaryDetails); // call for save
}
}
@Service
class DbService{
public void saveOrUpdate(Object insertObj){
Session session = surveyTransactionManager.getSessionFactory().getCurrentSession();
Transaction transaction = session.getTransaction();
if(!transaction.isActive()){
session.beginTransaction();
}
try{
session.saveOrUpdate(insertObj);
transaction.commit();
}catch(Exception e){
transaction.rollback();
// TODO Auto-generated catch block
if(logger.isDebugEnabled()){
logger.debug("SurveyDBService.saveOrUpdate Catch block");
}
e.printStackTrace();
}finally{
}
}
}
当然,我不能做出很好的评论,因为我不知道这背后的含义是什么。你应该用这个游戏中有意义的东西来替换它。
答案 1 :(得分:0)
只有摆脱了self.value1
,self.value2
等列表才能实现真正的改进。每当你看到自己创建这样的变量时,你应该使用一个列表。
以下代码执行您想要的操作(我省略了self
,因为它与代码无关):
def gather(hand):
values= []
for card in hand.cards:
#for each card, check if a list containing cards of the same rank already exists
for card_list in values:
if card_list[0].rank==card.rank:
#found one, add the card to this list
card_list.append(card)
break
else:#if no list with the same rank exists, create one
values.append([card])
#and if you insist on having your 4 lists:
values1= values[0] if len(values)>0 else []
values2= values[1] if len(values)>1 else []
values3= values[2] if len(values)>2 else []
values4= values[3] if len(values)>3 else []
答案 2 :(得分:0)
从使用变量self.value1到self.value4来判断,排名的数量是预先确定的。
如果事实确实如此,字典可以派上用场。
def gather_ranks(self, hand):
# initialize the dictionary with card ranks
# r1...r4 represents card ranks
self.ranked_cards = {"r1": [], "r2": [], "r3": [], "r4": []}
for card in hand.cards:
self.ranked_cards[card.rank].append(card)
答案 3 :(得分:0)
(编辑示例)
我会使用defaultdict:
from collections import defaultdict
from pprint import pprint
import itertools
import random
class Card(object):
def __init__(self, rank_color):
self.rank, self.color = rank_color
def __repr__(self):
return '{} of {}'.format(self.rank, self.color)
class Hand(object):
def __init__(self):
self.cards = []
self.gathered_ranks = defaultdict(list)
def add_card(self, card):
self.cards.append(card)
self.gathered_ranks[card.rank].append(card)
def get_gathered_ranks(self):
return dict(self.gathered_ranks)
if __name__ == '__main__':
hand = Hand()
colors = ['spade', 'club', 'heart', 'diamond']
ranks = range(1, 15)
deck = [e for e in itertools.product(ranks, colors)]
random.shuffle(deck)
# We suppose players have 5 random cards
for i in range(5):
card = deck.pop()
hand.add_card(Card(card))
pprint(hand.get_gathered_ranks())