• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
creyes

PYTHON CARD GAME - objects, methods and design

5 posts in this topic

Bit of background, I've been getting pretty into programming lately and think that I have a decent grasp on most programming concepts but have never actually put my skills to the test and made anything. I've decided that I want to make a text-only card game clone (WoW tcg) to test my skills. The game doesn't have to be completely functional, but I'd like to create a structure that would allow me to one day (if I feel like it) implement a rules system etc.

That means... cards can't just be names they need to be objects with attributes etc.

I'm pretty bad at design, but I figured that the best way to handle gameplay was to create a list for every zone (allyZone = [], deck = [], hand = [], graveyard = [] etc etc) and then interact with the cards via the different lists. If that's wrong... let me know but it's what I could think of.

Now my problem is interaction with the cards as objects in those zones, and figuring out how to design the card object in general.
[source lang="python"]class deck(object):
def __init__(self):
self.cards = []
from random import shuffle
shuffle(self.cards)

def shuffleDeck(self):
from random import shuffle
shuffle(self.cards)

def drawCard(self, hand):
d = self.cards
cardDrawn = d.pop(0)
hand.append(cardDrawn)

def viewLibrary(self):
for x in self.cards:
print x.name

def viewNumberOfCards(self, cardsToView):
for x in self.cards[:cardsToView]:
print x.name

class hand(object):
def __init__(self):
self.cards = []

def viewHand(self):
for x in self.cards:
print x.name

def playCard(self, card):
if card.type == "ally":
h = self.cards
cardToPlay = h.pop(card)
allyZone.append(cardToPlay)

class card(object):
def __init__(self, name, type):
self.name = name
self.type = type
[/source]

This barebones for sure, but you get the idea. Now obviously using a string for type in card.__init__ is a bad idea, but I'm not sure of a better way to do it and I'm not sure how I'm going to store the cardData (xml, just a python file, json i have zero clue).

Anyway my question for now is under hand.playCard(). When I try to use something like hand.playCard(hand.cards[0]) the compiler says that hand.playCard(card) needs to be an integer. I'm not sure how to get around that or what I'm supposed to use instead.

Any help would be awesome!
0

Share this post


Link to post
Share on other sites
The problem is because you're passing card into the .pop method. .pop expects to receive the number of items off the stack you want to take. It seems to me like you're expecting it to put a reference to the card being popped into "card." I think you're trying to take a card from your hand, then place that card into the ally zone:

[source lang="python"]def playCard(self, card):
if card.type == "ally" and card in self.cards:
self.cards.remove(card)
player.putInZone(card.type, card)

# to use this:
hand.playCard(hand.cards[0])[/source]

You might want to think about reorganizing a bit. Your Hand object is directly referencing allyZone, which tightly couples them together. Hand will not work if you decide to rename allyZone later, or want to use it separately from allyZone.

A better solution might be to handle this logic outside, in something like a Game class that knows the rules of how cards are taken from a hand and put into play:

[source lang="python"]def SomeGame:
def __init__(self):
self.graveyard = [];
self.deck = self.initializeDeck()

def playCardFromHand(self, player, card):
if player.hand.hasCard(card) and self.playCard(player, card):
player.hand.removeCard(card)

def playCard(self, player, card):
if not self.canPlayCard(player, card):
return False

if card.type == "ally" and card in self.cards:
player.putInZone(card.type, card)
return True[/source]

This would enable you to write different implementations of the Game object to have different rules, and also could help insulate some classes from changes in other classes.

For whatever reason I can't get the spacing to be consistent between edits. Edited by smr
2

Share this post


Link to post
Share on other sites
Thanks! that was incredibly helpful and exactly what I was looking for!

My follow up question is another design one with a little bit of implementation.

You bring up a good point that there should be some sort of "game state" class that everything interacts with like playing cards etc. I feel like this is also the place where EVERY RULES FUNCTION would go also (when ~ enters play do ~)... does that sound correct? In other words the "game state" object would contain all of the "rules objects (i've read that every rule should be made an object)" and then when a card "enters play" it checks the "game state" object and instantiates whatever rules that card has

thanks again, you've been a big help!
0

Share this post


