Skip to content

Commit

Permalink
feature: Create GameState model
Browse files Browse the repository at this point in the history
  • Loading branch information
bartoszputek committed Sep 24, 2024
1 parent aa308f8 commit 211ec59
Show file tree
Hide file tree
Showing 10 changed files with 151 additions and 34 deletions.
6 changes: 2 additions & 4 deletions svelte/.prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
"singleQuote": true,
"trailingComma": "none",
"printWidth": 100,
"plugins": [
"prettier-plugin-svelte"
],
"plugins": ["prettier-plugin-svelte"],
"overrides": [
{
"files": "*.svelte",
Expand All @@ -14,4 +12,4 @@
}
}
]
}
}
14 changes: 6 additions & 8 deletions svelte/src/lib/components/Card.svelte
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
<script lang="ts">
const CARD_REVERSE = '2B';
export let value: string = CARD_REVERSE;
export let value: string | null;
let cardValue: string;
$: cardValue = value ?? CARD_REVERSE;
export let width: number = 70;
const height: number = width * 1.4;
let isSelected: boolean = false;
</script>

<button
aria-label={value}
style="width:{width}px; height:{height}px;"
class:isSelected
on:click={() => (isSelected = !isSelected)}
>
<img alt="" src={`/images/cards/${value.toUpperCase()}.svg`} />
<button aria-label={value} style="width:{width}px; height:{height}px;" class:isSelected on:click>
<img alt="" src={`/images/cards/${cardValue.toUpperCase()}.svg`} />
</button>

<style>
Expand Down
19 changes: 17 additions & 2 deletions svelte/src/lib/components/CardIcon.svelte
Original file line number Diff line number Diff line change
@@ -1,17 +1,32 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte';
import { cardIconStore } from '$lib/stores/cardIconStore';
const dispatch = createEventDispatcher<{
click: { value: string };
}>();
export let value: string;
export let width: number = 60;
const height: number = width * 2.5;
let isSelected: boolean = false;
let isSelected: boolean;
$: isSelected = $cardIconStore[value] ?? false;
</script>

<button
aria-label={value}
style="width:{width}px; height:{height}px;"
class:isSelected
on:click={() => (isSelected = !isSelected)}
on:click={() => {
if (!isSelected) {
dispatch('click', { value });
}

$cardIconStore[value] = true;
}}
>
<img alt="" src={`/images/cards/${value.toUpperCase()}.svg`} />
</button>
Expand Down
28 changes: 21 additions & 7 deletions svelte/src/lib/components/Player.svelte
Original file line number Diff line number Diff line change
@@ -1,18 +1,32 @@
<script lang="ts">
import Card from './Card.svelte';
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher<{
click: { cardIndex: number };
}>();
export let playerName: string = 'Player 1';
import type { IPlayer } from '../types';
import Card from './Card.svelte';
export let firstCard: string | undefined;
export let secondCard: string | undefined;
export let player: IPlayer;
</script>

<section>
<div>
<Card value={firstCard} />
<Card value={secondCard} />
<Card
value={player.cards[0]}
on:click={() => {
dispatch('click', { cardIndex: 0 });
}}
/>
<Card
value={player.cards[1]}
on:click={() => {
dispatch('click', { cardIndex: 1 });
}}
/>
</div>
<h4>{playerName}</h4>
<h4>{player.name}</h4>
</section>

<style>
Expand Down
34 changes: 34 additions & 0 deletions svelte/src/lib/models/GameState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { IPlayer } from '../types';

const CURSOR_STARTING_POSITION: number = 0;

export default class GameState {
private _cursorPosition: number = CURSOR_STARTING_POSITION;

private get _playerPosition() {
return Math.floor(this._cursorPosition / 2);
}

private get _playerCardPosition() {
return this._cursorPosition % 2;
}

public players: IPlayer[] = [
{ name: 'Player 1', cards: [] },
{ name: 'Player 2', cards: [] },
{ name: 'Player 3', cards: [] }
];

public setCard(card: string): void {
this.players[this._playerPosition].cards[this._playerCardPosition] = card;
this._cursorPosition++;
}

public reset(): void {
this._cursorPosition = CURSOR_STARTING_POSITION;

this.players.forEach((player) => {
player.cards = [];
});
}
}
14 changes: 14 additions & 0 deletions svelte/src/lib/stores/cardIconStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { writable } from 'svelte/store';

function createCardIconStore() {
const { subscribe, set, update } = writable<Record<string, boolean>>({});

return {
subscribe,
set,
update,
reset: () => set({})
};
}

export const cardIconStore = createCardIconStore();
4 changes: 4 additions & 0 deletions svelte/src/lib/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface IPlayer {
name: string;
cards: (string | null)[];
}
50 changes: 45 additions & 5 deletions svelte/src/routes/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<script lang="ts">
import CardIcon from '$lib/components/CardIcon.svelte';
import Card from '../lib/components/Card.svelte';
import Player from '../lib/components/Player.svelte';
import GameState from '../lib/models/GameState';
import { cardIconStore } from '../lib/stores/cardIconStore';
export const CARD_SUITS: string[] = ['s', 'd', 'h', 'c'];
export const CARD_RANKS: string[] = [
Expand All @@ -19,17 +20,56 @@
'k',
'a'
];
const gameState = new GameState();
$: players = gameState.players;
</script>

{#each CARD_SUITS as suit}
{#each CARD_RANKS as rank}
<CardIcon value={`${rank}${suit}`}></CardIcon>
<CardIcon
value={`${rank}${suit}`}
on:click={(e) => {
const { value } = e.detail;
gameState.setCard(value);

players = gameState.players;
}}
></CardIcon>
{/each}
{/each}

<button
on:click={() => {
console.log(JSON.stringify(players, null, 2));
gameState.reset();

cardIconStore.reset();

players = gameState.players;
}}
>reset
</button>

<br />

<Player />
{#each players as player, index}
<Player
{player}
on:click={(e) => {
console.log(e.detail);

const { cardIndex } = e.detail;
const currentCardValue = players[index].cards[cardIndex];

if (currentCardValue) {
players[index].cards[e.detail.cardIndex] = null;

<h1>Welcome to SvelteKit</h1>
<p>Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation</p>
$cardIconStore[currentCardValue] = false;

return;
}
}}
/>
{/each}
10 changes: 5 additions & 5 deletions svelte/src/styles.css
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
html {
font-size: 62.5%;
font-size: 62.5%;
}

body {
font-family: 'Roboto', sans-serif;
font-size: 1.6rem;
font-family: 'Roboto', sans-serif;
font-size: 1.6rem;
}

h4 {
font-size: 2.1rem;
}
font-size: 2.1rem;
}
6 changes: 3 additions & 3 deletions svelte/test-results/.last-run.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"status": "passed",
"failedTests": []
}
"status": "passed",
"failedTests": []
}

0 comments on commit 211ec59

Please sign in to comment.