Вопрос по циклу, пропускает определенный участок кода
Есть игра в слова(правила думаю всем известный) ,но есть в ней проблема, а именно в цикле, там слово которое ты вводишь должно проверятся на правильность(начинается ли мое слово с буквы на которую заканчивается слово компьютера(здесь слова берутся из текстового документа) и в этой проверке должно вызываться окно проигрыша) , но почему то когда я ввожу первое слово, мне сразу же выкидвает это окно, вопрос заключается в том, каким образом цикл попадает в данный блок кода
new RussianLose();
return ("" + score);//первая буква не подходит
}
Вот код
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class Russian extends JFrame implements ActionListener {
JFrame frame = new JFrame("Игра в слова");
JTextField myword = new JTextField();
JTextField fileword = new JTextField();
JTextField information = new JTextField();
JTextField score1 = new JTextField();
JButton button =new JButton("Ответить");
JButton button1 = new JButton("Меню");
JLabel MYWORD = new JLabel("Введите ваше слово");
JLabel SCORE = new JLabel("Счёт");
public static void main(String[] args) throws IOException {
new Russian();
}
Russian(){
frame.setLayout(null);
frame.setVisible(true);
frame.getContentPane().setBackground(new Color(145,23,193));
frame.setResizable(false);
ImageIcon image = new ImageIcon(
"icons8-ps-controller-30.png");
frame.setIconImage(image.getImage());
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
JLabel game = new JLabel("Игра в слова");
game.setBounds(570,100,500,50);
game.setFont(new Font("Verdana", Font.TYPE1_FONT, 50));
frame.add(game);
myword.setBounds(500,250,500,100);
myword.setFont(new Font("Verdana", Font.PLAIN, 50));
myword.setBackground(new Color(0xFFFFFFFF, true));
frame.add(myword);
MYWORD.setBounds(600,320,400,100);
MYWORD.setFont(new Font("Verdana", Font.PLAIN, 30));
SCORE.setBounds(1300,50,100,50);
SCORE.setFont(new Font("Verdana", Font.PLAIN, 30));
frame.add(SCORE);
frame.add(MYWORD);
fileword.setBounds(500,430,500,100);
fileword.setFont(new Font("Verdana", Font.PLAIN, 50));
fileword.setBackground(new Color(0xFFFFFFFF, true));
fileword.setEditable(false);
frame.add(fileword);
information.setBounds(500,560,500,100);
information.setFont(new Font("Verdana", Font.PLAIN, 30));
information.setBackground(new Color(0xFFFFFFFF, true));
information.setEditable(false);
frame.add(information);
score1.setBounds( 1400,50,50,50);
score1.setFont(new Font("Verdana", Font.PLAIN, 20));
score1.setEditable(false);
frame.add(score1);
button.setBounds(600,700,300,100);
button.setFont(new Font("Verdana", Font.PLAIN, 20));
button.setBackground(new Color(225, 192, 192));
button.addActionListener(this);
frame.add(button);
button1.setBounds(50,50,100,50);
button1.setBackground(new Color(225, 192, 192));
button1.setFont(new Font("Verdana", Font.PLAIN, 20));
frame.add(button1);
button1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
frame.setVisible(false);
new MainFrame();
}
});
}
long score = 0;
Scanner scanner = null;
Scanner in = null;
File file = new File("russian_nouns.txt");
private final Set<String> repeatedWords = new HashSet<>();
public String run(String word) throws FileNotFoundException {
String fileWord;
while (true) {
if (isInputedWordCorrect(word) && !isWordInListOfRepeat(word)) {// проверка введенного слова на корректность и повтор
score++;//после каждого введенного слова прошедшего условия добавляется +1 в счет
addToListOfRepeat(word); //добавляет введенное слово в список повторов
fileWord = getWordFromFileOnChar(getLastChar(word));//ищет слово на заданную букву в файле
if (fileWord.isEmpty()) {//если слова в списке на данную букву закончились функция вернет ""
new RussianWin();
frame.setVisible(false);
JOptionPane.showMessageDialog(frame, "Ваш счет "+score);
return ("" + score);//слова в списке на данную букву закончлись
} else {
if(IsWordStartWith(word, getLastChar(fileWord))) {
fileword.setText(fileWord);
addToListOfRepeat(fileWord);
word = inputWord(getLastChar(fileWord));//пользователь вводит слово
}
if (!IsWordStartWith(word, getLastChar(fileWord))) {
new RussianLose();
return ("" + score);//первая буква не подходит
}
}
} else {
frame.setVisible(false);
new RussianLose();
JOptionPane.showMessageDialog(frame, "Ваш счет "+score);
return ("" + score);//слово либо уже было, либо его нет в списке
}
}
}
boolean IsWordStartWith(String word, char firstChar) {//проверяет начинается ли слово с заданной буквы
return word.charAt(0) == firstChar;
}
String getWordFromFileOnChar(char firstChar) throws FileNotFoundException {//ищет в списке слово, начинающееся с заданной букввы(также отсеивает повторы)
scanner = new Scanner(file);
String word = "";
while (scanner.hasNextLine()) {
word = scanner.nextLine();
if (IsWordStartWith(word, firstChar) && !isWordInListOfRepeat(word)) {//слово которое начинает с новой буквы и не повторяется
break;
}
}
if (IsWordStartWith(word, firstChar) && !isWordInListOfRepeat(word)) {//если цикл выше не находит подходящего слова, он остановится на последнем в списке, поэтому еще одна проверка
scanner.close();
return word;
} else {
scanner.close();
return "";
}
}
boolean isWordInListOfRepeat(String word) {//есть ли слово в списке тех, которые уже были
return repeatedWords.contains(word);
}
void addToListOfRepeat(String word) {
repeatedWords.add(word);
}
char getLastChar(String word) {
return word.charAt(word.length() - 1);
}
String inputWord(char firstChar) {
information.setText("Введеите слово на букву " + firstChar);
in = new Scanner(System.in, StandardCharsets.UTF_8);
return myword.getText();
}
boolean isInputedWordCorrect(String inputedWord) throws FileNotFoundException {//проверяет есть ли слово в списке(существует ли такое слово)
scanner = new Scanner(file);
while (scanner.hasNextLine()) {
String nextWord = scanner.nextLine();
if (nextWord.equals(inputedWord)) {
scanner.close();
return true;
}
}
scanner.close();
information.setText("Неправильное слово");
new RussianLose();
frame.setVisible(false);
return false;
}
@Override
public void actionPerformed(ActionEvent e) {
String s1 = myword.getText();
try {
score1.setText(run(s1));
myword.setText("");
} catch (FileNotFoundException ex) {
throw new RuntimeException(ex);
}
}
}
Ответы (1 шт):
Могу вам точно ответить на один вопрос: почему так долго вы не получили ответа? Ответ простой: этот код - полный треш. По этой причине разбираться в нем никто не хочет. Столь тривиальную задачу, как поиск слова по первой букве, вы умудрились превратить в огромное полотно кода со множеством вложений, в котором разобраться практически невозможно. Главное в коде - его читаемость. Посему пробуйте так:
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.text.JTextComponent;
public class Russian extends JFrame implements ActionListener {
private final String fileName = "russian_nouns.txt";
private Map<Character, Set<String>> allWords = new HashMap<>();
private Set<String> repeatedWords = new HashSet<>();
private long score = 0;
private final JFrame frame = new JFrame("Игра в слова");
private final JTextField myword = new JTextField();
private final JTextField fileword = new JTextField();
private final JTextField information = new JTextField();
private final JTextField score1 = new JTextField("0");
private final JButton button = new JButton("Ответить");
private final JButton button1 = new JButton("Меню");
private final JLabel MYWORD = new JLabel("Введите ваше слово");
private final JLabel SCORE = new JLabel("Счёт");
public static void main(String[] args) throws IOException {
new Russian();
}
private Russian() throws IOException {
frame.setLayout(null);
frame.setVisible(true);
frame.getContentPane().setBackground(new Color(145, 23, 193));
frame.setResizable(false);
frame.setIconImage(new ImageIcon("icons8-ps-controller-30.png").getImage());
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
JLabel game = new JLabel("Игра в слова");
game.setBounds(570, 100, 500, 50);
game.setFont(new Font("Verdana", Font.TYPE1_FONT, 50));
frame.add(game);
myword.setBounds(500, 250, 500, 100);
myword.setFont(new Font("Verdana", Font.PLAIN, 50));
myword.setBackground(new Color(0xFFFFFFFF, true));
frame.add(myword);
MYWORD.setBounds(600, 320, 400, 100);
MYWORD.setFont(new Font("Verdana", Font.PLAIN, 30));
SCORE.setBounds(1300, 50, 100, 50);
SCORE.setFont(new Font("Verdana", Font.PLAIN, 30));
frame.add(SCORE);
frame.add(MYWORD);
fileword.setBounds(500, 430, 500, 100);
fileword.setFont(new Font("Verdana", Font.PLAIN, 50));
fileword.setBackground(new Color(0xFFFFFFFF, true));
fileword.setEditable(false);
frame.add(fileword);
information.setBounds(500, 560, 500, 100);
information.setFont(new Font("Verdana", Font.PLAIN, 30));
information.setBackground(new Color(0xFFFFFFFF, true));
information.setEditable(false);
frame.add(information);
score1.setBounds(1400, 50, 50, 50);
score1.setFont(new Font("Verdana", Font.PLAIN, 20));
score1.setEditable(false);
frame.add(score1);
button.setBounds(600, 700, 300, 100);
button.setFont(new Font("Verdana", Font.PLAIN, 20));
button.setBackground(new Color(225, 192, 192));
button.addActionListener(this);
frame.add(button);
button1.setBounds(50, 50, 100, 50);
button1.setBackground(new Color(225, 192, 192));
button1.setFont(new Font("Verdana", Font.PLAIN, 20));
frame.add(button1);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
allWords = readFile(fileName);
// button1.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// frame.setVisible(false);
// //new MainFrame();
// }
// });
}
@Override
public void actionPerformed(ActionEvent e) {
run(myword.getText(), fileword.getText());
setText(myword, "");
}
public void run(String word, String previosWord) {
if (!isWordStartWith(word, getLastChar(previosWord)) || !isWordAvailiable(word)) {
endGame("Неправильное слово. Вы проиграли!");
return;
}
setText(score1, ++score);
Optional<String> result = getWordOnChar(getLastChar(word));
if (result.isPresent()) setText(fileword, result.get());
else endGame("Вы победили!");
}
private void setText(JTextComponent component, Object arg) {
component.setText(String.valueOf(arg));
}
//проверяет начинается ли слово с заданной буквы
private boolean isWordStartWith(String word, Character firstChar) {
return firstChar == null ? true : word.charAt(0) == firstChar;
}
private Character getLastChar(String word) {
return (word==null || word.isEmpty()) ? null : word.charAt(word.length() - 1);
}
//ищет в списке слово, начинающееся с заданной букввы(также отсеивает повторы)
private Optional<String> getWordOnChar(char firstChar) {
Optional<String> findWord = Optional.ofNullable(allWords.get(firstChar))
.map(words -> words.stream().filter(word -> !repeatedWords.contains(word)).findAny())
.orElseGet(Optional::empty);
findWord.ifPresent(word -> repeatedWords.add(word));
return findWord;
}
private boolean isWordAvailiable(String word) {
Boolean isExist = Optional.ofNullable(allWords.get(word.charAt(0)))
.map(words -> words.contains(word))
.orElse(false);
if (!isExist || repeatedWords.contains(word)) return false;
repeatedWords.add(word);
return true;
}
private void endGame(String args) {
System.out.println(args);
System.out.println("Ваш счет : " + score);
JOptionPane.showMessageDialog(frame, args + " Ваш счет :" + score);
frame.setVisible(false);
frame.dispose();
}
private HashMap<Character, Set<String>> readFile(String fileName) throws IOException {
try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
return stream.collect(Collectors.groupingBy(s -> s.charAt(0), HashMap::new, Collectors.toSet()));
}
}
}
Я не смог понять назначение некоторых ваших полей и кнопки меню, с этим будете разбираться сами. Также я не уверен, что слова отображаются в нужных окнах, потому что я не знаю, какого результата вы хотели изначально, но не думаю, что это проблема. Посему пробуйте разобраться с такой реализацией и , если возникнут сложности, задавайте вопросы