CS 5010讲解、辅导Yahtzee留学生、讲解Java程序、辅导Java编程

- 首页 >> Java编程

Assignment 8:

Multi-Player Client-Server Yahtzee

CS 5010

Released: November 26, 2018

Due: December 3, 2018

Abstract

Yahtzee is a dice-rolling game. The game requires 5 dice and a scorecard, and can be played

by (theoretically) any number of players. Gameplay consists of two phases: the Rolling phase,

and the Scoring phase. In the Rolling phase, players can roll as many of the dice as they want,

for up to 3 times total. At each roll, players can keep or re-roll as many dice as they want. In the

Scoring phase, the player chooses which entry on the scorecard they want to fill, given the final

values on the rolled dice. The player with the highest number of points on the scorecard at the

end wins. As you can imagine, it’s important to be familiar with the scorecard and figure out a

strategy to maximize points. However, in this assignment, you’re less concerned with winning,

and should be more concerned with how to make the game play fun and easy for your players.

1 Assignment Objectives

The objectives of this assignment are to:

Write a client to a given protocol

Write a server for a given protocol

Build a text-based UI that runs on the command line

Implement a client-server application

2 Background

We learned that a client server application requires a server application, a client application, and

a protocol defined to ensure consistent communication between the two. In this assignment, you

are going to write a client app that connects to server app, implementing the game protocol. The

server will control the game, such as keeping track of how many people are playing, who’s turn it

is, rolling the dice (so no cheating from the clients), keeping track of the score, and enforcing the

rules. The client is playing the game, and for this, it’s a command line interface so that a human

is playing the game with other humans joining from other instances of the client.

In the end, you will have a game that you can play!

3 Introduction to Yahtzee

Yahtzee is a dice game. The goal is to fill out a score card, based on rolls of the dice. There are

12 rounds to the game— one for each line on the scorecard. Each player goes through a round of

rolling the dice, and then chooses which row of the scorecard to fill out. This results in points.

1

3.1 The Scorecard

Below is the scorecard used for Yahtzee. This needs to be implemented on the server, as scoring

is done on the server. The ID column indicates what the score row is referred to in this game

implementation.

Upper Section

Pattern Condition Score ID

Aces none total value of all aces (ones) Aces

Twos none total value of all twos Twos

Threes none total value of all threes Threes

Fours none total value of all fours Fours

Fives none total value of all fives Fives

Sixes none total value of all sixes Sixes

Lower Section

Pattern Condition Score ID

Three of a kind 3 or more equals total value of all dice ThreeOfKind

Four of a kind 4 or more equals total value of all dice FourOfKind

Full House 3 equals + 2 other equals 25 FH

Small Straight sequence of 4 or more 30 SS

Large Straight sequence of 5 40 LS

Yahtzee 5 equals 50 Yahtzee

Chance none total value of all dice Chance

4 Requirements

Your client must:

Run from the command line, given a hostname and port number

Connect to the server via a socket

Get info from the user and format it appropriately to send to the server.

4.1 Client Requirements

The client is playing the game, and for this, it’s a command line interface so that a human is playing

the game with other humans joining from other instances of the client. Your client must display

information to the user, get choices from the user, and then send those choices to the server. You

can decide for yourself if the client you’re writing allows players to try to cheat or otherwise make

invalid moves.

Must be in package edu.neu.cs5010.yahtzee.client

Must run from the command line, given a hostname and port number

– e.g. java edu.neu.cs5010.yahtzee.client.GameClient localhost 1200

Connect to the server via a socket

Get info from the user and format it appropriately to send to the server.

2

4.2 Server Requirements

The server will control the game, such as keeping track of how many people are playing, who’s turn

it is, rolling the dice (so no cheating from the clients), keeping track of the score, and enforcing the

rules.

Must be in package edu.neu.cs5010.yahtzee.server

Must be able to run the server by calling java edu.neu.cs5010.yahtzee.server.GameServer 1200 DEV ,

where the first argument is the port number

Run from the command line, given a port number to listen on

– e.g.: java edu.neu.cs5010.yahtzee.server.GameServer 1200 DEV

– Param 1: port number to listen on

– Param 2: optional DEV flag to run with fewer rounds.

Properly shutdown the port when a kill command is sent (Ctrl-C) (See code from class)

Must allow 1-6 players to play in one game.

Must handle the provided protocol properly.

Must gracefully handle messages that do not conform to the protocol.

Is responsible for “rolling the dice”: at the start of each player’s turn, the server should roll

the dice and tell the player the values they have to choose from.

Must implement some message checking to ensure that a player is not cheating.

4.3 Hints and Tips

It’s usually most helpful to create an echo server as a placeholder for your server first, then

start building the client.

Consider creating multiple configurations for your project: one for running the server, one

for running the client. You might even have one for running an echo server.

Consider having a special “dev” mode for your client and/or server. Instead of running the

