LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 05-14-2012, 03:38 PM   #1
mcteague
LQ Newbie
 
Registered: Apr 2011
Posts: 9

Rep: Reputation: 1
card game programming framework


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
 
Old 05-14-2012, 03:43 PM   #2
TobiSGD
Moderator
 
Registered: Dec 2009
Location: Germany
Distribution: Whatever fits the task best
Posts: 17,148
Blog Entries: 2

Rep: Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886
The only thing I am aware of would be PySolFC. It is written in Python, which is an easy to learn language.
 
Old 05-14-2012, 06:19 PM   #3
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
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:
Code:
#!/bin/bash

White=$'\033[0;37m'
Black=$'\033[1;30m'
Red=$'\033[0;31m'
Normal=$'\033[0m'

Clear=$'\033[0m\033[H\033[2J'

Face=$White$'\360\237\202\240'$Normal

Jokers[1]=$Black$'\360\237\203\217'$Normal      # Black joker
Jokers[2]=$Red$'\360\237\203\237'$Normal        # Red joker

Spades[1]=$Black$'\360\237\202\241'$Normal      # Ace of Spades
Spades[2]=$Black$'\360\237\202\242'$Normal
Spades[3]=$Black$'\360\237\202\243'$Normal
Spades[4]=$Black$'\360\237\202\244'$Normal
Spades[5]=$Black$'\360\237\202\245'$Normal
Spades[6]=$Black$'\360\237\202\246'$Normal
Spades[7]=$Black$'\360\237\202\247'$Normal
Spades[8]=$Black$'\360\237\202\250'$Normal
Spades[9]=$Black$'\360\237\202\251'$Normal
Spades[10]=$Black$'\360\237\202\252'$Normal
Spades[11]=$Black$'\360\237\202\253'$Normal     # J, Jack
# Spades[11]=$Black$'\360\237\202\254'$Normal   # C, Knight
Spades[12]=$Black$'\360\237\202\255'$Normal
Spades[13]=$Black$'\360\237\202\256'$Normal

Hearts[1]=$Red$'\360\237\202\261'$Normal        # Ace of Hearts
Hearts[2]=$Red$'\360\237\202\262'$Normal
Hearts[3]=$Red$'\360\237\202\263'$Normal
Hearts[4]=$Red$'\360\237\202\264'$Normal
Hearts[5]=$Red$'\360\237\202\265'$Normal
Hearts[6]=$Red$'\360\237\202\266'$Normal
Hearts[7]=$Red$'\360\237\202\267'$Normal
Hearts[8]=$Red$'\360\237\202\270'$Normal
Hearts[9]=$Red$'\360\237\202\271'$Normal
Hearts[10]=$Red$'\360\237\202\272'$Normal
Hearts[11]=$Red$'\360\237\202\273'$Normal       # J, Jack
# Hearts[11]=$Red$'\360\237\202\274'$Normal     # C, Knight
Hearts[12]=$Red$'\360\237\202\275'$Normal
Hearts[13]=$Red$'\360\237\202\276'$Normal

Diamonds[1]=$Red$'\360\237\203\201'$Normal      # Ace of Diamonds
Diamonds[2]=$Red$'\360\237\203\202'$Normal
Diamonds[3]=$Red$'\360\237\203\203'$Normal
Diamonds[4]=$Red$'\360\237\203\204'$Normal
Diamonds[5]=$Red$'\360\237\203\205'$Normal
Diamonds[6]=$Red$'\360\237\203\206'$Normal
Diamonds[7]=$Red$'\360\237\203\207'$Normal
Diamonds[8]=$Red$'\360\237\203\210'$Normal
Diamonds[9]=$Red$'\360\237\203\211'$Normal
Diamonds[10]=$Red$'\360\237\203\212'$Normal
Diamonds[11]=$Red$'\360\237\203\213'$Normal     # J, Jack
# Diamonds[11]=$Red$'\360\237\203\214'$Normal   # C, Knight
Diamonds[12]=$Red$'\360\237\203\215'$Normal
Diamonds[13]=$Red$'\360\237\203\216'$Normal

Clubs[1]=$Black$'\360\237\203\221'$Normal       # Ace of Clubs
Clubs[2]=$Black$'\360\237\203\222'$Normal
Clubs[3]=$Black$'\360\237\203\223'$Normal
Clubs[4]=$Black$'\360\237\203\224'$Normal
Clubs[5]=$Black$'\360\237\203\225'$Normal
Clubs[6]=$Black$'\360\237\203\226'$Normal
Clubs[7]=$Black$'\360\237\203\227'$Normal
Clubs[8]=$Black$'\360\237\203\230'$Normal
Clubs[9]=$Black$'\360\237\203\231'$Normal
Clubs[10]=$Black$'\360\237\203\232'$Normal
Clubs[11]=$Black$'\360\237\203\233'$Normal      # J, Jack
#Clubs[11]=$Black$'\360\237\203\234'$Normal     # C, Knight
Clubs[12]=$Black$'\360\237\203\235'$Normal
Clubs[13]=$Black$'\360\237\203\236'$Normal

printf '%s' "$Clear"
printf 'Face down: %s\n' "$Face"
printf 'Jokers:    %s\n' "${Jokers[*]}"
printf 'Hearts:    %s\n' "${Hearts[*]}"
printf 'Diamonds:  %s\n' "${Diamonds[*]}"
printf 'Clubs:     %s\n' "${Clubs[*]}"
printf 'Spades:    %s\n' "${Spades[*]}"
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?
 
Old 05-14-2012, 08:39 PM   #4
mcteague
LQ Newbie
 
Registered: Apr 2011
Posts: 9

Original Poster
Rep: Reputation: 1
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.
 
Old 05-15-2012, 12:15 AM   #5
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
To be honest, I think a library for something like this would be overkill.

First, you can use the playing cards from the Open Clip Art Library. They are licensed under CC0-1.0, which means they are completely free to use.

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.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
LXer: Gameplay 1.2, open source game development framework, released LXer Syndicated Linux News 0 04-25-2012 01:01 AM
[SOLVED] Linux GUI Programming with no extra framework Doc CPU Programming 39 12-28-2011 07:46 PM
Game Programming manolakis Programming 5 08-30-2007 06:38 AM
C++ Game Programming qcoder Programming 6 09-17-2006 02:12 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 07:58 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration