Простая карточная игра Python
Я совершенно новичок в Python и понятия не имею, что делать с этой программой.
Я пытаюсь создать мини-карточную игру, которая делает следующее
- Есть шесть игроков.
- В начале каждой руки каждому игроку сдаются по четыре карты.
- Для каждого игрока все пары в его руке опускаются. Игрок получает одно очко за пару, состоящую из двух карт с рангом менее 10 (с тузом более 10). Игрок получает два очка за плательщика, состоящего из двух карт с рангом 10 или выше. Если рука как две пары, оба опускаются. Игрок получает соответствующие очки (1 или 2) для вида пары.
- Рука заканчивается после того, как пары были сброшены. (Игроки фактически не вводят данные и не принимают решения. Я говорил вам, что это была скучная игра.) Все карты возвращаются в колоду, она перетасовывается, и запускается новая рука.
- После каждого раунда игроки перечисляются в порядке убывания общего количества очков. Если два игрока имеют одинаковое количество очков, они печатаются с игроком с наименьшим номером.
- После шести раундов игра заканчивается. Первый игрок в списке очков (как определено выше) выигрывает игру
Вывод должен выглядеть так:
Hand 1 deal:
Player 1's hand: 5D 5H KD AS
Player 2's hand: 7D 8D 9C JS
Player 3's hand: 3D 3H 6S 7C
Player 4's hand: 4C 6D 8S TH
Player 5's hand: 4H 5C 7S QC
Player 6's hand: 5S 6H 9H KH
Dropping pairs:
Player 1 dropped 1 pair.
Player 2 dropped no pairs.
Player 3 dropped 1 pair.
Player 4 dropped no pairs.
Player 5 dropped no pairs.
Player 6 dropped no pairs.
Score:
Player 1: 1
Player 3: 1
Player 2: 0
Player 4: 0
Player 5: 0
Player 6: 0
Модули, которые я имею для этой игры, включают.
CARDS.py
import string
import random
suits = ['S', 'C', 'D', 'H']
longsuits = ['spades', 'clubs', 'diamonds', 'hearts']
ranks = ['2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A']
longranks = ['two', 'three', 'four', 'five', 'six', 'seven', 'eight',
'nine', 'ten', 'jack', 'queen', 'king', 'ace']
ranklist = string.join(ranks, "")
ranklookup = {}
for i in range(len(ranks)):
ranklookup[ranks[i]] = i
suitlookup = {}
for i in range(len(suits)):
suitlookup[suits[i]] = i
class Card:
"""
Class to hold information about a single playing card. The card's rank
and suit are stored.
The constructor takes two arguments, the rank and suit of the card. The
rank and suit must be values from the ranks and suits list.
>>> c1 = Card('8', 'C')
>>> c2 = Card('K', 'H')
>>> print c1
8C
>>> print c2
KH
"""
def __init__(self, rank, suit):
self.__rank = ranklookup[rank]
self.__suit = suitlookup[suit]
def __cmp__(self, other):
"""
Compare two card objects.
>>> c1 = Card('8', 'C')
>>> c2 = Card('K', 'H')
>>> c1<c2
True
>>> c1>c2
False
>>> c1==c2
False
"""
if self.__rank == other.__rank:
return cmp(self.__suit, other.__suit)
else:
return cmp(self.__rank, other.__rank)
def __str__(self):
"""
Return a two-character string representing the card.
>>> c1 = Card('8', 'C')
>>> str(c1)
'8C'
"""
return self.shortname()
def __repr__(self):
"""
Return a the Python code required to construt the card.
>>> c1 = Card('8', 'C')
>>> print repr(c1) .split(".",1)[1]
Card('8', 'C')
"""
return "%s.Card('%s', '%s')" % (self.__module__, ranks[self.__rank], suits[self.__suit])
def suit(self):
"""
Return a character representing the card's suit. This will be one of the
characters from suits.
>>> c1 = Card('8', 'C')
>>> c1.suit()
'C'
"""
return suits[self.__suit]
def rank(self):
"""
Return a character with the card's rank. This will be one of the
characters from ranks.
>>> c1 = Card('8', 'C')
>>> c1.rank()
'8'
"""
return ranks[self.__rank]
def shortname(self):
"""
Output a short two-character description of the card.
>>> c1 = Card('8', 'C')
>>> c1.shortname()
'8C'
"""
return ranks[self.__rank] + suits[self.__suit]
def longname(self):
"""
Return a long English description of the card.
>>> c1 = Card('8', 'C')
>>> c1.longname()
'eight of clubs'
"""
return longranks[self.__rank] + " of " + longsuits[self.__suit]
testhand = [ Card('9', 'H'), Card('6', 'C'), Card('7', 'S'), Card('6', 'D'), Card('A', 'H') ]
def deck():
"""
Return an *unshuffled* deck of cards (list of card objects).
>>> d = deck()
>>> print hand_string(d)
2S 3S 4S 5S 6S 7S 8S 9S TS JS QS KS AS 2C 3C 4C 5C 6C 7C 8C 9C TC JC QC KC AC 2D 3D 4D 5D 6D 7D 8D 9D TD JD QD KD AD 2H 3H 4H 5H 6H 7H 8H 9H TH JH QH KH AH
>>> print len(d)
52
"""
d = []
for suit in range(len(suits)):
for rank in range(len(ranks)):
c = Card(ranks[rank], suits[suit])
d.append(c)
return d
def small_deck():
"""
Return a small *unshuffled* deck of cards (list of card objects). This is
smaller than a regular deck and can be used for testing.
>>> d = small_deck()
>>> print hand_string(d)
9S TS JS QS KS AS 9C TC JC QC KC AC 9D TD JD QD KD AD 9H TH JH QH KH AH
>>> print len(d)
24
"""
d = []
for suit in range(len(suits)):
for rank in [7,8,9,10,11,12]:
c = Card(ranks[rank], suits[suit])
d.append(c)
return d
def start_pair(hand):
"""
Return index of first card in first pair of the hand.
The index is for the order the hand has after sorting.
If there are no pairs, return -1.
Side effect: The hand is sorted.
"""
hand.sort()
start = -1
for i in range(len(hand)-1, 0, -1):
if hand[i].rank() == hand[i-1].rank():
start = i -1
return start
def drop_pair(hand):
"""
Remove a pair from the hand (list of card objects) if possible. Return
the new hand and the number of pairs dropped (0 or 1). A "pair" is two
cards with the same rank.
If there is more than one pair, only the first is removed.
The hand MUST be sorted by rank before this function is called. This
can be done with:
hand.sort()
>>> testhand.sort()
>>> print hand_string(testhand)
6C 6D 7S 9H AH
>>> newhand, pts = drop_pair(testhand)
>>> print hand_string(newhand)
7S 9H AH
>>> print pts
1
"""
newhand = hand[:]
for i in range(len(newhand)-1):
if newhand[i].rank() == newhand[i+1].rank():
del(newhand[i+1])
del(newhand[i])
return newhand, 1
return newhand, 0
def hand_string(hand):
"""
Create a string that represents the cards in the player's hand.
>>> hand_string(testhand)
'6C 6D 7S 9H AH'
>>> hand_string([])
''
"""
return " ".join( [c.shortname() for c in hand] )
def _test():
import doctest
doctest.testmod()
if __name__ == "__main__":
_test()
конец модуля.
а также
pointsort.py
'''
Module to sort players by points and player numbers. See definition for
function sortPlayers() for details of sort order.
'''
def playerToSort(p):
''' Represent player number such that lower-numbered players sort before higher-numbered '''
return -p
def playerFromSort(p):
''' Extract original player number from playerToSort() representation '''
return -p
def sortPlayers(playerNum, points):
''' Sort players by total points, then by player number within total points.
Player numbers are sorted such that low-numbered players are highest.
Returns list of tuples (playerNumber, points), sorted in *increasing* order
by the two criteria.
'''
keys = []
for n in playerNum:
keys.append(playerToSort(n))
order = []
for i in range(len(points)):
order.append((points[i], keys[i]))
order.sort()
result = []
for i in range(len(order)):
result.append((playerFromSort(order[i][1]), order[i][0]))
return result
if __name__ == "__main__":
points = [3, 4, 1, 2, 0, 3]
number = [2, 1, 3, 4, 0, 5]
order = sortPlayers(number, points)
# Note that the following prints results in the WRONG order for A4
for i in range(len(order)):
print "Player " + str(order[i][0]) + " had " + str(order[i][1]) + " points."
i was really hoping if someone could help me with the loops that this program needs, especially the point loop system.
this what i have so far,
import cards
import random
new = cards.small_deck()
print cards.hand_string(new)
print len(new)
player1 = []
player2 = []
player3 = []
player4 = []
player5 = []
player6 = []
#shuffle the cards
random.shuffle(new)
num = input('How many cards to deal to each player? ')
while num > 0:
player1.append(new.pop(0))
player2.append(new.pop(0))
player3.append(new.pop(0))
player4.append(new.pop(0))
player5.append(new.pop(0))
player6.append(new.pop(0))
num = num - 1
#prints out 8 cards for each person
print 'the cards remaining in the deck are: '
print len(new)
#sorts player1 cards and removes the pairs
player1.sort()
print "sorted hand for player 1:"
print cards.hand_string(player1)
newplayer1 = []
player1points = 0
newplayer1, player1points = cards.drop_pair(player1)
print cards.hand_string(newplayer1)
#sorts player2 cards
player2.sort()
print "sorted hand for player 2:"
print cards.hand_string(player2)
newplayer2 = []
player2points = 0
newplayer2, player1points = cards.drop_pair(player2)
print cards.hand_string(newplayer2)
#sorts player3 cards
player3.sort()
print "sorted hand for player 3:"
print cards.hand_string(player3)
newplayer3 = []
player3points = 0
newplayer3, player1points = cards.drop_pair(player3)
print cards.hand_string(newplayer3)
#sorts player4 cards
player4.sort()
print "sorted hand for player 4:"
print cards.hand_string(player4)
newplayer4 = []
player4points = 0
newplayer4, player1points = cards.drop_pair(player4)
print cards.hand_string(newplayer4)
#sorts player5 cards
player5.sort()
print "sorted hand for player 5:"
print cards.hand_string(player5)
newplayer5 = []
player5points = 0
newplayer5, player1points = cards.drop_pair(player5)
print cards.hand_string(newplayer5)
#sorts player6 cards
player6.sort()
print "sorted hand for player 6:"
print cards.hand_string(player6)
newplayer6 = []
player6points = 0
newplayer6, player1points = cards.drop_pair(player6)
print cards.hand_string(newplayer6)
У меня большие проблемы с петлями, и я буду благодарен за любую помощь, которую я могу получить, заранее благодарю
1 ответ
Вы, кажется, не используете pointsort.py
Вообще-то, это нормально, так как я не нуждался в этом для ожидаемого результата.
# main.py
import cards
import random
deck = cards.small_deck()
class Player(object):
def __init__(self, number):
self.number = number
self.points = 0
self.hand = []
def __str__(self):
return "Player %d" % self.number
players = [Player(num + 1) for num in xrange(6)] # create six numbered players
rounds = 6
hand_size = 4
for round_num in xrange(rounds):
#shuffle the cards
random.shuffle(deck)
print "Hand %d deal:" % (round_num + 1)
# deal cards
for _ in xrange(hand_size):
for player in players:
# draw from the back instead of the front: possibly slightly more efficient
player.hand.append(deck.pop())
# sort player cards
for player in players:
player.hand.sort()
print "%s's hand: %s" % (player, cards.hand_string(player.hand))
print
print "Dropping pairs:"
for player in players:
#removes the pairs
new_hand, dropped_cards, pairs = cards.drop_pairs(player.hand)
deck.extend(player.hand) # realistically we can dump the hand now anyway.
player.hand = []
player.points += pairs
how_many = pairs
plural = "s"
if pairs == 0:
how_many = "no"
elif pairs == 1:
plural = ""
print "%s dropped %s pair%s" % (player, how_many, plural)
print
print "Score:"
for player in players:
print "%s: %d" % (player, player.points)
print
Я также изменил drop_pair на drop_pairs и заставил его найти все пары вместо одной. Если он находит тройку, он стоит 2 очка, а четверка - 3.
# in cards.py
def drop_pairs(hand):
new_hand = hand[:]
dropped_cards = []
pairs = 0
for card1, card2 in zip(hand, hand[1:]): # look at every two-in-a-row cards
if card1.rank() == card2.rank():
try:
new_hand.remove(card1)
except ValueError:
pass
else:
dropped_cards.append(card1)
try:
new_hand.remove(card2)
except ValueError:
pass
else:
dropped_cards.append(card2)
pairs += 1
return new_hand, dropped_cards, pairs
Я не просмотрел весь ваш код, и без более конкретных указаний, чем "помощь с циклами", я не могу помочь слишком многим, но кое-что заметил:
В python вы можете выполнять итерацию непосредственно по списку вместо того, чтобы переходить от 0 к len - 1 и проверять индексы. Например:
# this will work, but it's not recommended for suit in range(len(suits)): for rank in range(len(ranks)): c = Card(ranks[rank], suits[suit]) d.append(c) # this is much cleaner for suit in suits: for rank in ranks: d.append(Card(rank, suit))
Тем не менее, иногда вам НЕОБХОДИМО выполнять итерации по диапазону последовательных чисел, или вы просто хотите, чтобы какой-то код выполнялся определенное количество раз, и в этом случае вы можете использовать range (или xrange, что в python 2 более эффективно для больших диапазонов)
# don't do this while num > 0: do_something() num = num - 1 # Do this instead! for i in xrange(num): do_something()
Кроме того, если вам не нужна переменная 'i' для текущего номера, вы можете использовать имя '_', которое часто переназначается и является хорошим местом для ненужных данных.
Вы также можете вкладывать списки. Это очень полезно, если вы не уверены, сколько списков у вас будет. То есть, если у вас шесть игроков:
# no no no player1 = [] player2 = [] player3 = [] player4 = [] player5 = [] player6 = [] # better... players = [[], [], [], [], [], []] # yes! players = [] for _ in xrange(6): players.append([]) # There's also a shortcut called List Comprehensions, which allows us # to be even more concise with our list definitions. players = [[] for _ in xrange(6)]
Преимущество последних двух примеров состоит в том, что вы можете легко изменить количество игроков в игре, изменив число 6 или даже вместо него использовать переменную. Они также сокращают повторение кода: ваша логика для каждого игрока, имеющего дело со своими картами, копируется 6 раз с изменением только одного числа между ними. Это не очень расширяемо: если вы хотите добавить или удалить игроков, вам придется добавить или удалить столько повторяющихся блоков из вашего кода. Вместо:
# no! bad!
player1 = []
player2 = []
player3 = []
player4 = []
player5 = []
player6 = []
player1.do_stuff()
player2.do_stuff()
player3.do_stuff()
player4.do_stuff()
player5.do_stuff()
player6.do_stuff()
# much easier!
for player in players:
player.do_stuff()