entire game, only run 3-4 rounds.

This is a good time to utilize the design patterns you’ve learned about over the semester.

Be sure to test your game by running the server on one computer and client on another

computer. You may be asked to be the server to another team’s client in your codewalk.

Because all teams will implement the protocol properly, it should work seamlessly.

5 The game protocol

A protocol is defined by a set of “Frames” or messages that are sent between the server and client.

The frames specify the beginning and end of a message, and the actual message is in the “payload”

of the frame. Consider that our clients and servers are listening to streams of data coming in. How

does your client know where the end of the frame is, in order to parse the message?

In this protocol, the newline (\n) character is the end of a frame. The beginning of a frame is

a tag (string) followed by a colon (‘:’), which is then followed by a payload. Your client recognizes

receipt of a frame, parses the frame type from the frame header, and then uses that information to

parse the payload and respond accordingly.

3

Further, to ensure proper communication, every message the server sends to the client has a

unique ID associated with it; every response from the client includes the message ID it is responding

to. To implement the unique ID, it is acceptable in this case to simply initialize a counter to 0 at

the beginning of the server start up and increment it every time a message is sent.

In the next sections, the client and server frames are defined. After that, the list of the interaction

of the frames.

5.1 Client Frames

These are the messages that can be sent from the client to the server.

1. KEEP DICE

Payload: 6 ints. The first 1 is a unique id that corresponds to a roll of the dice by the server

(see CHOOSE DICE), and another 5, which must be 0 or 1s to indicate whether to keep the

relevant dice. If the original CHOOSE DICE message sent was “293 1 2 6 4 1” and the player

wants to keep the 1st, 2nd and 5th, the payload would be “293 1 1 0 0 1”.

2. SCORE CHOICE

Payload: 1 int and string. The first int is a unique id corresponding to a CHOOSE SCORE

message sent earlier, and a string that is the name of score to take (options provided in the

corresponding CHOOSE SCORE message).

3. ACK

Sends an acknowledgement of a message. Payload: 1 in and an optional string describing the

acknowledgement. First int is the message ID indicating the message this is in response to.

4. PRINT GAME STATE

Prints the current game state on the server terminal. Expect an GAME STATE response

from the server in response (the same game state string printed on the server terminal).

Payload: Unique message id.

5. QUIT GAME

Payload: 1 int. Unique message id. Tells the server that this player is quitting the game. The

round should complete, and then the server ends the game, sending a GAME OVER message

to all players. Expect an ACK from the server in response.

5.2 Server Frames

1. START GAME

Payload: Unique message id. Expect an ACK in return.

2. START ROUND

Payload: Unique message id and int indicating which round. Expect an ACK in return.

3. START TURN

Payload: Unique message id. Expect an ACK in return.

4. CHOOSE DICE

Payload: Unique message id and 5 ints, with values 1-6, each representing a given die roll.

Expect a KEEP DICE message in return.

5. INVALID DICE CHOICE

Payload: Unique message id and the same payload as CHOOSE DICE.

6. CHOOSE SCORE

Payload: Unique message id and 5 ints that are the current dice rolls, and then a sequence of

4

strings of the names of the score slots to be chosen from. Expect a SCORE CHOICE message

in return.

7. SCORE CHOICE INVALID

Payload: Unique message id and the same payload as CHOOSE SCORE.

8. SCORE CHOICE VALID

Payload: A unique id and a list of all the scores on the scorecard and their values. Value is

-1 if it has not been used yet. Order is arbitrary. Total is at the end.

Example: Aces -1 Twos 6 Fives 5 3K 6 [...] Total 75. Expect an ACK in return.

9. TURN OVER

Payload: Unique message id. Expect an ACK in return.

10. ROUND OVER

Payload: Unique message id and int indicating which round is over. Expect an ACK in

return.

11. GAME OVER

Payload: A unique message id and a list of the final scores for each player.

Example: Player1 109 Player2 74. Expect an ACK in return.

12. ACK

Payload: An id that indicates the message this ACK is in return to. An optional string

describing an acknowledgement of receipt of a message from the client.

13. INFO

Payload: A unique message id and a string providing an informational message from the

server to the client. Expect an ACK in return.

14. GAME STATE

Payload: A unique message id and a string describing the current game state. Expect an

ACK in return.

5.3 Interaction

1. Server starts

2. All client/player connects

3. Server sends “StartGame” to all clients/players

4. Game play rounds begins. Server sends StartRound message to all players.

For each client/player, this is the sequence for each player in each round:

(a) Server sends StartTurn message

(b) Start the rolling phase. While the player has rolled < 3 times or not kept all the dice:

i. Server rolls the dice and sends ChooseDice message

ii. Client sends KeepDice message

iii. Server sends valid/invalid KeepDice choice message

(c) Start the scoring phase.

i. Server sends set of score choices for client to choose from

ii. Client sends score choice

iii. Server sends valid/invalid score choice.

