Почему мне сразу выкидывает окно проигрыша?

Рейтинг: 0Ответов: 1Опубликовано: 27.01.2023

Есть игра в слова (правила думаю всем известный), но есть в ней проблема. А именно в цикле, там слово, которое ты вводишь должно проверятся на правильность (начинается ли моё слово с буквы, на которую заканчивается слово компьютера (здесь слова берутся из текстового документа).

И в этой проверке должно вызываться окно проигрыша, но почему-то когда я ввожу первое слово, мне сразу же выкидывает это окно. Вопрос заключается в том, каким образом цикл попадает в данный блок кода:

if (!IsWordStartWith(word, getLastChar(fileWord))) {
    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()));
        }
    }

}

Я не смог понять назначение некоторых ваших полей и кнопки меню, с этим будете разбираться сами. Также я не уверен, что слова отображаются в нужных окнах, потому что я не знаю, какого результата вы хотели изначально, но не думаю, что это проблема. Посему пробуйте разобраться с такой реализацией и , если возникнут сложности, задавайте вопросы