Tag: programming

Fifty Solitaires – It’s in the Cards

This is the second instalment of my series in which I am developing a JavaScript solitaire game that allows the player to choose between many different rules of Solitaire. As I explained in my previous post, the motivation for this project came from an old bet that I made with a friend of mine. The goal was to develop a program that is able to play 50 types of solitaire games. In the last post, I discussed my plans for the application architecture and set up the React environment. Since then I have been made aware of the Storybook library that allows you to browse and test your react components during development. So I decided to make use of Storybook for this project. If you want to follow along you can find the code at Github.

In this post, I will set up Storybook and create the basic component to display a plain card. To initialise Storybook for my game, I opened up my terminal in the project folder and ran on the following command.

npx sb init 

This installs all the tooling required for Storybook. It also creates some example files in the stories subfolder. I don’t need these examples and I also don’t like the way Storybook creates components in the same folder as the story definitions. So the first thing I did was to delete all the files in the src/stories/ folder.

My aim is to create playing cards and I was entertaining the thought of creating the appearance of the cards purely using Unicode characters and CSS. But then I came across a much more elegant solution. I found this SVG file on Wikimedia that is distributed under CC0 restrictions and therefore can be freely used for any purpose. The file contains images for all standard playing cards in an English deck. Looking at the source code of the SVG I discovered that each card was neatly organised as a single SVG group. This would allow me to manually add symbol tags around the group and make them directly available in react. I saved the file under src/assets/playing_cards.svg.

I like to put all my components in one place so in a new src\components subfolder I created the file Card.tsx. This is what the code for the component looks like.

import React from 'react';
import playingCards from '../assets/playing_cards.svg';
import './Card.css';

export enum CardSuit {
  clubs = 'Clubs',
  spades = 'Spades',
  diamonds = 'Diamonds',
  hearts = 'Hearts'
}

export enum CardValue {
  ace='Ace',
  two='Two',
  three='Three',
  four='Four',
  five='Five',
  six='Six',
  seven='Seven',
  eight='Eight',
  nine='Nine',
  ten='Ten',
  jack='Jack',
  queen='Queen',
  king='King'
}

export interface CardProperties {
  suit: CardSuit;
  value: CardValue;
}

export function Card({suit, value}: CardProperties) {
  return <svg className="card-component">
    <use xlinkHref={`${playingCards}#${value.toLowerCase()}-${suit.toLowerCase()}`}></use>
  </svg>
}

You will notice that I have defined two enums, one for the suit and the other for the value of the card. The enums are strings to allow easy access to the symbols in the SVG file. I am not quite sure yet if I will be using these enums in other parts of the code. In that case, I should move them into a different module. But I will cross that bridge when I get there.

The Card component itself is relatively simple. It takes the suit and the card value as parameters and simply wraps an SVG element that links to a symbol in our playing_cards.svg file. The symbol name is constructed from the parameters passed into the component.

The next step was to create a simple story for the card component that allowed me to view it in Storybook. I created a file src/stories/Card.stories.tsx with the following content.

import React from 'react';
import { Card, CardProperties, CardSuit, CardValue } from '../components/Card';

export default {
  component: Card,
  title: 'Components/Card',
};

interface StoryCardProperties extends CardProperties {
  style: { [key: string]: string}
}

function Template(args: StoryCardProperties) {
  return <div style={args.style}><Card {...args} /></div>
};

export const Large = Template.bind({});

(Large as any).args = {
  suit: CardSuit.spades, 
  value: CardValue.ace,
  style: {
    width: 380,
    height: 560,
    backgroundColor: '#008800',
    padding: 10
  }
};

export const Small = Template.bind({});

(Small as any).args = {
  suit: CardSuit.spades, 
  value: CardValue.ace,
  style: {
    width: 200,
    height: 290,
    backgroundColor: '#008800',
    padding: 10
  }
};

If you look closely, you will notice that the story is showing the card inside a div with a coloured background. I did this because the Card component doesn’t have an intrinsic size other than the SVG size. The container is needed to show that the card will adjust to different size layouts. I personally find it a bit annoying that I have to cast the stories Large and Small to any to be able to assign the args property. Maybe I’m doing something wrong here, or maybe the Storybook developers haven’t given enough attention to the TypeScript bindings. To start Storybook, I ran the command

npm run storybook 

The image below shows how the Card component looks inside Storybook.