(d) Server sends TurnOver message.

5. Repeat for each player

5

6. Repeat for each round (13 rounds total, unless in DEV mode)

7. Server sends GameOver message to all players

8. Players gracefully disconnect and terminate.

Below is a example of the back and forth messages between the clients and server.

6

Here, we have an example client and server output. Your output does not need to match, but

should have similar kinds of information.

Client Side

1 java edu.neu.cs5010.yahtzee.client.GameClient localhost 1200

2

3 FromServer: INFO: 1 Joining the game.

4 FromServer: INFO: 2 Waiting for more players to join.

5 FromServer: INFO: 3 Game Started. Waiting for my turn.

6 FromServer: START_ROUND: 4 1

7 FromServer: START_TURN: 5

8 FromServer: CHOOSE_DICE: 6 1 2 6 1 2

9 Enter numbers for the ones you want to keep, 1-5.

10 1 2 4 5

11 FromServer: CHOOSE_DICE: 7 1 2 2 1 2

12 Enter numbers for the ones you want to keep, 1-5.

13 1 2 3 4 5

14 FromServer: CHOOSE_SCORE: 8 1 2 2 1 2 Twos Fours SmallStraight FullHouse

Yahtzee Fives LargeStraight Aces Chance Threes FourOfKind Sixes

ThreeOfKind

15 Enter the Score you want to take: CHOOSE_SCORE: 1 2 2 1 2 Twos Fours

SmallStraight FullHouse Yahtzee Fives LargeStraight Aces Chance Threes

FourOfKind Sixes ThreeOfKind

16 FullHouse

17 FromServer: SCORE_CHOICE_VALID: 9 Twos -1 Fours -1 SmallStraight -1 FullHouse

25 Yahtzee -1 Fives -1 LargeStraight -1 Aces -1 Chance -1 Threes -1

FourOfKind -1 Sixes -1 ThreeOfKind -1 Total 25

18 FromServer: TURN_OVER: 10

19 FromServer: ROUND_OVER: 11 1

20 FromServer: START_ROUND: 12 2

21 FromServer: START_TURN: 13

22 FromServer: CHOOSE_DICE: 14 6 2 6 5 3

23 Enter numbers for the ones you want to keep, 1-5.

24 ...

Below is a sample output from the server (on the server console). This provides an example of

what the server is doing at each step, which helps all of us ensure it is doing the right thing, and

identify when it’s not.

1 java edu.neu.cs5010.yahtzee.server.GameServer 1200 DEV

2

3 Listening for clients to join...

4 Client connected.

5 Listing for input from client.

6 I am m joining the game!

7 Got a player to join the game!

8 Joining new player.

9 Got enough players; starting the game now.

10 Starting round 1

11 Rolling the dice...

12 ******* YAHTZEE Game State *******

13 Current Round: 1

14 Current Player: Player1

15 Num Rolls so far: 0

16 Current Dice Values: { [1] [2] [6] [1] [2] }

17 ---------------------------------------------------------------

18 Player 1 Scorecard:

19 Twos -1 Fours -1 SmallStraight -1 FullHouse -1 Yahtzee -1 Fives -1

LargeStraight -1 Aces -1 Chance -1 Threes -1 FourOfKind -1 Sixes -1

ThreeOfKind -1

20 Total Score: 0

21 ---------------------------------------------------------------

22 [DEBUG] Dice chosen: [Z@3b3782e9

23 [DEBUG] Rolling the dice...

24 [DEBUG] Rolling again...

25 [DEBUG] Dice chosen: [Z@5025d2af

7

26 [DEBUG] Waiting to score...

27 [DEBUG] checking for valid score selection...

28 [DEBUG] Ending turn for: Player1

29 [DEBUG] Valid choice of score... waiting for next turn.

30 [DEBUG] Ending round 1

31

32 [DEBUG] Starting round 2

33 [DEBUG] Starting turn for: Player1

34 [DEBUG] Rolling the dice...

35 ******* YAHTZEE Game State *******

36 Current Round: 2

37 Current Player: Player1

38 Num Rolls so far: 0

39 Current Dice Values: { [6] [2] [6] [5] [3] }

40 ---------------------------------------------------------------

41 Player 1 Scorecard:

42 Twos -1 Fours -1 SmallStraight -1 FullHouse 25 Yahtzee -1 Fives -1

LargeStraight -1 Aces -1 Chance -1 Threes -1 FourOfKind -1 Sixes -1

ThreeOfKind -1

43 Total Score: 25

44 ---------------------------------------------------------------

6 What To Turn In

When submitting your assignment, you should continue using the same Maven archetype that we

used in previous assignments.

Please submit the following:

All classes that you have developed for this assignment

All classes that you developed to test your code

A UML diagram showing the design of your program (for the client, server and protocol)

A brief write-up, which summarizes the main relations between your classes, and how does

your program handle errors and/or exceptions.


站长地图