Skip to content

Commit

Permalink
Merge pull request #8 from vmolero/feature/4--json-serialization
Browse files Browse the repository at this point in the history
[#4] Json Serialization and localStorage to save full Board
  • Loading branch information
vmolero authored Mar 15, 2018
2 parents 0474822 + 347fd65 commit 9392647
Show file tree
Hide file tree
Showing 16 changed files with 289 additions and 39 deletions.
70 changes: 58 additions & 12 deletions src/Board.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,50 @@
import Player from './Player';
import Deal from './Deal';
import Player, { PlayerJsonInterface } from './Player';
import Deal, { DealJsonInterface } from './Deal';
import House from './House';
import Hand from './Hand';
import Card from './Card';
import CardDeck from './CardDeck';

export interface BoardJsonInterface {
deal: DealJsonInterface;
house: PlayerJsonInterface;
player1: PlayerJsonInterface;
}

export default class Board {
private static playerWins: number = 0;
private static houseWins: number = 0;
private readonly SCORE_THRESHOLD: number = 21;

private deal: Deal;
private playerWins: number = 0;
private houseWins: number = 0;

private house: House;
private player1: Player;

public static get PlayerWins(): number {
return this.playerWins;
}

public static get HouseWins(): number {
return this.houseWins;
}

public static set PlayerWins(wins: number) {
this.playerWins = wins;
}

public static set HouseWins(wins: number) {
this.houseWins = wins;
}

public static sumPlayerWins(): number {
return ++this.playerWins;
}

public static sumHouseWins(): number {
return ++this.houseWins;
}

public static newGame(): Board {
let deal: Deal = new Deal(CardDeck.createStandard52CardDeck());
let playerHand: Hand = new Hand([]);
Expand All @@ -24,6 +55,29 @@ export default class Board {
return new Board(deal, house, player1);
}

public static fromJSON(json: BoardJsonInterface | string): Board {
if (typeof json === 'string') {
return JSON.parse(json, Board.reviver);
}
return new Board(
Deal.fromJSON(json.deal),
House.fromJSON(json.house),
Player.fromJSON(json.player1)
);
}

public static reviver(key: string, value: BoardJsonInterface): Board | BoardJsonInterface {
return key === '' ? Board.fromJSON(value) : value;
}

public toJSON(): BoardJsonInterface {
return {
deal: this.deal.toJSON(),
house: this.house.toJSON(),
player1: this.player1.toJSON()
};
}

public newDeal(): Board {
let deal: Deal = new Deal(CardDeck.createStandard52CardDeck());
let playerHand: Hand = new Hand([deal.pullCard()]);
Expand Down Expand Up @@ -57,14 +111,6 @@ export default class Board {
return this.deal;
}

public getPlayerWins(): number {
return this.playerWins;
}

public getHouseWins(): number {
return this.houseWins;
}

public getHouse(): House {
return this.house;
}
Expand Down
26 changes: 25 additions & 1 deletion src/Card.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,35 @@
import Suit from './Suit';
import Serializable from './interfaces/Serializable';

export default class Card {
export interface CardJsonInterface {
rank: number;
suit: number;
}

export default class Card implements Serializable {
readonly MIN_RANK = 1;
readonly MAX_RANK = 13;
private readonly rank: number;
private readonly suit: Suit;

public static fromJSON(json: CardJsonInterface | string): Card {
if (typeof json === 'string') {
return JSON.parse(json, Card.reviver);
}
return new Card(json.rank, json.suit);
}

public static reviver(key: string, value: CardJsonInterface): Card | CardJsonInterface {
return key === '' ? Card.fromJSON(value) : value;
}

public toJSON(): CardJsonInterface {
return {
rank: this.getRank(),
suit: this.getSuit(),
};
}

constructor(rank: number, suit: Suit) {
if (typeof(Suit[suit]) !== 'string') {
throw new Error('Invalid Suit');
Expand Down
40 changes: 34 additions & 6 deletions src/CardDeck.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import Card from './Card';
import Card, { CardJsonInterface } from './Card';
import Suit from './Suit';
import Serializable from './interfaces/Serializable';

export default class CardDeck {
export interface CardDeckJsonInterface {
deck: Array<CardJsonInterface>;
}

export default class CardDeck implements Serializable {
public readonly RANKS = 13;
private deck: Array<Card>;

public get cards(): Array<Card> {
return this.deck;
}

public static createStandard52CardDeck() {
let deck: Array<Card> = new Array<Card>();
for (let suit: Suit = Suit.Clubs; suit <= Suit.Diamonds; suit++) {
Expand Down Expand Up @@ -36,6 +37,33 @@ export default class CardDeck {
}
return new CardDeck(randomizedDeck);
}

public static fromJSON(json: CardDeckJsonInterface | string): CardDeck {
if (typeof json === 'string') {
return JSON.parse(json, CardDeck.reviver);
}
let deck: Array<Card> = new Array<Card>();
deck = json.deck.map((card: CardJsonInterface): Card => {
return Card.fromJSON(card);
});
return new CardDeck(deck);
}

public static reviver(key: string, value: CardDeckJsonInterface): CardDeck | CardDeckJsonInterface {
return key === '' ? CardDeck.fromJSON(value) : value;
}

public toJSON(): CardDeckJsonInterface {
return {
deck: this.cards.map((card: Card): CardJsonInterface => {
return card.toJSON();
}),
};
}

public get cards(): Array<Card> {
return this.deck;
}

public getLength(): number {
return this.deck.length;
Expand Down
23 changes: 22 additions & 1 deletion src/Deal.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
import Card from './Card';
import CardDeck from './CardDeck';
import CardDeck, { CardDeckJsonInterface } from './CardDeck';

export interface DealJsonInterface {
cardDeck: CardDeckJsonInterface;
}

export default class Deal {
private cardDeck: CardDeck;

public static fromJSON(json: DealJsonInterface | string): Deal {
if (typeof json === 'string') {
return JSON.parse(json, Deal.reviver);
}
return new Deal(CardDeck.fromJSON(json.cardDeck));
}

public static reviver(key: string, value: DealJsonInterface): Deal | DealJsonInterface {
return key === '' ? Deal.fromJSON(value) : value;
}

public toJSON(): DealJsonInterface {
return {
cardDeck: this.cardDeck.toJSON(),
};
}

public constructor(cardDeck?: CardDeck) {
this.cardDeck = cardDeck || CardDeck.createStandard52CardDeck();
}
Expand Down
29 changes: 28 additions & 1 deletion src/Hand.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,35 @@
import Card from './Card';
import Card, { CardJsonInterface } from './Card';

export interface HandJsonInterface {
cards: Array<CardJsonInterface>;
}

export default class Hand {
private cards: Array<Card>;

public static fromJSON(json: HandJsonInterface | string): Hand {
if (typeof json === 'string') {
return JSON.parse(json, Hand.reviver);
}
let cards: Array<Card> = new Array<Card>();
cards = json.cards.map((card: CardJsonInterface): Card => {
return Card.fromJSON(card);
});
return new Hand(cards);
}

public static reviver(key: string, value: HandJsonInterface): Hand | HandJsonInterface {
return key === '' ? Hand.fromJSON(value) : value;
}

public toJSON(): HandJsonInterface {
return {
cards: this.cards.map((card: Card): CardJsonInterface => {
return card.toJSON();
}),
};
}

public constructor(cards?: Array<Card>) {
this.cards = cards || new Array<Card>();
}
Expand Down
23 changes: 22 additions & 1 deletion src/Player.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
import Hand from './Hand';
import Hand, { HandJsonInterface } from './Hand';
import Card from './Card';

export interface PlayerJsonInterface {
hand: HandJsonInterface;
}

export default class Player {
private hand: Hand;

public static fromJSON(json: PlayerJsonInterface | string): Player {
if (typeof json === 'string') {
return JSON.parse(json, Player.reviver);
}
return new this(Hand.fromJSON(json.hand));
}

public static reviver(key: string, value: PlayerJsonInterface): Player | PlayerJsonInterface {
return key === '' ? this.fromJSON(value) : value;
}

public toJSON(): PlayerJsonInterface {
return {
hand: this.hand.toJSON(),
};
}

public constructor(hand: Hand) {
this.hand = hand;
}
Expand Down
17 changes: 11 additions & 6 deletions src/components/BoardComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import DealComponent from './DealComponent';
import Board from '../Board';
import Board, { BoardJsonInterface } from '../Board';

export interface BoardStateInterface {
board: Board;
Expand All @@ -20,9 +20,14 @@ interface BoardPropsInterface {
}

export interface JsonStateInterface {
board: BoardJsonInterface;
handNumber: number;
playerScore: number;
houseScore: number;
btnDealerClass: string;
btnHitClass: string;
btnStandClass: string;
message: string;
}

export class BoardComponent extends React.Component<BoardPropsInterface, BoardStateInterface> {
Expand All @@ -42,14 +47,14 @@ export class BoardComponent extends React.Component<BoardPropsInterface, BoardSt

public fromSavedState(stateObject: JsonStateInterface): BoardStateInterface {
let state: BoardStateInterface = {
board: Board.newGame(),
board: Board.fromJSON(stateObject.board),
handNumber: stateObject.handNumber,
playerScore: stateObject.playerScore,
houseScore: stateObject.houseScore,
btnDealerClass: '',
btnHitClass: 'invisible',
btnStandClass: 'invisible',
message: 'Welcome to vmolero\'s BlackJack Game. Press \'Deal!\' to start playing.'
btnDealerClass: stateObject.btnDealerClass,
btnHitClass: stateObject.btnHitClass,
btnStandClass: stateObject.btnStandClass,
message: stateObject.message
};

return state;
Expand Down
Loading

0 comments on commit 9392647

Please sign in to comment.