Skip to content

Commit

Permalink
Merge pull request #2 from vmolero/develop
Browse files Browse the repository at this point in the history
Change to immutable objects
  • Loading branch information
vmolero authored Mar 6, 2018
2 parents 260e124 + e20fc99 commit 1ba8740
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 206 deletions.
100 changes: 69 additions & 31 deletions src/Board.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,56 @@
import Player from './Player';
import CardDeck from './CardDeck';
import Deal from './Deal';
import House from './House';
import Hand from './Hand';
import Card from './Card';
import CardDeck from './CardDeck';

export default class Board {
private readonly SCORE_THRESHOLD: number = 21;

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

public constructor();
public constructor(deal?: Deal) {
this.deal = deal || new Deal(CardDeck.createStandard52CardDeck());
private house: House;
private player1: Player;

public static newGame(): Board {
let deal: Deal = new Deal(CardDeck.createStandard52CardDeck());
let playerHand: Hand = new Hand([]);
let player1: Player = new Player(playerHand);
let houseHand: Hand = new Hand([]);
let house: House = new House(houseHand);

return new Board(deal, house, player1);
}

public firstDeal() {
this.deal.pullPlayerCard();
this.deal.pullHouseCard();
public newDeal(): Board {
let deal: Deal = new Deal(CardDeck.createStandard52CardDeck());
let playerHand: Hand = new Hand([deal.pullCard()]);
let player1: Player = new Player(playerHand);
let houseHand: Hand = new Hand([deal.pullCard()]);
let house: House = new House(houseHand);

return new Board(deal, house, player1);
}

public addPlayer(player: Player) {
this.deal.addPlayer(player);
}
public dealPlayer(): Board {
let card: Card = this.deal.pullCard();
let player1: Player = this.player1.hit(card);

public giveCardToPlayer() {
if (!this.deal.isDealOver()) {
this.deal.pullPlayerCard();
if (this.deal.getPlayerScore() > this.deal.SCORE_THRESHOLD) {
this.deal.setDealOver();
}
}
return new Board(this.deal, this.house, player1);
}

public giveCardToHouse() {
if (this.deal.getHouseScore() >= this.deal.getPlayerScore()) {
this.deal.setDealOver();
}
if (!this.deal.isDealOver()) {
this.deal.pullHouseCard();
if (this.deal.getHouseScore() >= this.deal.SCORE_THRESHOLD ||
(this.deal.getHouseScore() >= this.deal.getPlayerScore())) {
this.deal.setDealOver();
}
}
public dealHouse() {
let card: Card = this.deal.pullCard();
let house: Player = this.house.hit(card);

return new Board(this.deal, house, this.player1);
}

public isHouseWinning() {
return (this.deal.getHouseScore() >= this.deal.getPlayerScore() ||
this.deal.getPlayerScore() > 21) && this.deal.getHouseScore() <= 21;
return (this.getHouseScore() >= this.getPlayerScore() ||
this.getPlayerScore() > 21) && this.getHouseScore() <= 21;
}

public getDeal(): Deal {
Expand All @@ -59,4 +64,37 @@ export default class Board {
public getHouseWins(): number {
return this.houseWins;
}

public getHouse(): House {
return this.house;
}

public getPlayerHand(): Hand {
return this.player1.getHand();
}

public getHouseHand(): Hand {
return this.house.getHand();
}

public getPlayerScore(): number {
return this.getPlayerHand().getScore();
}

public getHouseScore(): number {
return this.house.getScore();
}

public isGameOver(): boolean {
return this.getHouseScore() >= this.SCORE_THRESHOLD ||
this.getPlayerScore() > this.SCORE_THRESHOLD ||
(this.getHouseScore() >= this.getPlayerScore() &&
this.house.getHand().getCards().length > 1);
}

private constructor(deal: Deal, house: House, player1: Player) {
this.deal = deal;
this.house = house;
this.player1 = player1;
}
}
73 changes: 3 additions & 70 deletions src/Deal.ts
Original file line number Diff line number Diff line change
@@ -1,86 +1,19 @@
import Hand from './Hand';
import Card from './Card';
import CardDeck from './CardDeck';
import House from './House';
import Player from './Player';

export default class Deal {
public readonly SCORE_THRESHOLD: number = 21;

// private cardCount: number = 0;
private dealOver: boolean = false;
private house: House;
private players: Array<Player>;
private cardDeck: CardDeck;

public constructor(cardDeck?: CardDeck) {
this.cardDeck = cardDeck || CardDeck.createStandard52CardDeck();
this.house = new House();
this.players = new Array<Player>();
this.cardDeck.shuffle();
}

public setHouse(house: House): Deal {
this.house = house;

return this;
}

public getHouse(): House {
return this.house;
}

public addPlayer(player: Player) {
this.players.push(player);
}

public getPlayer(order: number): Player {
if (this.players[order - 1] !== undefined) {
return this.players[order - 1];
}
throw new Error('Player not found');
}

public getPlayerHand(): Hand {
return this.getPlayer(1).getHand();
}

public getHouseHand(): Hand {
return this.house.getHand();
}

public getPlayerScore(): number {
return this.getPlayerHand().getScore();
}

public getHouseScore(): number {
return this.house.getScore();
}

public pullPlayerCard() {
try {
let card: Card = this.cardDeck.popCard();
this.getPlayer(1).pullCard(card);
} catch (doNothingOnEmptyDeck) {
this.dealOver = true;
}
}

public pullHouseCard() {
public pullCard(): Card {
try {
let card: Card = this.cardDeck.popCard();
this.getHouseHand().add(card);

return this.cardDeck.popCard();
} catch (doNothingOnEmptyDeck) {
this.dealOver = true;
throw Error('No cards');
}
}

public setDealOver() {
this.dealOver = true;
}

public isDealOver(): boolean {
return this.dealOver;
}
}
1 change: 0 additions & 1 deletion src/Hand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import Card from './Card';
export default class Hand {
private cards: Array<Card>;

public constructor();
public constructor(cards?: Array<Card>) {
this.cards = cards || new Array<Card>();
}
Expand Down
11 changes: 6 additions & 5 deletions src/Player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import Card from './Card';
export default class Player {
private hand: Hand;

public constructor();
public constructor(hand?: Hand) {
this.hand = hand || new Hand();
public constructor(hand: Hand) {
this.hand = hand;
}

public pullCard(card: Card) {
this.hand.add(card);
public hit(card: Card): Player {
let cards: Array<Card> = this.hand.getCards();
cards.push(card);
return new Player(new Hand(cards));
}

public getScore(): number {
Expand Down
85 changes: 35 additions & 50 deletions src/components/BoardComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,88 +1,58 @@
import * as React from 'react';
import DealComponent from './DealComponent';
import Board from '../Board';
import Player from '../Player';

interface BoardStateInterface {
board: Board;
handNumber: number;
playerScore: number;
houseScore: number;
btnDealerClass: string;
btnPlayerClass: string;
}

export default class BoardComponent extends React.Component<{}, BoardStateInterface> {

constructor(props: {}) {
super(props);
const board: Board = new Board();
board.addPlayer(new Player());
this.state = {
board: board,
board: Board.newGame(),
handNumber: 0,
playerScore: 0,
houseScore: 0
houseScore: 0,
btnDealerClass: '',
btnPlayerClass: 'invisible'
};
}

public handleDealClick() {
let board: Board = new Board();
board.addPlayer(new Player());
board.firstDeal();
this.setState(
{
board: board,
handNumber: this.state.handNumber + 1
board: this.state.board.newDeal(),
handNumber: this.state.handNumber + 1,
btnDealerClass: 'invisible',
btnPlayerClass: ''
}
);
}

public handleHitClick() {
let board: Board = new Board();
board = this.state.board;
board.giveCardToPlayer();
this.setState({ board: board });
let playerScore: number = this.state.playerScore;
let houseScore: number = this.state.houseScore;
if (board.getDeal().isDealOver()) {
if (board.isHouseWinning()) {
houseScore += 1;
} else {
playerScore += 1;
}
}
this.setState(
{
board: board,
houseScore: houseScore,
playerScore: playerScore,
}
);
let newState: BoardStateInterface = this.state;
newState.board = this.state.board.dealPlayer();
this.setNewState(newState);
}

public handleStandClick() {
let board: Board = new Board();
board = this.state.board;
while (!board.getDeal().isDealOver()) {
board.giveCardToHouse();
let newState: BoardStateInterface = this.state;
let board: Board = this.state.board;
while (!board.isGameOver()) {
board = board.dealHouse();
}
let playerScore: number = this.state.playerScore;
let houseScore: number = this.state.houseScore;
if (board.isHouseWinning()) {
houseScore += 1;
} else {
playerScore += 1;
}
this.setState(
{
board: board,
houseScore: houseScore,
playerScore: playerScore,
}
);
newState.board = board;
this.setNewState(newState);
}

public render() {
const board: Board = this.state.board;
return (
<div id="table">
<aside id="subheader">
Expand All @@ -102,12 +72,27 @@ export default class BoardComponent extends React.Component<{}, BoardStateInterf
</div>
</aside>
<DealComponent
deal={board.getDeal()}
board={this.state.board}
btnDealerClass={this.state.btnDealerClass}
btnPlayerClass={this.state.btnPlayerClass}
onDealClick={() => this.handleDealClick()}
onHitClick={() => this.handleHitClick()}
onStandClick={() => this.handleStandClick()}
/>
</div>
);
}

private setNewState(newState: BoardStateInterface) {
if (newState.board.isGameOver()) {
if (newState.board.isHouseWinning()) {
newState.houseScore += 1;
} else {
newState.playerScore += 1;
}
newState.btnDealerClass = '';
newState.btnPlayerClass = 'invisible';
}
this.setState(newState);
}
}
Loading

0 comments on commit 1ba8740

Please sign in to comment.