gpt4 book ai didi

java - 实现客户端-服务器,GUI StringBuilder 问题

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:07:03 24 4
gpt4 key购买 nike

尝试制作客户端服务器程序,特别是刽子手游戏。

我有 4 个文件:KnockKnockServerKnockKnockProtocolHangmanKnockKnockClient。

KnockKnockServer 运行,KnockKnockClient 连接到它。 KnockKnockProtocol 处理来自客户端的请求。如果 KnockKnockProtocol 识别出特定单词或短语,客户端将向用户发送请求,它将为特定单词提供答案。Hangman 文件是一个完整的 Hangman 游戏(不是客户端服务器),我想重新使用其中的一些方法,例如打印 Hangman 花花公子。拿那个 Hangman 花花公子并在客户端显示。

所以我正在使用字符串生成器来修改字符串。但是我得到了奇怪的结果。我应该使用字符串生成器还是其他东西?我还需要修复什么,以便客户端可以接收 Hangman 资源?我应该重新设计整个项目吗?

这是服务器打印的方式:

run:
____
| |
|
|
|
|
|
|
__|__

_ _ _
Wrong letters: ____
| |
|
|
|
|
|
|
__|__

_ _ _
Wrong letters:
s
a
BUILD SUCCESSFUL (total time: 1 minute 31 seconds)

奇怪的是它打印了两次 Hangman dude。

这是客户端显示的内容:

run:
Server: Connection Established.. Start hangman? (y/n)
y
Client: y
Server: ____
a
Client: a
Server: | |
e
Client: e
Server: |
i
Client: i
Server: |
o
Client: o
Server: |
s
Client: s
Server: |
r
Client: r
Server: |
r
Client: r
Server: |
r
Client: r
Server: __|__
s
Client: s
Server:
g
Client: g
Server: _ _ _
g
Client: g
Server: Wrong letters:
h
Client: h
Server: You're supposed to say "Little Old Lady who?"! Try again. Knock! Knock!
BUILD STOPPED (total time: 1 minute 15 seconds)

客户端使用字符串生成器从服务器端重建字符串绘制一个刽子手。但它没有被正确绘制。

KnockKnockServer 服务器端:

import java.net.*;
import java.io.*;

public class KnockKnockServer {
public static void main(String[] args) throws IOException {

if (args.length != 1) {
System.err.println("Usage: java EchoServer <port number>");
System.exit(1);
}

//sets portNumber to argument run value
int portNumber = Integer.parseInt(args[0]);

try (
ServerSocket serverSocket = new ServerSocket(portNumber);
Socket clientSocket = serverSocket.accept();
PrintWriter out =
new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
) {

String inputLine, outputLine;

KnockKnockProtocol kkp = new KnockKnockProtocol();
outputLine = kkp.processInput(null);
out.println(outputLine);

while ((inputLine = in.readLine()) != null) {
outputLine = kkp.processInput(inputLine);
out.println(outputLine);
if (outputLine.equals("Bye."))
break;
}
} catch (IOException e) {
System.out.println("Exception caught when trying to listen on port "
+ portNumber + " or listening for a connection");
System.out.println(e.getMessage());
}
}
}

KnockKnockProtocol 服务器端:

import java.net.*;
import java.io.*;

