基于 24 小时时间重置的逻辑和变量的 Java 程序问题

Java Program issue with 24 hour time reset based logic and variables

提问人:Rory Steuart 提问时间:9/28/2023 更新时间:9/28/2023 访问量:40

问:

我正在创建一个基本的 java 程序,它是命令行中的 Wordle 克隆。我的主要问题是能够允许玩家每天最多玩 10 场比赛,重置 24 个荷鲁斯。出于某种原因,在我当前的代码中,它看不到带有 gamesPlayedToday 变量的 maxGamesPlayed,这使得它只允许我玩 1 个游戏而不是 10 个游戏。任何帮助将不胜感激。

主 Commandle 类:


import java.io.*;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;

public class Commandle {
    public static final int MAX_TRIES = 6;
    public static final int MAX_DAILY_GAMES = 10;
    public static final Duration DAY_DURATION = Duration.ofDays(1); // 24 hours duration
    private static final String TIMESTAMP_FILE = "lastGameTimestamp.txt";

    private static int gamesPlayedToday = 0;
    private static LocalDateTime lastGameTimestamp = LocalDateTime.MIN;


    public static void main(String[] args) throws IOException {
        initializeLastGameTimestamp();
        start(System.in, System.out, args);
    }

    // Initialize last game timestamp from the file or set to current time if the file doesn't exist
    private static void initializeLastGameTimestamp() {
        try {
            File file = new File(TIMESTAMP_FILE);
            if (file.exists()) {
                BufferedReader reader = new BufferedReader(new FileReader(file));
                String timestampString = reader.readLine();
                if (timestampString != null) {
                    lastGameTimestamp = LocalDateTime.parse(timestampString, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
                    reader.close();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void saveLastGameTimestamp() {
        try {
            File file = new File(TIMESTAMP_FILE);
            BufferedWriter writer = new BufferedWriter(new FileWriter(file));
            writer.write(lastGameTimestamp.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void start(InputStream in, PrintStream out, String[] args) throws IOException {
        initializeLastGameTimestamp();
        String dictionaryFileName = "testdictionary.txt";
        if (null != args && args.length > 0) {
            dictionaryFileName = args[0];
        }

        List<String> wordList = getWordList(dictionaryFileName);
        start(in, out, wordList);
    }

    public static void start(InputStream in, PrintStream out, List<String> wordList) throws IOException {
        Scanner scanner = new Scanner(in);

        while (true) {
            if (!canPlayGame()) {
                break;
            }

            if (gamesPlayedToday >= MAX_DAILY_GAMES) {
                out.println("You have reached the maximum number of games for today.");
                break;
            }

            GameBoard gameBoard = new GameBoard(wordList);
            gameBoard.startGame();

            out.println("Games played today: " + gamesPlayedToday); // Moved inside the game loop

            boolean result = playOneGame(out, MAX_TRIES, gameBoard, scanner);
            if (result) {
                out.println("Congratulations, you won!");
            } else {
                out.println("Sorry, you lost!");
            }

            out.println("Play again? (Y/N)");

            if (!"Y".equalsIgnoreCase(scanner.nextLine().trim())) {
                break;
            }

            gamesPlayedToday++;
        }

        out.println("See you next time!");

        scanner.close();
    }

    private static boolean canPlayGame() {
        LocalDateTime currentTime = LocalDateTime.now();
        long hoursBetween = ChronoUnit.HOURS.between(lastGameTimestamp, currentTime);

        if (hoursBetween >= 24) {
            lastGameTimestamp = currentTime;
            saveLastGameTimestamp();
            gamesPlayedToday = 0; // Reset games played for a new day
        } else if (gamesPlayedToday >= MAX_DAILY_GAMES) {
            System.out.println("You have reached the maximum number of games for today.");
            return false;
        } else if (hoursBetween < 24) {
            System.out.println("You must wait for 24 hours before starting a new game.");
            return false;
        }

        return true;
    }


    private static List<String> getWordList(String dictionaryFileName) throws IOException {
        List<String> wordList = new ArrayList<>();
        try (InputStream inputStream = Commandle.class.getClassLoader().getResourceAsStream(dictionaryFileName);
             InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
             BufferedReader br = new BufferedReader(inputStreamReader)) {

            String line;
            while ((line = br.readLine()) != null) {
                wordList.add(line.trim().toLowerCase());
            }
        }
        return wordList;
    }


    private static String getNextValidGuess(Scanner scanner, Set<String> guesses, GameBoard gameBoard) {
        String guess = scanner.nextLine().trim().toLowerCase();

        if (guess.length() != 5) {
            System.err.print("Please enter a word of 5 letters: ");
        } else if (guesses.contains(guess)) {
            System.err.print("Please enter a new word: ");
        } else if (!gameBoard.containsWord(guess)) {
            System.err.print("Please enter a valid word: ");
        } else {
            guesses.add(guess);
            return guess;
        }
        return getNextValidGuess(scanner, guesses, gameBoard);
    }

    private static boolean playOneGame(PrintStream out, int rounds, GameBoard gameBoard, Scanner scanner) {
        if (gamesPlayedToday >= MAX_DAILY_GAMES) {
            out.println("You have reached the maximum number of games for today.");
            return false;
        }

        Set<String> guesses = new HashSet<>();

        for (int i = 0; i < rounds; i++) {
            out.print("Please enter your guess: ");
            String guess = getNextValidGuess(scanner, guesses, gameBoard);

            GameBoard.Status[] result = gameBoard.isInTarget(guess.toLowerCase().toCharArray());
            String hint = "";
            for (int j = 0; j < result.length; j++) {
                switch (result[j]) {
                    case correct -> hint += guess.charAt(j);
                    case wrong -> hint += "#";
                    case partial -> hint += "?";
                }
            }
            int round = i + 1;
            out.println(round + ": " + guess + "  " + round + ": " + hint);
            if (gameBoard.hasWon(result)) {
                return true;
            }
        }
        return false;
    }
}

我认为问题出在 canPlayGame 逻辑中,一旦玩完游戏,它就没有看到正确引用这一点。Java 不是我的主要语言,所以我有点难以理解为什么这不起作用。

 private static boolean canPlayGame() {
        LocalDateTime currentTime = LocalDateTime.now();
        long hoursBetween = ChronoUnit.HOURS.between(lastGameTimestamp, currentTime);

        if (hoursBetween >= 24) {
            lastGameTimestamp = currentTime;
            saveLastGameTimestamp();
            gamesPlayedToday = 0; // Reset games played for a new day
        } else if (gamesPlayedToday >= MAX_DAILY_GAMES) {
            System.out.println("You have reached the maximum number of games for today.");
            return false;
        } else if (hoursBetween < 24) {
            System.out.println("You must wait for 24 hours before starting a new game.");
            return false;
        }

        return true;
    }
变量 命令行 java-time

评论

3赞 Matteo NNZ 9/28/2023
要读取的代码很多,但乍一看,您只是在读取文件中找到的第一个时间戳,而不是最后一个时间戳。
0赞 maloomeister 9/28/2023
在你里面很可能是问题所在。因为这会在一轮后返回,即使这一天还有游戏要玩。您可能需要考虑是否只想在一个会话中只允许当天的游戏数量,或者您还必须像存储时间戳一样存储今天玩的游戏数量。else if (hoursBetween < 24)canPlayGame()false
0赞 Reilas 9/28/2023
“......它只让我玩 1 场比赛而不是 10 场比赛。...“,如果我运行代码,它只是递归调用 getNextValidGuess

答: 暂无答案