/irmingard-backbone

Solitaire-like card game built with Backbone Marionette. (Currently porting this to Om here: https://github.com/paulwittmann/omingard)

Primary LanguageRuby

IRMINGARD

For the reimplementation in ClojureScript and Om see: https://github.com/paulkoegel/omingard

PLAY: http://irmingard.herokuapp.com

Irmingard is a patience card game. The goal of the game is to clear away all cards from the board to discard piles.

TL;DR Rules

  • the aim is to sort all cards to their discard piles (you have 8 of those instead of Solitaire's 4)
  • drag and drop cards onto other matching cards (draggable cards are marked green on hover, drop targets are marked yellow on hover while dragging another card)
  • double click on a card to discard it to a pile
  • press 'hit me' to get new cards

screenshot of the game board

How to play

Irmingard is played with two sets (104 cards in total) of four suits (♠, ♣, ♦, ♥) with card values from Ace, 2, 3, ... Queen, King - without Jokers. The goal of the game is to clear away all cards to discard piles, where cards are ordered by suit and ascending value (Aces first). The game starts with a board filled with cards in columns of 1, 2, 3, 4, 5, 4, 3, 2, and 1 cards. The only cards on the board whose face you can see are the ones at the bottom of a column, all cards above them are flipped and blocked. You can rearrange cards by putting cards of a lower value below cards of a different colour. Example: 7 of hearts can go below an 8 of spades or an 8 of clubs. At the beginning of the game, all cards that aren't on the board are in a stack (which is not shown in this implementation of the game), and all eight piles are empty. Once you have a moveable Ace it can be discarded on one of the eight piles (2 sets of 4 suits, so we have 8 Aces in the game, each with a duplicate). When no more moves are left, new open cards can be put at the bottom of each pile by pressing the 'Hit me' button in the top right. This continues until you've cleared the entire board or have run out of moves.

  • when a column on the game board is empty only Kings can be dropped on them
  • the first card to discard on a pile must be an Ace
  • top cards from piles can be dragged back onto the board (comes in very handy in the late game, believe me)

Making of

The slides of my presentation "Solitaire mit Backbone" (German) from November 2012's CologneJS can be found here: http://paulkoegel.github.com/colognejs-talk-2012-11

Technologies

Only using Rails as a build tool (compiles CoffeeScript, HAML Coffee etc.). I'd use Grunt or Gulp for this today. All game logic - even saving/loading of games - resides in client-side JavaScript.

Planned features

  • add some awesome end game animation or image (how about reusing this?)
  • write Jasmine specs
  • improve UI
  • save game state
  • collaboration mode with server-side validation of moves and real time move propagation handled by web sockets (using FAYE, most likely)

Why "Irmingard"?

It's named after a person.

Objects

Stack

The stack of shuffled and cards in your hand, you can only see their back.

Pile

Discard piles where all the cards land in the following order: ace, 2, 3, ..., queen, king There's 8 of them, two per suit.

Column

There are 9 columns on the board. at the start of the game they're filled with 1, 2, 3, 4, 5, 4, 3, 2, and 1 cards (left to right). Only the last card of each column is open and movable.

Card

104 in total:

  • 2 sets of cards
    • in 4 suits (hearts, diamonds, spades, clubs)
      • with values from 1 (ace), 2, 3, ... 10, 11 (jack), 12 (queen), 13 (king)

Dev notes

Jasmine Javascript Specs

  • in your browser: rails s open localhost:3000/jasmine

  • headless: guard-jasmine spec

Problems

Callback Flow

  • Can't set a card's draggability directly in its render method because on rendering the card's Column hasn't been updated yet by Backbone Relational Cards Collection: 'add' callback, card's column is still: 4 CardsShow: rendering ♥queen with column still set to: 4 Column Model.handleAdd callback: only now has the card's column been updated to the new one: 0

    The card first gets added to the Card Collection Backbone Relational uses behind the scene. This add automatically triggers Marionette's render on the card - unfortunately, Backbone Relational hasn't updated the card's column value then. One way out of this could be to rerender the Card in the Column's handleAdd callback (con: double rendering). A better idea might be to leave everything as it is and only update the card's draggability in Column.handleAdd. Then simply bind the CardView to changes on draggability and set the HTML-attribute accordingly.

Acknowledgements

Big thanks to Jeremy Ashkenas for creating CoffeeScript & Backbone.js, to Derick Bailey for building Backbone Marionette, and to Bumi for introducing me to Backbone in the first place - back in 2010 ;)

Graphics

Thank you for providing the card images to the following artists: