Here is another code update. I didn't work on this yesterday because I was short on time.
Current Build
"""
To do:
- Create the used stack pile.
- Allow players to make a move by playing a card onto the used stack pile.
- Create an Ai which plays available cards, and draws if unavailable.
- Create rules for unique cards, like lose a turn, etc.
Created by: CecilSunkure
"""
import sys
import random
ACES_HIGH = True
GAME_RUNNING = True
class card:
suits = ["Clubs",
"Diamonds",
"Hearts",
"Spades" ]
ranks = ["Ace",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10",
"Jack",
"Queen",
"King" ]
def __init__(self, suit=0, rank=0):
self.suit = suit
self.rank = rank
def __str__(self):
return (self.ranks[self.rank] + " of " + self.suits[self.suit])
class deck:
def __init__(self):
self.cards = []
for suit in range(4):
for rank in range(12):
self.cards.append(card(suit, rank))
def __str__(self):
s = ''
for i in range(len(self.cards)):
s = s + str(self.cards[i]) + '\n'
return s
def shuffle(self):
import random
cards_length = len(self.cards)
for i in range(cards_length):
j = random.randrange(i, cards_length)
self.cards[i], self.cards[j] = self.cards[j], self.cards[i]
def remove(self, card):
if card in self.cards:
self.cards.remove(card)
return True
else:
return False
def draw(self):
return self.cards.pop()
def is_empty(self):
return (len(self.cards) == 0)
def deal(self, hands, num_cards=999):
for i in range(num_cards):
if self.is_empty(): break
card = self.pop()
hand = hands[i % len(hands)]
hand.add(card)
def pop(self):
return self.cards.pop()
class hand(deck):
def __init__(self, player=''):
self.cards = []
self.player = player
def add(self, card):
self.cards.append(card)
def __str__(self):
s = self.player + "'s Hand"
t = 0
if self.is_empty():
s = s + " is empty\n"
else:
s = s + " contains\n"
for i in range(len(self.cards)):
t += 1
s = s + str(t) + '. ' + str(self.cards[i]) + '\n'
return s
class MauMau:
def __init__(self, stack=0, topCard=0):
self.deck = deck()
self.deck.shuffle()
self.players = []
self.stack = stack
self.topCard = topCard
def getName(self):
print('Welcome to Mau Mau!')
player = raw_input()
print('What is your name?')
player = raw_input()
print('')
return player
def startCard(self):
self.topCard = self.deck.pop()
def cmp_topCard(self, other):
if self.topCard.suit == other.suit:
if self.topCard.rank == other.rank:
return True
def isValidMove(move, hand, game, handlen):
"""Used to determine if a move by checking to see if the move is an integer, followed by and testing to see
if the proposed move is within the length of the hand passed to this function. Finally, this function
makes sure that the proposed card to be played is valid within the rules of the game (same rank)."""
x = []
for i in range(1, (handlen+2)):
x.append(i)
try:
int(move)
except:
print('That is not a valid move (not int).\n')
return False
if int(move) not in x:
print('That is not a valid move (not 1-' + str(handlen+1) + ').\n')
return False
if move != str(handlen+1):
if game.topCard.rank == hand.cards[(int(move)-1)].rank:
return True
else:
return False
elif move == str(handlen+1):
return True
def main():
"""This function is the main loop used for running the Class MauMau. The turns between Ai and human are
represented by integers, and those integers are used in if statements to determine which player is currently
taking their turn."""
#turn = random.randrange(2) + 1 <-- A comment for now, so for testing the human always goes.
turn = 0
game = MauMau()
name = game.getName()
hand1 = hand(name)
hand2 = hand("CPU")
game.deck.deal([hand1], 5)
game.deck.deal([hand2], 5)
game.startCard()
if turn == 1:
print('The computer will go first, as decided at random.')
else:
print('You will move first, as decided at random.')
while GAME_RUNNING:
print ('///' + '\n' + '/// ' + str(game.topCard) + '\n' + '///' + '\n')
print (hand1)
if turn == 1:
print ('The computer will now take its turn, hit enter to proceed.')
Move = raw_input()
else:
print ('Choose a card to play (1-' + str(len(hand1.cards)) + ') or draw a card (' + str((len(hand1.cards)+1)) + ').')
Move = raw_input()
if isValidMove(Move, hand1, game, len(hand1.cards)):
print('Valid move check passed.\n')
if Move == str(len(hand1.cards)+1):
hand1.add(game.deck.draw())
else:
print('Valid move check failed.\n')
if __name__ == "__main__":
main()
Output Sample
Welcome to Mau Mau!
What is your name?
Randy
You will move first, as decided at random.
///
/// 9 of Hearts
///
Randy's Hand contains
1. 5 of Diamonds
2. Jack of Diamonds
3. 2 of Clubs
4. Queen of Clubs
5. 6 of Clubs
Choose a card to play (1-5) or draw a card (6).
1
Valid move check failed.
///
/// 9 of Hearts
///
Randy's Hand contains
1. 5 of Diamonds
2. Jack of Diamonds
3. 2 of Clubs
4. Queen of Clubs
5. 6 of Clubs
Choose a card to play (1-5) or draw a card (6).
LOLOL
That is not a valid move (not int).
Valid move check failed.
///
/// 9 of Hearts
///
Randy's Hand contains
1. 5 of Diamonds
2. Jack of Diamonds
3. 2 of Clubs
4. Queen of Clubs
5. 6 of Clubs
Choose a card to play (1-5) or draw a card (6).
6
Valid move check passed.
///
/// 9 of Hearts
///
Randy's Hand contains
1. 5 of Diamonds
2. Jack of Diamonds
3. 2 of Clubs
4. Queen of Clubs
5. 6 of Clubs
6. 7 of Diamonds
Choose a card to play (1-6) or draw a card (7).
As you can see from the output code, I added in a function that checks to see if a move is valid. I input an invalid move rule wise, as in the card in my hand didn't have the same rank as the face up card. The error I received was "Valid move check failed.". After this, I entered in a non-integer, which resulted in a error message telling me my move was not an integer. Finally, I chose to draw a card from the deck. This added another card into my hand.
Since you can draw cards, the only downside to this game is that a person's hand could in theory become really large, making it a bit annoying to scroll up and down.
I expanded the main function, and modified the MauMau class to allow for checking to see if a move is valid.
I also deleted the __cmp__ method of my card class, because it was screwing with my == comparison, and I was a bit unsure of how to use the 'rich' methods. Things were getting over-complicated with this method. I might bring it back if it turns out to be easier to use with <, >, <=, >=, != later on.
Now I need to implement an actual stack of played cards (the face up ones next to the deck). I already have a test file that creates a stack and pops (pop means removing and returning the last value of a list) values that were recently laid into the stack. Here is my test file for the stack, which will be added into the card game simulation sometime soon:
StackTest.py
#A test module for creating a stack.
run = True
stack = []
while run:
print('Stack, Pop, end, or continue? (1, 2, 3, enter)')
yesno = raw_input()
if yesno == '1':
print('Enter a value to stack')
a = raw_input()
stack.append(a)
if yesno == '2':
try:
stack.pop()
b = stack.pop()
print(b)
except:
print('Stack is empty.\n')
if yesno == '3':
run = False
The stack code is fairly simple and I don't think I really need to explain it. If you want me to I can however.
As always, any comments questions or suggestions are appreciated.
Here is a .exe of my current build:
http://download503.mediafire.com/m5ydqyl9zzng/nyfzyamykzi/Cards.7z
Post has been edited 2 time(s), last time on Apr 16 2010, 6:47 pm by CecilSunkure. Reason: Added .exe link.
None.