Link to post
Share on other sites
In my opinion it's a good idea for your Hand and card implementations to know as little as possible (preferably nothing, if you can manage it) about the rules of the game. Hand should know only about how to receive and remove a card, fetch a card, maybe search for a particular type of card, and maybe some way to sort the cards (some players prefer to keep their cards sorted). Even sorting is a little tricky because different games may have different ways to sort cards. This can probably be accomplished by implementing some sort of "sorter" interface. You could create classes "MyGameHandSorter" or a "PokerHandSorter" or "BridgeHandSorter," for example. At that point you could either "MyGameHandSorter().sort(myHand)". You can even go through the trouble of formally declaring your interfaces, "class IHandSorter(object): ...class PokerHandSorter(IHandSorter)" but it's probably not necessary. Remember, python does [url="http://en.wikipedia.org/wiki/Duck_typing#In_Python"]duck typing[/url].

As far as implementing every game rule as an object: It depends. Some rules are better left implemented directly into your Game class. Things like phases of a player turn, what can be done during the different phases, etc. might be better left in Game.

That being said, if you're making a game in the same genre as MtG, each card could have its own set of special rules associated with it. You should spend some time trying to classify these rules down into as many "rule types" as you can. From there, find a way to represent the data that is associated with these rule types. That data will be held in your Card implementation for the game, either directly in the card or attached to the card through some sort of CardProperties member on Card or something. I'd probably just stick them in Card. With MtG there are always exceptions, and these will have to be handled in your Game.playCard implementation. I wouldn't put them on Card, personally. Cards should just be data. This way you don't risk having to rewrite individual card implementations if you decide to create some specialized version of your game.

In fact, you probably won't be implementing a "playCard" method on game. You'll more likely be implementing what we call the [url="http://en.wikipedia.org/wiki/Command_pattern"]command pattern[/url]. The player will build commands indicating what she would like to do, then dispatch those to the implementation of Game. The reason you have to do this is because in games like MtG, the opposing player has an opportunity to interrupt your action. You cannot immediately resolve a healing spell, for example, because the opposing player might cast an interrupt to prevent the spell. Another player might interrupt that spell somehow, or perform some other action (maybe even eliminate the player with an instant damage spell!) that affects the outcome. All these commands will need to be collected from all the players, then resolved by Game in the proper order and the outcome will need to change the state of the game, cards, and players. And finally those outcomes will need to be presented to the players.

I bet you thought you were picking an easy game coding project, didn't you? Edited by smr
2

Share this post


Link to post
Share on other sites
First of all, I'd like to thank you @smr for all the help you gave - I learned a ton just be reading your posts. As for "picking an easy project" - that's sort of true. I definitely thought it would be easier but I'm glad it turned out to be more difficult because it's forced me to read about/I've learned a lot about oop and program design. Because of all that, I have all of the infrastructure done (can draw cards, play cards to each of the different zones etc etc)

I think my final question before I put this mini-project to bed for a while (until I learn a lot more about oop, and gui stuffs) is about data-storage. I know this is a much discussed topic but I haven't really found a solid answer. I'm pretty sure what I want to do is make an XML file similar to

[source lang="xml"]<card>
<name>"Random Name"</name>
<type>Ally</type>
<subtype>Human Warrior</subtype>
<attack>5</attack>
<health>3</attack>
<abilities>When this comes into play, gain 5 life</abilities>
</card>[/source]

But I can't seem to find any tutorials online about how to parse those into objects. I'd assume I make a prototype class before hand but my xml/python knowledge is zero. If someone can point me in the direction of a tutorial or if there's a better way to do this (sqlite maybe? then make all the class instances sql queries?) that'd be much appreciated!
0

Share this post


Link to post
Share on other sites
You're welcome!

As far as using XML, I wouldn't. XML is a bit more difficult to parse than, say, JSON. JSON is JavaScript Object Notation and looks pretty much the same as defining lists and dicts in python:

[code]
[ // <-- opening square brace because we're defining a list
{ // <-- opening with a curly brace because we're defining a dict
"name": "Random Name", //<-- commas here to separate the key/value pairs in the dict. JSON also requires the key to be in DOUBLE quotes, even though this is not necessary in JavaScript. All strings are double quoted.
"type": "Ally",
"subtype": "Human Warrior",
"attack": 5,
"health": 3,
"abilities": When this comes into play, gain 5 life
}, // <-- notice the comma here. Necessary because it's not the last item in the list

{ // Begins next card
"name": "Random Name 2",
"type": "Ally",
"subtype": "Human Warrior",
"attack": 5,
"health": 3,
"abilities": When this comes into play, gain 5 life
}
]
[/code]

And in python, importing JSON is already built in:

[code]
import json

cards = json.load(open("cards.json"))

print cards[0]["name"] #outputs "Random Name 1"
[/code] Edited by smr
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0