public class KnockKnockProtocol {
private static final int WAITING = 0;
private static final int SENTKNOCKKNOCK = 1;
private static final int SENTCLUE = 2;
private static final int ANOTHER = 3;

private static final int NUMJOKES = 5;

private int state = WAITING;
private int currentJoke = 1;

private int counter = 0;

private String[] clues = { "Turnip", "Little Old Lady", "Atch", "Who", "Who" };
private String[] answers = { "Turnip the heat, it's cold in here!",
"I didn't know you could yodel!",
"Bless you!",
"Is there an owl in here?",
"Is there an echo in here?" };

public String processInput(String theInput) {
Hangman hman = new Hangman();
String theOutput = null;

if (state == WAITING) {
theOutput = "Connection Established.. Start hangman? (y/n)";
state = SENTKNOCKKNOCK;





} else if (state == SENTKNOCKKNOCK) {
//if (theInput.equalsIgnoreCase("Who's there?")) {
if (theInput.equalsIgnoreCase("y")) {
//theOutput = clues[currentJoke];
theOutput = hman.printCurrentState();
System.out.println(theOutput);
state = SENTCLUE;

} else {
theOutput = "You guessed a wrong word" + " failed attempts: " + counter++ +
" Try agian. Start hangman? (y/n)";
}
} else if (state == SENTCLUE) {
if (theInput.equalsIgnoreCase(clues[currentJoke])) {
theOutput = answers[currentJoke] + " Play again? (y/n)";
state = ANOTHER;
} else {
theOutput = "You're supposed to say \"" +
clues[currentJoke] +
" who?\"" +
"! Try again. Knock! Knock!";
state = SENTKNOCKKNOCK;
}
} else if (state == ANOTHER) {
if (theInput.equalsIgnoreCase("y")) {
theOutput = "Guess a word";
if (currentJoke == (NUMJOKES - 1))
currentJoke = 0;
else
currentJoke++;
state = SENTKNOCKKNOCK;
} else {
theOutput = "Bye.";
state = WAITING;
}
}
return theOutput;
}
}

刽子手游戏服务器端:

///////////////////////////////////////////////////////////////////////////////
// Title: Hangman
// Files: Hangman.java
//////////////////////////// 80 columns wide //////////////////////////////////

import java.util.*;

