2
\$\begingroup\$

I wrote my first project in java which is just a simple game where you need to guess title of movie. I'm curious what do you think about it? Could you tell me what i did incorrectly, what would you change, etc. I would appreciate any feedback from you.

public class Main {

    public static void main(String[] args) {

        boolean playAgain;

        do {
            ChoseMovie choseMovie = new ChoseMovie();

            char[] movie = choseMovie.randomChoseMovie();
            char[] dashMovie = choseMovie.dashRandomChoseMovie(movie);

            Game game = new Game(movie, dashMovie);

            playAgain = game.playAgain();

        } while(playAgain);

    }
}

ChoseMovie class deals with chosing movie title from txt file. randomChoseMovie take one title and save it in char array. dashRandomChoseMovie creates clone of that array and change characters to '-' sign.

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;

public class ChoseMovie {

    private ArrayList<String> listOfMovies = new ArrayList<>();

    ChoseMovie() {

        try {
            File moviesFile = new File("movies.txt");
            Scanner readMoviesFile = new Scanner(moviesFile);

            while (readMoviesFile.hasNextLine()){
                listOfMovies.add(readMoviesFile.nextLine());
            }

            readMoviesFile.close();

        } catch (FileNotFoundException e) {
            System.out.println("An internal error occurred! Please try again later.");
        }

    }

    public char[] randomChoseMovie() {
        return listOfMovies.get((int) (Math.random() * listOfMovies.size())).toCharArray();

    }

    public char[] dashRandomChoseMovie(char[] RandomChoseMovie) {
        char[] dashChosenMovie = RandomChoseMovie.clone();

        for (int i = 0; i < RandomChoseMovie.length; i++) {
            if (Character.toString(dashChosenMovie[i]).matches("[a-zA-Z0-9]")) {
            dashChosenMovie[i] = '-';
        }
    }

        return dashChosenMovie;

    }

}

Game class contains logic of the game. First ask user to type only one letter or number, check if it's correct and change '-' signs to this character in dashMovie array. If you make mistake increment mistakes variable, after 5 mistakes you will lose. if in dashMovie array there won't be any '-' sign you will win.

import java.util.ArrayList;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.Scanner;

public class Game {

    private Scanner readUserInput;
    private char[] movie;
    private char[] dashMovie;
    private ArrayList<Character> wrongCharacters = new ArrayList<>();
    private int mistakes = 0;

    Game(char[] movie, char[] dashMovie) {

        readUserInput = new Scanner(System.in);
        String userChar;
        this.movie = movie;
        this.dashMovie = dashMovie;

        System.out.println("Guess title of the movie by typing a letter or a number.");
        System.out.println("You can make 5 mistakes.");

        do {

            System.out.println("The title of the movie is:");
            System.out.println(this.dashMovie);
            System.out.println("You have made (" + mistakes + "/5) mistakes");
            System.out.println("Wrong characters: " + wrongCharacters);

            userChar = readUserInput.next();

            if (userChar.matches("[a-zA-Z0-9]")) {
                char singleChar = Character.toLowerCase(userChar.charAt(0));
                compareAndChange(singleChar);
            }
            else System.out.println("It's not a single letter or digit. Try again.");

           if (!containsDash()) break;

        } while(mistakes < 5);

        if(mistakes != 5) System.out.println("You win! The movie is: " + new String(this.movie));
        else System.out.println("You lose! You have made 5 mistakes. The movie is: " + new String(this.movie));

    }

    private void compareAndChange(char userChar){

       int charOccurrence = 0;

       for (int i = 0; i < movie.length; i++) {

            if (movie[i] == userChar) {
                dashMovie[i] = userChar;
                charOccurrence++;
            }

        }

        addWrongCharacters(charOccurrence, userChar);

    }

    private void addWrongCharacters(int charOccurrence, char userChar) {
        if (charOccurrence == 0 && !wrongCharacters.contains(userChar)) {
            wrongCharacters.add(userChar);
            mistakes++;
        }

    }

    private boolean containsDash() {
        return Arrays.toString(dashMovie).contains("-");

    }

    public boolean playAgain() {

        readUserInput = new Scanner(System.in);
        int userInput;
        boolean playAgain = false;

        System.out.println("Do you want to play again?");
        System.out.println("1. Yes");
        System.out.println("2. No");

        try {
            userInput = readUserInput.nextInt();
            if (userInput == 1) playAgain = true;
            else if (userInput == 2) playAgain = false;
            else {
                System.out.println("Type 1 to play again or 2 to exit.");
                playAgain();
            }

        } catch (InputMismatchException e) {
            System.out.println("Type 1 to play again or 2 to exit.");
            playAgain();
        }

        return playAgain;

    }

}    

movies.txt file contains titles of movies you can guess in game

the shawshank redemption
the godfather
the dark knight
schindler's list
pulp fiction
the lord of the rings
the good the bad and the ugly
fight club
the lord of the rings
forrest gump
star wars
inception
the lord of the rings
the matrix
samurai
star wars
city of god
the silence of the lambs
batman begins
die hard
chinatown
room
dunkirk
fargo
no country for old men

Here's link to this project on my GitHub: https://github.com/wolak041/GuessTHEMovie

\$\endgroup\$
1
\$\begingroup\$

Initial question: Why do you use char[] arrays instead of String?

In main I would have initialised the variable and then used a while-loop:

boolean startNewGame = true;
while (startNewGame)
{
    // several lines of your code 
    startNewGame = game.playAgain()
}

The argument mame shouldn't be capitalized in

public char[] dashRandomChoseMovie(char[] randomChoseMovie) {
    String chosenMovie = new String(randomChoseMovie);
    String dashChosenMovie = chosenMovie.replaceAll("[a-zA-Z0-9]", "-");
    // Did you want to replace any char by a dash? 
    // In schindler's list ' wouldn't be replaced. 
    // This could be fixed by using
    //String dashChosenMovie = chosenMovie.replaceAll(".", "-");

    return dashChosenMovie.toCharArray();
}

If you use char[] you can also search in the array

private boolean containsDash() {
    return Arrays.binarySearch(dashMovie, '-') >= 0;
}

Further I would avoid the recursion in playAgain in case of invalid user input:

while (true) {
    Scanner readUserInput = new Scanner(System.in);
    try {               
        int userInput = readUserInput.nextInt();
        if (userInput == 1) return true;
        if (userInput == 2) return false;
        System.out.println("Type 1 to play again or 2 to exit.");
    } catch (InputMismatchException e) {
        System.out.println("Type 1 to play again or 2 to exit.");
    }
} // while(true)
\$\endgroup\$
  • \$\begingroup\$ Thank you for your comment. I changed those char arrays to Strings. I used arrays becouse it was my first idea how to write it but now i see that using Strings is shorter. That argument name was just a typo. binarySearch did't work, after few guessed characters game was over though there was few letters to guess. Last, i changed the playAgain method as you wrote. \$\endgroup\$ – wolak041 Feb 24 '18 at 19:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.