Last updated: Wed, 11 Mar 2015 10:39:23 -0400
DUE: Monday 3/16/2015, 9pm EST
You must use the Intermediate Student with lambda language to complete this assignment. Select it via the Choose Language... menu located at the bottom-left of the DrRacket window.
Put all your solution files in a directory named set08 in your repository.
Download extras.rkt to this directory (right-click and choose "Save As"; don’t copy and paste) and commit it as well.
Use begin-for-test and rackunit to define your examples and tests.
- Don’t forget to tell us how many hours you spent working on the assignment. This should be a global variable called TIME-ON-TASK in each file. For example:
(define TIME-ON-TASK 10.5) ; hours
- So each solution file must have at least the following at the top:
(require "extras.rkt") (require rackunit) (define TIME-ON-TASK <number-of-hours-you-spent>)
- After you’ve submitted your solution, use a web browser to go to https://github.ccs.neu.edu/ and check that your repository contains the following files:
Git Commit Requirement: For this assignment, you must have at least three well-labeled git commits (including the final commit). A well-labeled git commit accurately and succinctly describes the changes since the previous commit. Something like "commit2", or "home work 3" is not an acceptable git commit label. Failure to meet this requirement will result in loss of points.
UPDATE 2015-03-10: You may use functions from the racket/string library. In particular, string-split may be useful. No other unapproved libraries are allowed.
(check-location "08" "chat.rkt")
Write a chat client using the distributed big-bang from 2htdp/universe.
- On the left is a column displaying the user names of all chat participants. This area should be 100 x 400 pixels. The names should be listed in lexicographic order, top to bottom. This section should be updated whenever users enter or leave the chat. If there are more users than fit in this part of the window, then the user list should be truncated, starting with the usernames that are lexicographically last.
- On the bottom is an area for the user to enter a message. This area should resemble the one-line editor from previous problem sets and should be 300 x 20 pixels in size. Specifically:
The left and right keys move the cursor.
Pressing \b (backspace) erases the character to the left of the cursor.
- Pressing \t (tab) should autocomplete a user name. Specifically, if the cursor is all the way to the right in the editor and the text entered so far is a prefix of a current chat participant, then pressing tab should change the editor’s contents to that chat participant’s user name, with the cursor still at the right. If there is more than one match, choose the match that would appear first lexicographically. If there are no matches, then the tab key is ignored.
UPDATE 2015-03-10: Case-sensitivity matters when auto-completing. Only autocomplete when there is an exact prefix match. So ste may autocomplete to stephen but not Stephen.
Pressing enter should send the currently entered message. Sending message is discussed below.
This area has no size limit. If the entered message is too large to display, only the most recently entered characters are displayed. However, the entire message should still be sent to the server.
UPDATE 2015-03-06: When the entered message is too large to fit entirely within the editor, pressing "left" and "right" at the edges should scroll what is displayed, as in a typical text editor. Specifically:
When the cursor is all the way at the right edge, and "right" is pressed, if there are more characters available on the right, then one additional character should appear at the right, and some characters should disappear at the left to compensate. Shift out enough characters on the left such that no characters get cut off when rendering the editor. The cursor should still be rendered all the way to the right,
and vice versa when the cursor is all the way to the left edge and "left" is pressed.
If the cursor is somewhere in the middle of the editor, then only the position of the cursor changes when "left" or "right" is pressed.
- The remaining area should display received messages, sent messages, and other events, with the most recent messages at the bottom.
No more than 25 events should be displayed in this area.
If there’s not enough room to render 25 events, then render as many events as possible, giving preference to more recently received events.
When the history exceeds 25 events, the oldest message should be dropped from the chat state.
A message should be displayed with the originating user name in angle brackets, with a single space inside each bracket, followed by a space outside the right bracket, followed by the message content.
Private messages should be formatted slightly differently, as explained below.
- If an event cannot be cannot be rendered within the width of the display area, it should be rendered on multiple lines, fitting as many words as possible on the first line, then fitting as many words as possible on the second line, etc.
UPDATE 2015-03-10: If one word exceeds the width of the display area, then fit as many characters as possible on each line.
Join and leave events should be rendered in gray.
Error messages from the server should be rendered in red.
prasad: secret message
UPDATE 2015-03-10: The chat client should only attempt to send a private message if the text before the : is a valid UserName. Otherwise, it should send a broadcast message with the entire entered message, including the text before the : and the : itself.
; A UserName is a String, consisting of only letters and numbers, ; and is between 1 and 12 characters long. ; Represents a chat room participant. ; A Message is a String ; MsgToServer is a: ; - (list 'broadcast Message) ; - (list 'private UserName Message) ; The user in the private message is the intended recipient of the message.
; A MsgFromServer is a: ; - (list 'userlist ListOf<UserName>) ; all the current chat participants ; - (list 'join UserName) ; the user that just joined ; - (list 'leave UserName) ; the user that just left ; - (list 'error Message) ; an error message from the server ; - (list 'private UserName Message) ; a priv msg from the specified user ; - (list 'broadcast UserName Message) ; a broadcast msg from the specified user
; A HandlerResult is a: ; - World ; - (make-package World MsgToServer) ; mk-world : UserName -> World ; Returns the initial world state for user name. (define (mk-world nam) ...) ; receive : World MsgFromServer -> HandlerResult ; Handles messages received from the server. ; key-handler : World KeyEvent -> HandlerResult ; Handles keyboard user input. ; get-users : World -> ListOf<UserName> ; Returns a list of current chat participants, in lexicographic order. ; get-editor : World -> Editor ; Returns a representation of the chat client's input area. ; get-editor-pre : Editor -> String ; get-editor-post : Editor -> String ; Returns an editor's content before and after the cursor. ; get-chat-history : World -> ListOf<String> ; Returns a list of chat events, rendered to string, ; where each string format is the same as when the event is ; rendered to the chat window, except the string should not be broken into ; multiple lines.