ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I am not a programmer. I can write a shell script and a little perl, but that's about it. I thought I would try a project.
I want to write a graphical tutorial program for some card games. Rather than reinvent the wheel, I thought some framework (or library, or whatever they're called) might already exist and I could start there.
Does anything like that exist? I just mean something that contains the card images and has a basic card game structure that can be built on.
Or is it better to just try to do it from scratch myself. If so what language (not to cryptic) would you recommend? Thanks
You could use your shell scripting skills to get started. Use ANSI escape sequences for colors, and Unicode 6 glyphs for the cards. Run this Bash script to see if your terminal is UTF-8, and your preferred terminal font has the glyphs:
If you already know exactly what kind of card games you want to work on, and don't need to experiment, I too suggest using Python. With PyQt4 you should be up and running in no time. If you want nice graphics, use Inkscape to draw your card faces as individual SVG files. Because they are vector images, they can be scaled. I for one, as an user, hate it when a designer decides the size of the graphics for me; better let me choose the size/scale, or I'll move on to something better!
Put the SVG images in $HOME/.mycardgame/decks/default/, so that you can later let the user choose from different deck graphics. This will also help you put the rest of your game files in the correct place ($HOME/.mycardgame/ in every OS except Windows, but Windows sucks pebbles anyways).
To be honest, I wrote the above shell script snippet because I wondered what on earth is a "basic card game structure". As far as I know, there is no such thing. All card games have cards, but that's about it. Some card games I know have one stack, some more, some none at all (because all cards are dealt to the players at the start of the game). Could you be more specific about what kind of card games you are talking about? Poker?
Thank you both for the reply. By "basic card game structure" I meant something that displays a background of some sort, has card pictures, knows how to shuffle, and perhaps has some predefined method of inputting rules of the game.
I guess I just assumed that most programmers reuse existing code all the time. Programs seem more and more complicated. So I was expecting some sort of modular framework, so people don't have to rewrite the same basic code.
My final plan is to write a gin rummy tutorial and practice program. But I might start with something simpler like "go fish", or "war". It depends on how far I want to go. Putting up some example hands with annotations is one thing. But writing a program that could actually play rummy with any skill might be asking to much at this early stage.
I might try the shell script idea. It will give me a chance to work out some of the ideas. But I was a little curious about how programming in a graphical environment works. And again I just assumed that much of that is already modular. Unlike the early days, that I remember, when everything in X had to be configured by hand.
For this example, you'll need four cards, as h_10.svg, h_j.svg, h_q.svg, and h_k.svg, in the same directory as the following Python file.
You'll need Python and PyQt4 for this:
Code:
#!/usr/bin/python
from PyQt4 import QtCore, QtGui, QtSvg
import os
import sys
# SVG card widgets.
#
class PlayingCard(QtSvg.QSvgWidget):
def __init__(self, svgfilename, parent, suit, value):
# Let QtSVG initialize the object first.
QtSvg.QSvgWidget.__init__(self, svgfilename, parent)
# The card face is hidden by default.
self.setVisible(False)
# Calculate the card aspect ratio.
self.aspectRatio = 1.0 * self.sizeHint().width() / self.sizeHint().height()
# For good measure, save the suit and value of this card.
self.suit = suit
self.value = value
# Main window class.
#
class CardGame(QtGui.QMainWindow):
# Main window constructor.
#
def __init__(self):
QtGui.QMainWindow.__init__(self)
# Set the window title and margins.
self.setWindowTitle('CardGame')
self.setContentsMargins(0, 0, 0, 0)
# Define a new palette, with black button/text color, and a green background.
self.setPalette(QtGui.QPalette(QtGui.QColor(0,0,0,255), QtGui.QColor(0,153,0,255)))
self.setBackgroundRole(QtGui.QPalette.Base)
# Center the window, covering a quarter (half width, half height) of the desktop area.
self.move(QtGui.QDesktopWidget().width() / 4, QtGui.QDesktopWidget().height() / 4)
self.resize(QtGui.QDesktopWidget().width() / 2, QtGui.QDesktopWidget().height() / 2)
# Prepare the playing card images.
H10 = PlayingCard('h_10.svg', self, 1, 10)
HJ = PlayingCard('h_j.svg', self, 1, 11)
HQ = PlayingCard('h_q.svg', self, 1, 12)
HK = PlayingCard('h_k.svg', self, 1, 13)
# Define two VISIBLE hands, two cards each.
self.visibleHands = [ [ H10, HJ ], [ HQ, HK ] ]
# Make sure everything is correctly positioned
self.resizeEvent(None)
# This method will handle our screen updates.
#
def update(self):
# Base unit has 10% space above and below each card,
# for each hand, covering the entire window.
height = self.height() / (1.2 * len(self.visibleHands))
# Display the currently visible hands.
y = self.height() / 10
for hand in self.visibleHands:
x = self.height() / 10
for face in hand:
face.move(x, y)
face.resize(int(height * face.aspectRatio), height)
face.setVisible(True)
x += int(height * face.aspectRatio * 0.27)
y += height
self.show()
# Main window resize event handler.
#
def resizeEvent(self, event):
self.update()
# When run as an application:
#
if __name__ == "__main__":
application = QtGui.QApplication(sys.argv)
window = CardGame()
sys.exit(application.exec_())
This above example shows the four cards, as two different "hands", in the window. The window is of course freely resizeable, and the card size depends only on the window height.
Now, because I haven't done any testing, I have no idea whether the above is the best approach. You need to test to see! The main issue is how the cards are handled. (Should the card objects be manipulated directly as I do above, or should the "hands" be just strings describing the hands? Maybe lists of short strings? Lists of constants? Dicts? Or should the face shown in the window be completely detached from the concept of a card, and be something the display routines should handle? There are lots of options; you're definitely not bound to my approach above.)
Since each card can exist only once on-screen, I think creating a QSvgWidget for each one is a good idea. You'd also need the maximum number of on-screen card backs as QSvgWidgets, too. The logical hand is separate from the visual hand. The visual hand is just the cards that are shown in the window. This approach makes it extremely easy to handle clicking and dragging cards; just add the relevant method or methods to the PlayingCard class.
PyQt4 lets you override existing methods to provide new functionality -- like I've overridden the constructors (__init__) and the resizeEvent(). Also, you don't need to calculate coordinates like I did above if you don't want to; you can use the Qt4 containers to handle the layout for you. (If you want the cards to overlap, you might wish to do it like I do, however; the containers don't expect you to want to have items in them overlap.)
The above is less than a hundred lines of Python. Hopefully, you can see that using a framework for something as simple as this would not reduce the amount of code you'd need to write that much, but it would certainly limit your approach. Do not tie yourself to arbitrary limitations by constraining yourself to existing frameworks! Liberate your creativity!
Last edited by Nominal Animal; 05-15-2012 at 12:21 AM.
Reason: Added a few comments in the code.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.