1. Model and Engine - meng-zx/aechess-team GitHub Wiki

Story Map

storymap

Engine Architecture

Block Diagram drawio

Front-end AR Rendering

ARGomoku is a Gomoku game based on the Vuforia Engine. The engine receives camera input and track markers around the chess board and on the newly put chess, so as to get the 3D coordinate of the chess board and chess piece.

Rendering AR image on the user's phone is done by Unity.

The AR engine runs on the front-end. As a result, we will build our front-end application with Unity, which is well-compatible with Vuforia. After getting the chess board location from Vuforia Engine and opponent's chess pieces location from the back-end, the opponent's chess pieces can be rendered by Unity on user's phone.

Game Registration

The player could start matchmaking with a button click on the front-end. Before the game starts, the user will need to send their info to the matchmaking server to find an opponent. The info includes user's identifier and preferred game rules. The server will find an opponent or create an AI opponent for the player, then return info of the new game, including game id and other game configs.

Once searching is done on the matchmaking server, the player's front-end will be notified and connect to the game server with game id. A game starts when both sides have established connection with the game server.

During Game

The game proceeds as players take turns to put pieces onto the board. A sample movement in player 1's round goes as follows:

Player 1 puts a chess piece on a physical board, and then put an AR marker on it. The AR Engine will read camera input and get the position of the new chess piece relative to the board. We then calculate its relative location to the board. The 3D coordinate for the relative location will be sent to the game server and stored. The server computes which cross the chess is put on, and decides whether the game is over. The locations for all of the player 1's chess pieces will be sent to player 2's front-end, and they will be rendered on player 2's device. Now player 1's round finishes, and player 2's round will similarly proceeds.

Store Chess Positions in PostgreSQL database

When the player, rival player/AI has played a move, the game server stores that move into the corresponding table associated with the game ID. This in turns allow huge amount of data to be indexed on the game server. So multiple gameplays can be established and run concurrently.

Gomoku API (not implemented): If the user has selected the game_with_ai mode, the game server would connect to a Gomoku API. Then whenever the player plays a move, the server would send that move to that Gomoku API and send back the AI's corresponding move.

Detailed Implementation

Database Schema

1. Match queue

MATCH_QUEUE is used to store the user information for matching purpose. Record won't be deleted when users are matched, but it will be deleted when user finishes the game and send clearrecords request. This is to ensure every active user has a unique USERID.

MATCH_QUEUE:

field type description
USERID int user's unique id
RULEID int user's choice of rule
TIMESTAMP Date/Time Types user's last request time
MATCHED bool whether user has been matched

2.Game info

GAME_INFO stores the status of a game, such as whose turn is it now, whether the game has ended etc.

GAME_INFO:

field type description
USERID int user's unique id
OPPONENTID int opponent's userid
PLAYER_TURN bool whether it's this player's turn
GAME_STATUS string The status of game. Can be "OnGoing", "Win", or "Lose".
PIECE_CNT int Count how many pieces user has put.

3.New piece info

NEW_PIECE_INFO stores the position of the newly put piece.

NEW_PIECE_INFO:

field type description
USERID int user's unique id
X int x component of the newly put piece
Z int z component of the newly put piece

4. All pieces info

ALL_PIECES_INFO stores all the pieces in all the games.

ALL_PIECES_INFO :

field type description
USERID int user's unique id
X int x component of the piece
Z int z component of the piece

Backend Implementation

1.1 Game matching

When the front-end start matching, the backend either matches the player with an opponent with the same game rule or places it in the matching queue. Link to code

Endpoint: POST /gamestart/

Request Parameters:

key type description
ruleid int user's choice of rule

Steps:

    1. Assign a unique userid to the user.
    1. Push the record into MATCH_QUEUE.
    1. [MVP] Delete the record if the timestamp is longer than 10 min.
    1. Search in the MATCH_QUEUE, check if there's any record match this one (Same rule)
    1. If found a record that match, set MATCHED to True for both record, and create records in GAME_INFO for both of them.
    1. If no match, do nothing, leave the record there.
    1. Return userid no matter matched or not.

2.1 Wait for match

The backend either returns the information of the matched player or tells the front end it's still queuing. Link to code

Endpoint: POST /waitformatch/

Request Parameters:

key type description
userid int user's assigned id

Steps:

    1. Check whether user's record is in GAME_INFO. If user's record in GAME_INFO, return:
key type description
isFirst boolean First to go or not
status string "matched"
    1. If user record not in GAME_INFO, it means user is not matched. [MVP] Update the timestamp in MATCH_QUEUE.
    1. Return:
key type description
isFirst bool True
status string "continue waiting"

2.2 Player send new piece

Store the new piece placed by the user into the database. Link to code Also the back end will check if the new piece leads to the wining of that player. Link to code If so, the back end returns the winning state of the game.

Endpoint POST /sendpiece/

Request Parameters:

key type description
userid int user's assigned id
marker_location string (x,y,z) of the marker's relative position

Steps:

    1. Check the GAME_STATUS in GAME_INFO, if the game has ended, return:
key type description
status string "end game"
    1. Change the new piece in NEW_PIECE_INFO to marker_location.
    1. Add the record to ALL_PIECES_INFO.
    1. In GAME_INFO table, corresponding PIECE_CNT +=1.
    1. [MVP] Calculate whether player wins. If player wins, change player's GAME_STATUS in GAME_INFO from "OnGoing"to "Win", change opponent's GAME_STATUS from "OnGoing"to "Lose".
    1. Set player's PLAYER_TURN in GAME_INFO to False, opponent's PLAYER_TURN to True
    1. Return:
key type description
status string "opponent turn"

2.3 Check game status

The back end returns the status of the game (ongoing/win/lose). Link to code

Endpoint: POST /checkstatus/

Request Parameters:

key type description
userid int user's assigned id

Steps:

    1. Check the GAME_STATUS in GAME_INFO, if the game has ended, return:
key type description
status string "end game"
new_piece_location string (0,0,0)
    1. Check if it's player's turn by PLAYER_TURN in Game_info
    1. If PLAYER_TURN == False , return:
key type description
status string "opponent turn"
new_piece_location string (0,0,0)
    1. If PLAYER_TURN == True, find opponent's new piece, return:
key type description
status string "player turn"
new_piece_location string opponent's new piece (x,y,z)

2.4 End game request:

The front-end user leaves the game, the back-end lets this user lose the game. Link to code

Endpoint: POST /endgame/

Request Parameters:

key type description
userid int user's assigned id

Steps:

    1. If userid is in Game_info, set player's GAME_STATUS in GAME_INFO from "OnGoing"to "Lose", set opponent's GAME_STATUS from "OnGoing"to "Win".
    1. If player is unmatched in the MATCH_QUEUE, set MATCHED to True.
    1. Return status = 'ended'

3.1 Check end game stats

Check the stats of the game after game ends. Link to code

Endpoint POST /checkwin/

Request Parameters:

key type description
userid int user's assigned id

Steps:

    1. If userid in Game_info , returns:
key type description
isWin bool True if win, "False" otherwise
num_piece int number of pieces in the game
    1. Otherwise, return:
key type description
isWin bool False
num_piece int number of pieces in the game

3.2 Clear user records in database

Clear user records regarding this game in the database. Link to code

Endpoint: POST /clearrecords/

Request Parameters:

key type description
userid int user's assigned id

Steps:

    1. Clear all the records related to userid in GAME_INFO, NEW_PIECE_INFO, and ALL_PIECES_INFO.
    1. Clear all the records related to userid in MATCH_QUEUE.
    1. Return: status = 'cleared'