The picture shows the way the card will look once I’m done. But I still have to edit playing_cards.svg so that the individual card symbols are defined correctly. Fortunately, I can edit the SVG and watch the effect of my changes directly in the browser through Storybook. I am not going to paste my edits here. This image shows an example of me editing the code.

The most important aspect of the edits is to get the viewBox right for each of the cards. You can also see the IDs of the symbols that need to match the card’s suit and value enums.

Conclusion

By creating a simple Card component, I have taken one big step in creating my solitaire game. Cards will be stacked to make the piles and I will have to create a way that the user can interact with the cards and the piles when playing the game. Right now the card is a passive component without any user interaction. My plan is to place all the code for the interactivity into a Pile component that will act as a container for one or more cards. But this will be the topic for my next post on this solitaire game.

Read More

Fifty Solitaires – A Beginning

Many years ago, when I was a physics student and I was just getting to know the ins and outs of programming, I made a bet with a friend of mine. At the time my mother was into solitaire card games, the ones with real cards you play on the kitchen table. This was before everyone had a computer with a built-in little solitaire game. She was given a book with the rules of 50 different games. The bet I made with my friend was this. During the summer holidays, I would be able to write a solitaire game for the computer. The game would not just allow the player to play one type of card game. No, the game should contain all 50 different rules. The stake of the bet was a crate of beer.

So when the holidays started, I set about writing the game. The programming language at the time was Turbo Pascal and the user interface was character-based with special symbols used to create the graphical appearance of the cards. Turbo Pascal was object-oriented, allowed to react to mouse interactions and, as far as I recall, provided an event-based API for implementing the user interface. At the end of the summer holidays, I had a working solitaire game and I enjoyed my well-earned crate of beer with my friends. I had also gained lots of experience in application development and object-oriented programming. Unfortunately, the game does not exist anymore. It was stored on old 5.25-inch floppy disks which after some years became unreadable.

Game design

Today, I want to recreate the game and make it available for anyone to play. Of course, I won’t be using Turbo Pascal and character-based GUIs. I am going for a JavaScript-based game that will be using React for the user interface. For most of my life, I have been programming in strongly typed languages, so I am going to use TypeScript which adds typing to JavaScript applications and makes everything a bit more predictable.

In recent times, the functional programming style has become popular in the JavaScript community, especially when React is being used. I want to try and follow this style for the front-end. I was thinking about using Redux to manage the state of the application. Redux imposes its own functional programming model which is based on reducers. I think Redux is great for many types of web applications.

On the other hand, I still believe that an object-oriented approach is ideal to capture the logic of something like a solitaire game. Let’s think about the way you would implement the game rules. In solitaire, you play different stacks of cards on the table. Each stack might have different attributes that describe its appearance. For instance, a stack may contain cards facing up or facing down. The stack might be spread to reveal some or all of the cards. Then there are the game rules. A stack might allow dropping a card onto it if it meets certain criteria. Or you may be able to pick up a card. Or maybe you can turn over cards that end up in a separate stack.

These rules are independent of appearance and should not be implemented in the front-end. Rather there should be some model that controls the game logic. To me, it feels natural that the model of a card stack should somehow have the rules available at its fingertips. What better way to do this than by creating classes that represent the rules and then implementing the specific rule variants using inheritance.

Creating the Game Skeleton

So, there you go. The game will be written in TypeScript using React, but no other framework will be used. I will be managing the application state directly in the object model that implements the game rules. And I will make that model flexible enough so that I can implement all game variations, simply by plugging different objects together. In the end, I want to be able to read JSON files that specify the rules and construct a game without having to write any additional code.

For today, I will only create the GitHub repo and initialise the skeleton React application. First, I created an empty repository at https://github.com/holgerschmitz/fifty-solitaires

Then, in the folder on my computer where I keep all my source code, I open the terminal and run

npx create-react-app fifty-solitaires --template typescript --use-npm

The command create-react-app is a useful tool for starting a new React project. Apart from setting up the toolchain for the application, it also sets up a local git repository. I still need to tell git, where the upstream of the project lives. To do this, I navigate into the new project folder and run the following two commands.

git remote add origin git@github.com:holgerschmitz/fifty-solitaires.git
git push -u origin master

I will also be using SCSS for styling. This makes it possible to keep colour definitions and other useful mixins in one place. The command for including SCSS in this project is

npm install node-sass --save

This is it for now. You can look at the repository on GitHub. I invite you to think about the next steps and how you would approach implementing the game.

Read More