Building a Multi Player Card Game for Free

Source Code

https://github.com/jericopulvera/pusoy-dos

Demo

https://pusoy-dos.vercel.app/

Introduction

Recently I've been introduced to a a Filipino Card game called "Pusoy Dos" and we've played it with a friendly betting involved hence the reason I was inspired to build an online version of it for us to use sometimes.

Prerequisites

  • Experience in Git
  • Basic knowledge of React
  • Basic knowledge of NodeJS

Tech Stack

We'll be using Next.js, Vercel and PlanetscaleDB to simplify the Development, Global Accessibility and Scalability upon deployment.

Data Models

  • users
  • games

Step 1: Install Next.js, MongoDB and Other Packages

Create project directory

mkdir pusoy-dos

Initialize project

npm init -y

Install Next.js

npm install next react react-dom

Install Prisma

npm install @prisma/client

Step 2: Sketch the Pages

Initial Wireframe

Step 4: List the HTTP endpoints we'll need

We'll be mainly using HTTP in our game. Ideally we'll use Websocket on other stuff to make it super fast but unfortunately it will be a hassle to maintain and if we want to use it we'll have to use a third party solution or self host a websocket server since it's not natively supported via Vercel.

Step 5: Work on the HTTP Endpoints Logic

Each HTTP endpoints we'll have a simple written algorithm and is not that detailed but this will keep us on track of what we'll need in an endpoint.

Login Endpoint

I plan to make this endpoint a login that registers you at the same time to make thing super simple. The inputs would be username and password.

  1. Collect the inputs needed
  2. Sanitize and validate the inputs
  3. Search if username exist
  4. If username does not exist create the user
  5. Check if the user's password matches the given password
  6. Generate a json web token
  7. Return the json web token
  8. Return response in HTTP Status Code 201 or 200

Create Game Endpoint

This endpoint will be used to create a game. There would be no inputs just a simple POST request with the user's JWT.

  1. Check if the request contains a valid user jwt
  2. Create the game
  3. Return game data in the response with HTTP Status Code 201

Get Game Details Endpoint

This endpoint will be used to get the game details. The inputs would be the game id.

  1. Check if the game exists
  2. Get user jwt if there is one
  3. Strip player cards data except the one owned by the logged in user
  4. Return game data in the response with HTTP Status Code 200

Join Game Endpoint

This endpoint will be used to join a game. The inputs would be the game id and the user's jwt.

  1. Check if the game exists
  2. Check if the game is not full
  3. Check if the user jwt is valid
  4. Add the user to the game
  5. Return game data in the response with HTTP Status Code 200

Kick Player Endpoint

This endpoint will be used to kick a player from the game. The inputs would be the game id and the player id.

  1. Gather, sanitize and validate the inputs: playerId, gameId
  2. Check if the inputs are valid
  3. Check if the request contains a valid user jwt
  4. Check if the user jwt is the one who created the game
  5. Remove the player in the game
  6. Return response with HTTP Status Code 200

Start Game Endpoint

This endpoint will be used to start the game. The inputs would be the game id.

  1. Gather, sanitize and validate the inputs: gameId
  2. Check if the request contains a valid user jwt
  3. Check if the user jwt is the one who created the game
  4. Check if the game has started
  5. Check if the game has more than 1 player
  6. Shuffle the card
  7. To add difficulty we'll remove N cards where N is the amount of players
  8. Distribute the cards evenly to each player
  9. Identify the player to move while distributing the card
  10. Update game status
  11. Return response with HTTP Status Code 200

Play Card Endpoint

This endpoint will be used to play a card. The inputs would be the game id, the player id and the card id.

  1. Check if the request contains a valid user jwt
  2. Check if the game is ongoing
  3. Check if the user is in the game
  4. Gather, sanitize and validate the inputs: cards
  5. Check if its the users turn to move
  6. If move count 0 lowest card must be included in the cards to play
  7. If move count 0 and lowest card is included update game.lastMove immediately
  8. Check if played cards is allowed (2 pairs is not allowed and played cards must be in the same rank as the last move, Kicker is not allowed on 3 of a Kind)
  9. If Played Cards is empty update game.playerToMove
  10. If its your turn to move and the last move is still your you can drop any rank of cards
  11. Check if the cards is greater than the last move
  12. Cannot Play Cards already played
  13. Update player cards

Step 6: Work on the Frontend

Visit the source code to see how it works. I'll be adding more details in the far future or never.

Step 7: Deploy to Vercel

Vercel is intuitive and easy to use. Visit the site and register an account. Then connect your GitHub account and select the repository you want to deploy. You can also connect your domain to it.