Fall 2019 CSE30264 Programming Assignment 4 - Online Pong Game


Total Points: 100 points
Goal: Create an Online Pong Game
Assigned: Nov. 13
Due: Dec. 4, 2019 by the beginning of class
Grouping: Completed by a group


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 assignments 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. For a starting point, a local (non-networked) implementation pong.c/pong.cpp (along with its Makefile) is provided at /escnfs/courses/fa19-cse-30264.01/files/program4/. The left paddle is controlled using the W / S keys, and the right paddle is controlled by the UP / DOWN arrow keys. The program uses ncurses for the interface, so it can be run through an ssh session.

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/fa19-cse-30264.01/files/program4/. 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 until a player exits the game. 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.

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 A

Table 1. Port Assignments
TCP Port to UseName
41001 Samuel Battalio
41002 Bailey Blum
41003 Paul Brunts
41004 Kathleen Capella
41005 Jacques Charboneau
41006 Thomas Clare
41007 Jack Conway
41008 Matthew DaDamio
41009 Megha Devaraj
41010 Michael Eisemann
41011 Michael Erdenberger
41012 Nicholas Fahrney
41013 Clare Fallon
41014 Patrick Fischer
41015 Chris Foley
41016 John Fox
41017 Luke Fraser
41018 Owen Gallahue
41019 Jorge Garcia
41020 Elizabeth Genovese
41021 Gabrielle Good
41022 Joseph Gripenstraw
41023 Katherine Hecht
41024 Jack Hill
41025 Julia Hughes
41026 Carson Lance
41027 Connor Laracey
41028 Bailey Logan
41029 Horacio Lopez
41030 Catherine Markley
41031 Imari McKinney
41032 Sean Michalec
41033 Ralph Moran
41034 David Odun-Ayo
41035 Jewon Oh
41036 Cole Pickford
41037 Brendan Raimann
41038 Christopher Ray
41039 Daniel Riehm
41040 Conor Rinehart
41041 Francis Schickel
41042 Matthew Siciliano
41043 Richard Stefanik
41044 Emily Strout
41045 Blake Trossen
41046 Justin Virgadamo
41047 Trenton Wray
41048 Jillian Ybanez
41049 Logan Yokum
41050 Christina Youn