Skip to content
This repository has been archived by the owner on Nov 5, 2024. It is now read-only.

bitbybit/node-battleship

 
 

Repository files navigation

Battleship game websocket server

Preparations

Install dependencies

npm ci

Set ports in .env file

PORT_HTTP=4000
PORT_WS=3000

Run

Prod

npm run start

Dev

npm run start:dev

Tests

npm run test

Description

Battleship game backend using websocket.

The backend should be able to do the following:

  • Start websocket server
  • Handle websocket connection
  • Handle player requests
  • Handle room requests
  • Handle ships requests
  • Handle game requests
  • Create single play bot

Technical requirements

  • Only ws, cross-env, typescript, tsx, ts-node, ts-node-dev, nodemon, dotenv, eslint and its plugins, webpack and its plugins, prettier, @types/* and testing tools (for example, Jest, Mocha, AVA, Jasmine, Cypress, Storybook, Puppeteer) are allowed
  • All requests and responses must be sent as JSON string
  • After starting the program displays websocket parameters
  • After program work finished the program should end websocket work correctly
  • After each received command program should display the command and result

The backend have 3 types of response:

  1. personal response
  • reg - player registration/login
  1. response for the game room
  • create_game - game id and player id (unique id for user in this game)
  • start_game - information about game and player's ships positions
  • turn - who is shooting now
  • attack - coordinates of shot and status
  • finish - id of the winner
  1. response for all
  • update_room - list of rooms and players in rooms
  • update_winners - send score table to players

Game description

  1. We have inmemory DB with player data (login and password) storage
  2. Player can create game room or connect to the game room after login
  3. Player room data (players, game board, ships positions) storages in the server
  4. Game starts after 2 players are connected to the room and sent ships positions to the server
  5. Server sends move order
  6. Players should shoot in theirs turn
  7. Server send back shot result
  8. If player hits or kills the ship, player should make one more shoot
  9. Player wins if he has killed all enemies ships

List of websocket commands (requests/responses) and their syntax (<- - cmd from frontend, -> - answer):

- data value should be a json string

- id should be always 0

  • Player
    • Login or create player
      <-
      {
          type: "reg",
          data:
              {
                  name: <string>,
                  password: <string>,
              },
          id: 0,
      }
      ->
      {
          type: "reg",
          data:
              {
                  name: <string>,
                  index: <number | string>,
                  error: <bool>,
                  errorText: <string>,
              },
          id: 0,
      }
    • Update winners (for all after every winners table update)
      ->
      {
          type: "update_winners",
          data:
              [
                  {
                      name: <string>,
                      wins: <number>,
                  }
              ],
          id: 0,
      }
  • Room
    • Create new room (create game room and add yourself there)
      <-
      {
          type: "create_room",
          data: "",
          id: 0,
      }
    • Add user to room (add yourself to somebodies room, then remove the room from available rooms list)
      <-
      {
          type: "add_user_to_room",
          data:
              {
                  indexRoom: <number | string>,
              },
          id: 0,
      }
      ->
      {
          type: "create_game", //send for both players in the room, after they are connected to the room
          data:
              {
                  idGame: <number | string>,
                  idPlayer: <number | string>, /* generated by server id for player in the game session, not enemy (unique id for every player) */
              },
          id: 0,
      }
    • Update room state (send rooms list, where only one player inside)
      ->
      {
          type: "update_room",
          data:
              [
                  {
                      roomId: <number | string>,
                      roomUsers:
                          [
                              {
                                  name: <string>,
                                  index: <number | string>,
                              }
                          ],
                  },
              ],
          id: 0,
      }
  • Ships
    • Add ships to the game board
      <-
      {
          type: "add_ships",
          data:
              {
                  gameId: <number | string>,
                  ships:
                      [
                          {
                              position: {
                                  x: <number>,
                                  y: <number>,
                              },
                              direction: <boolean>,
                              length: <number>,
                              type: "small"|"medium"|"large"|"huge",
                          }
                      ],
                  indexPlayer: <number | string>, /* id of the player in the current game session */
              },
          id: 0,
      }
    • Start game (only after server receives both player's ships positions)
      ->
      {
          type: "start_game",
          data:
              {
                  ships: /* player's ships, not enemy's */
                      [
                          {
                              position: {
                                  x: <number>,
                                  y: <number>,
                              },
                              direction: <boolean>,
                              length: <number>,
                              type: "small"|"medium"|"large"|"huge",
                          }
                      ],
                  currentPlayerIndex: <number | string>, /* id of the player in the current game session, who have sent his ships */
              },
          id: 0,
      }
  • Game
    • Attack
      <-
      {
          type: "attack",
          data:
              {
                  gameId: <number | string>,
                  x: <number>,
                  y: <number>,
                  indexPlayer: <number | string>, /* id of the player in the current game session */
              },
          id: 0,
      }
    • Attack feedback (should be sent after every shot, miss and after kill sent miss for all cells around ship too)
      ->
      {
          type: "attack",
          data:
              {
                  position:
                  {
                      x: <number>,
                      y: <number>,
                  },
                  currentPlayer: <number | string>, /* id of the player in the current game session */
                  status: "miss"|"killed"|"shot",
              },
          id: 0,
      }
    • Random attack
      <-
      {
          type: "randomAttack",
          data:
              {
                  gameId: <number | string>,
                  indexPlayer: <number | string>, /* id of the player in the current game session */
              },
          id: 0,
      }
    • Info about player's turn (send after game start and every attack, miss or kill result)
      ->
      {
          type: "turn",
          data:
              {
                  currentPlayer: <number | string>, /* id of the player in the current game session */
              },
          id: 0,
      }
    • Finish game
      ->
      {
          type: "finish",
          data:
              {
                  winPlayer: <number | string>, /* id of the player in the current game session */
              },
          id: 0,
      }

Websocket commands sequence

  Player1               Server                  Player2
    reg         -->
                <--        reg
                <--    update_room
                <--   update_winners
 create_room    -->
                <--    update_room
                                      <--         reg
                           reg        -->
                <--    update_room    -->
                <--   update_winners  -->
                                      <--    add_user_to_room
                <--    update_room    -->
                <--    create_game    -->
   add_ships    -->
                                      <--       add_ships
                <--     start_game    -->
                <--        turn       -->
 attack (miss)  -->
                <--       attack      -->
                <--        turn       -->
                                      <--     randomAttack (shoot)
                <--       attack      -->
                <--        turn       -->
                                      <--     randomAttack (kill) - send state for all cells around killed ship
                <--       attack      -->
                <--        turn       -->
                <--       attack      -->
                <--        turn       -->
                <--       attack      -->
                <--        turn       -->
                <--       attack      -->
                <--        turn       -->
                           ...
                                      <--     randomAttack (miss)
                <--       attack      -->
                <--        turn       -->
 attack (miss)  -->
                <--       attack      -->
                <--        turn       -->
                           ...
                <--      finish       -->
                <--   update_winners  -->

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • TypeScript 94.4%
  • JavaScript 4.0%
  • Other 1.6%