Spring 2021 CSE30264 Programming Assignment 4 - Online Pong Game


Total Points: 100 points
Goal: Create an Online Pong Game
Assigned: April 19, 2021
Due: May 5, 2021 Extended to May 10, 2021 by the end of day (11:59 pm Eastern).
Grouping: To be completed by a group.
Note: This instruction is based on C/C++. The Python version is available at here.

Background

In this programming assignment, you will create a Pong game that can be played over the network. You can design the protocol that the game uses so that both competitors can see the same synchronized game board, and you may choose whether to use TCP or UDP. You are free to reuse parts of your programs from assignment 1-3 to finish this programming assignment. Note: please refer to appendix A for the port number assigned to you (the same as PG1).

For the assignment, you will turn in a gzipped tar file to your dropbox. The gzipped tar file should contain:

The Game

Pong is played by two competitors. A ball bounces between the two sides of the court, and each player controls a paddle to deflect the ball when it reaches their side. The goal is to score points by getting the ball past the opponent's paddle. The left paddle is controlled using the W / S keys, and the right paddle is controlled by the UP / DOWN arrow keys.

Below is an example of the provided UI. The two paddles (controlled by the players) are on the sides, and the ball is currently in the upper right next to the score. The competitor on the left has 1 point, and the right has 0. This GUI along with the code to run it (i.e., pong.c/pong.cpp) is provided at /escnfs/courses/sp21-cse-30264.01/public/program4/C/. The program uses ncurses for the interface, so it can be run through an SSH session. Note: The provided code is formatted as a starting point to be modified, not as a library.

┌────────────────────┬────────────────────┐
│                  1 │ 0                  │
│                    │        █           │
│                    │                    │
│                    │                    │
│                    │                    │
│                    │                    │
│                    │                    │
│█                   │                    │
│█                   │                    │
│█                   │                   █│
│█                   │                   █│
│█                   │                   █│
│                    │                   █│
│                    │                   █│
│                    │                    │
│                    │                    │
│                    │                    │
│                    │                    │
│                    │                    │
└────────────────────┴────────────────────┘

Networked Pong

This assignment is intended to be far more open-ended than previous assignments. Here we provide a few suggestions based on what we have observed to work well, but we expect you to design the protocol you use. We also state requirements that you are responsible for implementing.

Structure

Your implementation should use a peer-to-peer structure. The alternative is to have a separate game server, making for three hosts in communication. However, since there are only two players in pong, using a direct connection between them can be much easier to implement than having a separate game server. Care must be taken, however, to resolve any discrepancies that arise because of timing issues. For example, if the ball is about to go past Player1's paddle, but Player1 moves the paddle just in time, then it is possible for Player1 to observe a save while Player2 observes that a point is scored. Your protocol must be able to resolve such discrepancies fairly, that is, there is no structural advantage for one player over the other.

Even though the structure is peer-to-peer, the initialization of the protocol requires one host to listen for incoming connections (i.e., it is hosting the game) while the other makes an outgoing connection. Therefore, you should use the flag "--host" to differentiate between the two roles in the initialization of the protocol.

Synchronization

You may choose how and when the two running instances of the game communicate with each other. Two popular approaches we can recommend are timer-based and event-based systems. In a timer-based system, the instances of the game send each other updated information (paddle position, ball position, points scored, etc.) at a fixed rate, e.g., 20 times each second. Alternatively, under an event-based scheme, updates are only sent when something important happens (e.g., paddle moves because of user input, a point is scored, the ball is deflected).

UDP vs. TCP

You may choose whether to use UDP or TCP. We found that the TCP and UDP protocols work best when paired with certain update schemes. Since UDP is lightweight but does not guarantee error-free delivery, we found that it works best with a timer-based update scheme. If a packet is corrupted or fails to arrive, then the next one can be used instead. TCP, on the other hand, will bog down a game at a much slower update rate than UDP in a timer-based scheme. Therefore, TCP is better suited for an event-based scheme, where the built-in delivery guarantees that a packet won't be missed.

Hosting and Difficulty

The provided pong.c/pong.cpp code allows players to set the difficulty, which corresponds to the time between ball movements (a smaller time interval means the ball moves faster, which makes the game harder). Your networked version should also allow difficulty settings. The three difficulties are: easy where the rate is 80 milliseconds, medium where it is 40 milliseconds, and hard where it is 20 milliseconds. The networked Pong game should prompt the peer hosting the game for the difficulty level, i.e., the host will receive an incoming challenge of the selected difficulty.

When running the code, please use the following syntax for arguments:

[user@server ~]$ ./netpong --host PORT 

[user@client ~]$ ./netpong HOSTNAME PORT

Round Counting

The networked Pong game should allow the players to play multiple rounds of games. In each round, the player first reaches the score of 2 will win the round and the score board will be reset to zero for both players. The networked Pong game should prompt the peer hosting the game to enter the maxium number of rounds to play, and count the number of rounds. If the maximum number of rounds is reached or a player exits, the game should exit gracefully.

Quitting

The game exits when one competitor terminates the application, e.g., by pressing CTRL-C. When this happens, both players should exit gracefully. You may find it useful to set up a signal handler to intercept the CTRL-C:

#include <signal.h>

void handler(int signal) {
    // do cleanup tasks (send termination message to peer, close socket cleanly, etc.)
    endwin(); // clean up ncurses
    exit(0);
}
Then, in your main method:

signal(SIGINT, handler);

Demo:


Download the Demo.

General Notes

The peer that hosts the game by listening for a connection should listen on the specified port number [refer to Appendix for the port number for your group] that is given by command line argument. Your server should bind to the port and then listen for incoming client connections. You may want to allow for port reuse for quicker recovery after a crash.

Submission

Submit a gzipped tar file of your entire assignment package to your dropbox/program4 directory. The archive must include the following:

Grading Rubric


Appendix

Table 1. Port Assignments
Port to UseName
41001 Joshua Agron
41002 Matthew Ahrens
41003 Emma Ascolese
41004 Julia Blanchard
41005 Brian Cariddi
41006 Maria Carroll
41007 Mark Cheng
41008 Clara Cheong
41009 Megha Devaraj
41010 Theodore Donegan
41011 Ahmed Farag
41012 William Gentry
41013 John Gordley
41014 Emily Grow
41015 Alejandro Jose Gutierrez Elizondo
41016 Jake Hracho
41017 Melka Konshie
41018 Tyler Krasny
41019 Zachary Kreft
41020 Jonathan David Lamptey
41021 Sabin Litchfield
41022 Nicholas Locascio
41023 Keegan MacDonell
41024 John Masciopinto
41025 Jacob Mazur
41026 Mary McCann
41027 Daniel McFarlane
41028 Evan Mercurio
41029 Conor Murphy
41030 Peter Oliver
41031 Ryan Pairitz
41032 Thomas Renfrew
41033 John Rundle
41034 Matthew Shan
41035 Luke Siela
41036 Dane Williams