/**
* This program implements the word guessing game called Hangman.
*
* <p>Bugs: none known
*
* @author CS302, 2009,2012 modified by Jim Skrentny
*/
public class Hangman {

//////////////////////////////////////////////////////////////////////
// 1. CLASS VARIABLE
//////////////////////////////////////////////////////////////////////
private static String [] words = //choose secret word from these
{"geography", "cat", "yesterday", "java", "truck", "opportunity",
"fish", "token", "transportation", "bottom", "apple", "cake",
"remote", "pocket", "terminology", "arm", "cranberry", "tool",
"caterpillar", "spoon", "watermelon", "laptop", "toe", "toad",
"fundamental", "capitol", "garbage", "anticipate", "apple"};



//////////////////////////////////////////////////////////////////////
// 2. INSTANCE VARIABLES
//////////////////////////////////////////////////////////////////////
private String secretWord; // the chosen secret word
private ArrayList<Character> correctLetters; // correct guesses
private ArrayList<Character> incorrectLetters; // incorrect guesses

private Scanner stdin = new Scanner(System.in); // for user input



//////////////////////////////////////////////////////////////////////
// 3. CONSTRUCTOR
//////////////////////////////////////////////////////////////////////
/**
* Constructs a Hangman game.
*/
public Hangman() {
//REMOVE LINE BELOW WHEN DONE TESTING
//this.secretWord = "miscellaneous";

//Randomly choose a word from list of words
//UNCOMMENT LINES BELOW TO PLAY WHEN DONE TESTING
Random randIndex = new Random();
int index = randIndex.nextInt(Hangman.words.length);
this.secretWord = Hangman.words[index];

this.correctLetters = new ArrayList<Character>();
for (int i = 0; i < this.secretWord.length(); i++)
this.correctLetters.add('_');
this.incorrectLetters = new ArrayList<Character>();
}



//////////////////////////////////////////////////////////////////////
// 4. PUBLIC INSTANCE METHODS
//////////////////////////////////////////////////////////////////////

/**
* playGame
*
* Play one game of Hangman until
* the user wins (guesses all of the letters in the secret word)
* or loses (guesses 7 incorrect letters):
*/
public void playGame() {

while (!gameOver()) {

//Print the Hangman picture
printHangman();

//Print the correct guesses in the secret word
for (int i = 0; i < this.correctLetters.size(); i++)
System.out.print(this.correctLetters.get(i) + " ");

//Print the incorrect letters that have been guessed
System.out.print("\nWrong letters: ");
for (int i = 0; i < this.incorrectLetters.size(); i++)
System.out.print(this.incorrectLetters.get(i) + " ");

//Prompt and read the next guess
System.out.print("\nEnter a lower-case letter as your guess: ");
String guess = stdin.nextLine();

//Process the next guess
handleGuess(guess.charAt(0));
}

System.out.println("The secret word was: " + secretWord);
if (gameWon()) {
System.out.println("Congratulations, you won!");
} else {
System.out.println("Sorry, you lost.");
printHangman();
}
}

/*
-
*/
public String printCurrentState() {
//Print the Hangman picture
StringBuilder sb = new StringBuilder();
sb.append(printHangman());

//Print the correct guesses in the secret word
for (int i = 0; i < this.correctLetters.size(); i++){
System.out.print(this.correctLetters.get(i) + " ");
sb.append(this.correctLetters.get(i) + " ");}


//Print the incorrect letters that have been guessed
System.out.print("\nWrong letters: ");
sb.append("\nWrong letters: ");
for (int i = 0; i < this.incorrectLetters.size(); i++){
System.out.print(this.incorrectLetters.get(i) + " ");
sb.append(this.incorrectLetters.get(i) + " ");}
return sb.toString();
}


//////////////////////////////////////////////////////////////////////
// 5. PRIVATE INSTANCE METHODS (HELPERS)
//////////////////////////////////////////////////////////////////////

/**
* handleGuess
*
* If the guessed letter (parameter ch) is in the secret word
* then add it to the array list of correct guesses and tell the user
* that the guess was correct;
* otherwise, add the guessed letter to the array list of incorrect
* guesses and tell the user that the guess was wrong.
*
* @param ch the guessed letter
*/


private void handleGuess(char ch) {
boolean chInSecretWord = false;

// go through the secret word character by character
for (int i = 0; i < this.secretWord.length(); i++) {
if (this.secretWord.charAt(i) == ch) { // if ch matches
chInSecretWord = true; // the guess was correct
this.correctLetters.set(i, ch); // update the user's guess
}
}



if (chInSecretWord)
System.out.println("The letter you guessed was correct!");

else { // the character was not in the secret word
this.incorrectLetters.add(ch);
System.out.println("Sorry, that letter is not in the secret word");
}

/////////////////////////
// TODO FILL IN CODE HERE
/////////////////////////
}

/**
* gameWon
*
* Return true if the user has won the game;
* otherwise, return false.
*
* @return true if the user has won, false otherwise
*/
private boolean gameWon() {
boolean won = true; // initially assume the game has been won

if (this.correctLetters.contains('_')) // if there are any '_'
won = false; // the game has not been won

return won;

/////////////////////////
// TODO FILL IN CODE HERE
/////////////////////////

// NOTE: THE LINE BELOW IS SO THE CODE WILL COMPILE
// Replace it with appropriate code for your implementation
//return false;
}

/**
* gameLost
*
* Return true if the user has lost the game;
* otherwise, return false.
*
* @return true if the user has lost, false otherwise
*/
private boolean gameLost() {
return this.incorrectLetters.size() >= 7;

/////////////////////////
// TODO FILL IN CODE HERE
/////////////////////////

// NOTE: THE LINE BELOW IS SO THE CODE WILL COMPILE
// Replace it with appropriate code for your implementation
//return false;
}

/**
* gameOver
*
* Return true if the user has either won or lost the game;
* otherwise, return false.
*
* @return true if the user has won or lost, false otherwise
*/
private boolean gameOver() {
return gameWon() || gameLost();
/////////////////////////
// TODO FILL IN CODE HERE
/////////////////////////

// NOTE: THE LINE BELOW IS SO THE CODE WILL COMPILE
// Replace it with appropriate code for your implementation
//return false;
}

/**
* printHangman
*
* Print the Hangman that corresponds to the given number of
* wrong guesses so far.
*
* @param numWrong number of wrong guesses so far
*/
private String printHangman() {
StringBuilder sb = new StringBuilder();

int poleLines = 6; // number of lines for hanging pole
System.out.println(" ____");
System.out.println(" | |");
sb.append(" ____\n");
sb.append(" | |\n");

int badGuesses = this.incorrectLetters.size();
if (badGuesses == 7) {
System.out.println(" | |");
System.out.println(" | |");
sb.append(" | |\n");
sb.append(" | |\n");
}

if (badGuesses > 0) {
System.out.println(" | O");
poleLines = 5;
sb.append(" | O\n");
}
if (badGuesses > 1) {
poleLines = 4;
if (badGuesses == 2) {
System.out.println(" | |");
sb.append(" | |\n");
} else if (badGuesses == 3) {
System.out.println(" | \\|");
sb.append(" | \\|\n");
} else if (badGuesses >= 4) {
System.out.println(" | \\|/");
sb.append(" | \\|/\n");
}
}
if (badGuesses > 4) {
poleLines = 3;
if (badGuesses == 5) {
System.out.println(" | /");
sb.append(" | /\n");
} else if (badGuesses >= 6) {
System.out.println(" | / \\");
sb.append(" | / \\\n");
}
}
if (badGuesses == 7) {
poleLines = 1;
}

for (int k = 0; k < poleLines; k++) {
System.out.println(" |");
sb.append(" |\n");
}
System.out.println("__|__");
System.out.println();
sb.append("__|__\n");
sb.append("\n");
return sb.toString();
}



//////////////////////////////////////////////////////////////////////
// 6. FOR TESTING PURPOSE ONLY
//////////////////////////////////////////////////////////////////////

/**
* toString
*
* Returns a string representation of the Hangman object.
* Note that this method is for testing purposes only!
* @return a string representation of the Hangman object
*/
public String toString() {
String s = "secret word: " + this.secretWord;

s += "\ncorrect letters: ";
for (int i = 0; i < this.correctLetters.size(); i++)
s += this.correctLetters.get(i) + " ";

s += "\nused letters: ";
for (int i = 0; i < this.incorrectLetters.size(); i++)
s += this.incorrectLetters.get(i) + " ";

s += "\n# bad letters: " + this.incorrectLetters.size();

return s;
}

private void setCurrentWord(String newWord) {
this.secretWord = newWord;
}

private void setCorrectLetters(ArrayList<Character> newGuesses) {
this.correctLetters = newGuesses;
}

private void setIncorrectLetters(ArrayList<Character> newUsedLetters) {
this.incorrectLetters = newUsedLetters;
}

private void setBadGuesses(int newBadGuesses) {
this.incorrectLetters.clear();
for (int i = 0; i < newBadGuesses; i++) {
this.incorrectLetters.add('x');
}
}

//////////////////////////////////////////////////////////////////////
// 7. PUBLIC CLASS METHOD - MAIN
//////////////////////////////////////////////////////////////////////

public static void main(String [] args) {

/* Note initially the constructor sets the secret word to:
* "miscellaneous". Be sure to update the constructor when
* you're ready to play the game.
*/

Hangman game = new Hangman();

/*
* A. Testing the constructor
*
* To test the constructor, we use the toString method
* to see if the data members are as expected.
*/

System.out.println("The CONSTRUCTED game is:\n" + game);
System.out.println("\n======== END CONSTRUCTOR TEST ========\n");
// */

/*
* B. Testing gameWon
*/

if (game.gameWon())
System.out.println("Game should not be won at beginning");

String str = "miscellaneous";
game.setCurrentWord(str);
ArrayList<Character> guesses = new ArrayList<Character>();

for (int i = 0; i < str.length(); i++)
guesses.add(str.charAt(i));
game.setCorrectLetters(guesses);

if (!game.gameWon()) {
System.out.println(game);
System.out.println("Game should be won");
}

for (int i = 0; i < str.length(); i += 3)
guesses.set(i, '_');
game.setCorrectLetters(guesses);

if (game.gameWon()) {
System.out.println(game);
System.out.println("Game should NOT be won");
}

System.out.println("\n======== END gameWon TEST ========\n");
// */

/*
* C. Testing gameLost
*/

game = new Hangman(); // start with a new game

if (game.gameLost())
System.out.println("Game should not be lost at beginning");

game.setBadGuesses(3);
if (game.gameLost()) {
System.out.println(game);
System.out.println("Game should not be lost");
}

game.setBadGuesses(7);
if (!game.gameLost()) {
System.out.println(game);
System.out.println("Game should be lost");
}

game.setBadGuesses(10);
if (!game.gameLost()) {
System.out.println(game);
System.out.println("Game should be lost");
}

System.out.println("\n======== END gameLost TEST ========\n");
// */

/*
* D. Testing gameOver
*
* Add your own similar tests as above.
*/


System.out.println("\n======== END gameOver TEST ========\n");
// */


/*
* E. Testing handleGuess
*/

game = new Hangman(); // start with a new game
System.out.println(game);

game.handleGuess('a'); // check a letter in the word
System.out.println(game);

game.handleGuess('q'); // check a letter not in the word
System.out.println(game);

game.handleGuess('m'); // check for first letter in word
System.out.println(game);

game.handleGuess('l'); // check a letter that appears more than once
System.out.println(game);

game.handleGuess('s'); // check last letter in word
System.out.println(game);

game.handleGuess('x'); // check another letter not in word
System.out.println(game);
System.out.println("\n======== END handleGuess TEST ========\n");
// */

/* F. Test the playGame method
* Do this after all the private methods have been tested.
*/

game = new Hangman(); // start with a new game
game.playGame();
// */
}

}

