Skip to content

Commit

Permalink
Adds API service and basic model
Browse files Browse the repository at this point in the history
  • Loading branch information
Wekios committed Apr 4, 2021
1 parent 48d64a3 commit f3367a4
Show file tree
Hide file tree
Showing 5 changed files with 268 additions and 11 deletions.
64 changes: 64 additions & 0 deletions src/config/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { CardDiscard, CardType } from "model";

/**
* Names mapped to the key, user is always key: 0
*/
export const playersNames: {
[key: number]: string;
} = {
0: "You",
1: "Mr 2",
2: "Mister 3",
3: "Mister 4",
};

/**
* Number of cards per game
*/
export const cardsCount: number = 10;

export const cardValuesLookup = (card: CardType["value"]) => {
switch (card) {
case "KING":
return 14;
case "QUEEN":
return 13;
case "JACK":
return 12;
case "ACE":
return 1;
default:
return parseInt(card);
}
};

export const MIN_PLAYER_COUNT = 2;
export const MAX_PLAYER_COUNT = 4;
/**
* helper fn to check if number of players is valid
*/
export const isInPlayerCountRange = (num: number) => num >= MIN_PLAYER_COUNT && num <= MAX_PLAYER_COUNT;

/**
* Simple algorithm: who had the highest||same card last takes the lead
* @param discard played cards during the round
* @returns round winner
*/
export const determineRoundWinner = (discard: CardDiscard[]) => {
const formattedDiscard = discard.map((dis) => ({
...dis,
cardValue: cardValuesLookup(dis.card.value),
}));

return formattedDiscard.reduce(
(acc, cur) => {
if (acc.cardValue <= cur.cardValue) {
acc.id = cur.player.id;
acc.cardValue = cur.cardValue;
}
acc.scoreSum += cur.cardValue;
return acc;
},
{ id: 0, scoreSum: 0, cardValue: 0 }
);
};
26 changes: 26 additions & 0 deletions src/model/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export type CardType = {
code: string;
image: string;
suit: string;
value: string;
};

export type PlayerType = {
id: number;
name: string;
hand: CardType[];
turnToPlay: boolean;
score: number;
};

export type NewDeckResponse = {
deck_id: string;
success: boolean;
remaining: number;
cards: CardType[];
};

export type CardDiscard = {
player: PlayerType;
card: CardType;
};
17 changes: 17 additions & 0 deletions src/services/cards-client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { HttpClient } from "./http-client-base";
import { NewDeckResponse } from "model";
import { cardsCount } from "config";

const BASE_URL = "https://deckofcardsapi.com/api/deck";
const NEW_DECK_URL = "/new/draw/?count=";

export class CardsAPI extends HttpClient {
public constructor() {
super(BASE_URL);
}

fetchNewDeck = (playerCount: number) =>
this.instance.get<NewDeckResponse>(`${NEW_DECK_URL}${playerCount * cardsCount}`);
}

export const cardsAPI = new CardsAPI();
25 changes: 25 additions & 0 deletions src/services/http-client-base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import axios, { AxiosInstance, AxiosResponse } from "axios";

declare module "axios" {
interface AxiosResponse<T = any> extends Promise<T> {}
}

export abstract class HttpClient {
protected readonly instance: AxiosInstance;

public constructor(baseURL: string) {
this.instance = axios.create({
baseURL,
});

this._initializeResponseInterceptor();
}

private _initializeResponseInterceptor = () => {
this.instance.interceptors.response.use(this._handleResponse, this._handleError);
};

private _handleResponse = ({ data }: AxiosResponse) => data;

protected _handleError = (error: any) => Promise.reject(error);
}
Loading

0 comments on commit f3367a4

Please sign in to comment.