Program Organization - PDX-Checkers/checkers GitHub Wiki

This program consists of two parts: the frontend and the backend.

Backend

The backend is primarily implemented in Express, with OvernightJS decorators.

Each endpoint is implemented with a Controller. The controllers are located in src/controllers. Each controller class is decorated with OvernightJS decorators to define its endpoint and methods.

One major exception to the OvernightJS structure is the ActiveGameController class, which doesn't work with it because it uses WebSockets. This has to use the underlying Express backend.

ActiveGameController

The ActiveGameController, at its core, consists of a data structure of ActiveGame objects and a data structure of WebSockets.

The controller itself subscribes users' WebSockets to a "game room" of sorts. Users can create games or join existing games by sending commands through their WebSocket. If a game is created or joined, the WebSocket is then subscribed to that particular ActiveGame object. Upon finishing the game, the socket is resubscribed to the game room.

Much of the ActiveGameController's logic involves parsing WebSocket requests and performing changes to its state / responding to the requests.

UserController

This is a very simple overnight endpoint that handles registering, logging in, and logging out.

There are no requirements for the username or password, other than the username must be unique from other, already created accounts. It's totally secure.

Authentication is handled via a combination of PassportJs and FileStore to persist user sessions in the backend.

ActiveGame

All of these files are located in src/BoardClasses.

Every ActiveGame consists of a Board object, the websockets that have joined, and assorted members that aid in responding to requests or changing the state of itself or its parent ActiveGameController object.

The ActiveGame, similar to the ActiveGameController, listens to its users' WebSockets and changes its state. Users can execute move requests, and the ActiveGame will then attempt to call its Board's move method. Invalid requests result in the Board returning null, and the ActiveGame will respond with an InvalidMoveResponse. Alternatively, a valid move will result in the Board returning a new Board object, and the game will respond with a ValidMoveResponse.

Lastly, the Board object contains the actual logic for moving pieces. It and the utils.ts folder determine whether a move is valid and implement the resulting state change of valid moves.

JSONRequest and JSONResponse

These are Typescript abstract base classes that are intended to standardize the serializing and deserializing of the WebSocket API. They are located in src/JSONClasses.

Frontend

The frontend is a single, very simple web page built using React + Typescript. The general structure of the React components is as follows, with each component on the left of the arrow containing the component on the right:

Index.tsx -> App.tsx -> Login.tsx -> GamesBrowser.tsx -> Game.tsx -> Board.tsx -> Piece.tsx -> Square.tsx

Index.tsx instantiates an app, which in turn instantiates the other elements, which are displayed conditionally based on the current state.

Websockets

To interact with the backend, the frontend uses a websocket connection. As each browser would only contain a single websocket connection at a time, there is a single set of global methods that are used to manage the current websocket, allowing easy reassignment of websocket request handling between different states of the application.