KnockKnockClient 客户端:

import java.io.*;
import java.net.*;

public class KnockKnockClient {
public static void main(String[] args) throws IOException {

/*
needs two arguments, host name and port number.
*/
if (args.length != 2) {
System.err.println(
"Usage: java EchoClient <host name> <port number>");
System.exit(1);
}

/*
sets port number.
*/
String hostName = args[0];
int portNumber = Integer.parseInt(args[1]);

/*
try resource creates new Socket object with hostname and portnumber to connect to.
*/
try (
Socket kkSocket = new Socket(hostName, portNumber);
PrintWriter out = new PrintWriter(kkSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(kkSocket.getInputStream()));
) {
BufferedReader stdIn =
new BufferedReader(new InputStreamReader(System.in));
String fromServer;
String fromUser;

while ((fromServer = in.readLine()) != null) {
System.out.println("Server: " + fromServer);
if (fromServer.equals("Bye."))
break;

fromUser = stdIn.readLine();
if (fromUser != null) {
System.out.println("Client: " + fromUser);
out.println(fromUser);
}
}
} catch (UnknownHostException e) {
System.err.println("Don't know about host " + hostName);
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to " +
hostName);
System.exit(1);
}
}
}

最佳答案

问题似乎出在这里:

while ((fromServer = in.readLine()) != null) {
System.out.println("Server: " + fromServer);
if (fromServer.equals("Bye."))
break;

fromUser = stdIn.readLine();
if (fromUser != null) {
System.out.println("Client: " + fromUser);
out.println(fromUser);
}
}

简答:

服务器写入多行以显示刽子手,您只读取一行,然后您等待用户输入另一个字符。您应该阅读服务器输入的所有行。为此,请使用 DataInputStream(dis = new DataInputStream(in))包装 BufferedReader,然后使用 dis.readUTF() 获取整个服务器消息。

长答案:

服务器向您发送此字符串:____\n | |\n |\n |\n |\n..... 并且您只读到第一个 \n。阅读整个消息(直到 in.readLine() 为 null 或如上所述使用 DataInputStream)然后要求客户端进行新的猜测。

关于java - 实现客户端-服务器,GUI StringBuilder 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20029923/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com