Next page | Contents page |

Initial deal, columns

Solitaire games generally lay cards out in columns. We will therefore be needing another type of object: Column. First let's see what the deal() method needs to be able to do. We will use the example of Spider. Add the following to the file spiderA.js. The initial comments say what Spider is expected to do.


Spider.prototype.deal = function ()
{ // 4 rows + 4 cards face down then a row face up
  // 5 deals of 10 remaining
  var colNo = 0;
  for (var i = 0; i < 54; i++)
  { var card = GAME.deck.getCard (i);
    if (i > 43) card.reveal ();
    GAME.COLUMNS [colNo].addCard (card);
    colNo++;
    if (colNo >= GAME.N_COLUMNS) colNo = 0;
  }
  // more to do later - set remainder pile
};

Objects of type Column must at least have an addCard() method and we also need to add method reveal() for a Card. There is also an implication that when cards are first constructed they are face down, not revealed.

Add another script file called columnA.js and containing the following. Notice that we set the top left position of the column for drawing it on the canvas.


function Column (xLeft, yTop)
{ this.XL = Math.floor (xLeft);
  this.YT = Math.floor (yTop);
  this.CARDS = [];
}

Column.prototype.addCard = function (card)
{ var len = this.CARDS.length;
  this.CARDS.push (card);
  card.setColumn (this, len);
};

When we display columns and start moving cards around there will be much more to add to type Column.

Notice something else slipped in here: it seems likely that it will be useful for cards to know which column they belong to and perhaps where they are in the column. So another method for Card is setColumn().

Now add some things to cardA.js:

In the constructor function add


  this.faceUp = false;

and later in the file put


Card.prototype.reveal = function ()
{ this.faceUp = true;
};

Card.prototype.setColumn = function (column, index)
{ this.column = column;
  this.columnIndex = index;
};

The first time setColumn() is invoked it adds 2 new properties to the card. Note that the index parameter is just the position of the card in the column, from 0 at the top. It is not necessarily the index into any array inside Column, which would be an internal detail that a card does not want to know about.

Other programming languages would be stricter about this: you would have to declare the additional properties first as part of the type (in the constructor). This is part of JS's flexibility. As long as you are careful and manage things clearly, as I am trying to show, this flexibility is a benefit. For beginners it can be easy to overdo and cause problems though.

Empty columns will be created at the start of the game so we also need to add something to Spider. Previously we had


function Spider ()
{ GAME.deck = new Deck (2, 0);// 2 packs, no jokers
  GAME.deck.shuffle ();
  GAME.N_COLUMNS = 10;
  const COL_WIDTH = (GAME.cnv.width - 40) / (GAME.N_COLUMNS + 1);
  // - 40 allows some margin, + 1 allows space for the remainder pile
  // TO DO: create columns - in a later page
}

but now we can replace the TO DO comment with


  for (var i = 0, xL = 0.05 * COL_WIDTH;
       i < GAME.N_COLUMNS; i++, xL += COL_WIDTH)
  { var col = new Column (xL, 4);
    col.DY = Math.round (Card.prototype.width / 2.6);
    GAME.COLUMNS.push (col);
  }

Jumping ahead slightly (next page) the DY property introduced here is the vertical offset between cards when drawing them. We have not yet set the card width - next page.

Next page | Contents page |