3
\$\begingroup\$

This is a simple "Choose a number between 0-9" Game. It works perfectly but I'd like to know if there's a way to make my code smaller with the exact same functionality.

package firstGame;

    import java.util.Scanner;

    public class Player {

        static Scanner p2Name = new Scanner(System.in);
        static Scanner p1Name = new Scanner(System.in);
        static Scanner p3Name = new Scanner(System.in);

        static Scanner p1Num = new Scanner(System.in);
        static Scanner p2Num = new Scanner(System.in);
        static Scanner p3Num = new Scanner(System.in);

        String name;
        int age;
        int size;

        public static void main(String[] args) {




            // Create a random number generator (0-9)
            int number = (int) (Math.random() * 10);

            // Get Player1's name
            System.out.print("Player 1, please enter your name : ");
            String p1 = p1Name.nextLine();
            System.out.println("Welcome " + p1 + "!");

            // Get Player1's chosen number
            System.out.println("Please enter a number between 0 and 9");
            int p1Choice = p1Num.nextInt();
            System.out.println("");

            // Get Player2's name
            System.out.print("Player 2, please enter your name : ");
            String p2 = p2Name.nextLine();
            System.out.println("Welcome " + p2 + "!");

            // Get Player2's chosen number
            System.out.println("Please enter a number between 0 and 9");
            int p2Choice = p2Num.nextInt();
            System.out.println("");

            // Get Player3's name
            System.out.print("Player 3, please enter your name : ");
            String p3 = p3Name.nextLine();
            System.out.println("Welcome " + p3 + "!");

            // Get Player3's chosen number
            System.out.println("Please enter a number between 0 and 9");
            int p3Choice = p3Num.nextInt();
            System.out.println("");

            //Output generated number
            System.out.println("The number I was thinking of was : " + number);

            //if 1 player wins, output this
            if (number == p1Choice || number == p2Choice || number == p3Choice) {
                System.out.println("We have a winner!");
            }

            //Player1 won or lost?
            if (number == p1Choice) {
                System.out.println(p1 + " won!");
            } else {
                System.out.println(p1 + ", you lose!");
            }

            //Player2 won or lost?
            if (number == p2Choice) {
                System.out.println(p2 + " won!");
            } else {
                System.out.println(p2 + ", you lose!");
            }

            //Player3 won or lost?
            if (number == p3Choice) {
                System.out.println(p3 + " won!");
            } else {
                System.out.println(p3 + ", you lose!");
            }

        }

    }
\$\endgroup\$
0

2 Answers 2

4
\$\begingroup\$
        static Scanner p2Name = new Scanner(System.in);
        static Scanner p1Name = new Scanner(System.in);
        static Scanner p3Name = new Scanner(System.in);

        static Scanner p1Num = new Scanner(System.in);
        static Scanner p2Num = new Scanner(System.in);
        static Scanner p3Num = new Scanner(System.in);

You don't need all those scanners. One is plenty.

        static Scanner scanner = new Scanner(System.in);

Then replace each call using one of the other variables with scanner.

It's possible that you may have to call scanner.nextLine() after calling scanner.nextInt(). I haven't tried it.

@BKSpurgeon in Java

Here's the @BKSpurgeon solution converted to Java:

Program.java

class Program {

    public static void main(String[] args) {
        GameMaster g = new GameMaster(3);
        g.printResults();
    }

}

Player.java

class Player {

    static Scanner scanner = new Scanner(System.in);

    private String name;       
    private int number;

    public Player(int playerPosition) {
        name = inputName(playerPosition);
        printName();
        number = inputNumber();
        //scanner.nextLine(); // uncomment if needed
    }

    private void printName() {
        System.out.println("Welcome "+ name + "!");
    }

    private int inputNumber() {
        System.out.println("Please enter a number between 0 and 9");

        return scanner.nextInt();
    }

    private String inputName(int playerPosition) {
        System.out.println("Player " + playerPosition + ", please enter your name");

        return scanner.nextLine();
    }

    public String calculateResult(int winningNumber) {
        return name + ((winningNumber == number) ? " won!" : ", you lose!");
    }

}

GameMaster.java

public class GameMaster {

    private final int winningNumber;
    private final List<Player> players = new ArrayList<>();

    public GameMaster(int playerCount) {
        winningNumber = chooseWinningNumber();

        for (int i = 1; i <= playerCount; i++) {
            players.add(new Player(i));
        }
    }

    public void printResults() {
        for (Player p : players) {
            System.out.println(p.calculateResult(winningNumber));
        }
    }

    private static int chooseWinningNumber() {
        return (int) (Math.random() * 10);
    }

}

I made a few tweaks to comply with Java coding conventions, but the structure is mostly the same.

I haven't tried to run it, so beware of typos, etc.

\$\endgroup\$
3
\$\begingroup\$

The first issue I see with the code is that there is a lot of (needless) repetition.

• All the players are being asked to enter a name: the code to do this need only be written once, in one place.

• Same issue with number: enter and storage code need only be done once.

• We can store that functionality in a Player class – so every time we create a player it does those same repetitive things. But each player might choose a different number. So that unique value should be saved within an instance of a player class.

• The issue about winning/losing can be taken care of by a GameMaster.

Normally i'd go with TDD but i thought i could do it faster without it. it's worth noting how most of the duplication is eliminated. a die hard OOP might say: but you have conditionals in your PrintResults method!! they'd be right too, but it's probably a lot simpler to leave it in there.

I hope this helps you. From your point of view it's well worth redoing it with TDD (test driven development). btw it's a c#. i know you wrote in Java but who can really tell the difference between the two anyways?

    class Program
    {
        static void Main(string[] args)
        {
            GameMaster g = new GameMaster();
            g.PrintResults();
        }
    }

 class Player
    {
        private string _name;       

        private int winningNumber;

        private int _number;

        public Player(int playerPosition, int winningNumber)
        {
            this.winningNumber = winningNumber;

            _name = GetName(playerPosition);
            PrintName();
            _number = GetNumber();            
        }

        private void PrintName()
        {
            Console.WriteLine("Welcome "+ _name + "!");
        }

        /// <summary>
        /// Gets player's number choice. Note that I have not added
        /// any exception handling. What if a player decides to choose 11?
        /// that is outside the acceptable boundary. There is currently
        /// no way to handle this.
        /// </summary>
        /// <returns></returns>
        private int GetNumber()
        {
            Console.WriteLine("Please enter a number between 0 and 9");
            int _number = Convert.ToInt32(Console.ReadLine());

            return _number;
        }

        private string GetName(int playerPosition)
        {
            Console.WriteLine("Player " + playerPosition + "Please enter your name");
            string name = Console.ReadLine();

            return name;
        }

        public void PrintResult()
        {
            if (this.winningNumber == _number)
            {
                Console.WriteLine(_name + " won!");

            }
            else
            {
                Console.WriteLine(_name + ", you lose!");
            }

            Console.ReadLine();
        }
    }

public class GameMaster
    {
        int winningNumber;

        List<Player> players;

        public GameMaster()
        {
            // get winning number
            this.winningNumber = GetWinningNumber();
            this.players = GetPlayers();
        }

        public void PrintResults()
        {
            foreach (Player p in players)
            {
                p.PrintResult();
            }
        }

        private List<Player> GetPlayers()
        {
            List<Player> players = new List<Player>();

            for (int i = 1; i < 4; i++)
            {
                Player a = new Player(i, winningNumber);
                players.Add(a);
            }

            return players;
        }

        private int GetWinningNumber()
        {
            Random rnd = new Random();
            int number = rnd.Next(0, 10);
            return number;
        }
    }
\$\endgroup\$
3
  • \$\begingroup\$ Wow, very informative, thank you! Seeing this from another dev's eyes really helps. I'll train a bit more and learn how to enhance my TDD skills. Thanks again :) \$\endgroup\$
    – Crypto
    May 2, 2017 at 3:55
  • 1
    \$\begingroup\$ @Crypto I've deleted the public properties seeing we don't actually use it. \$\endgroup\$
    – BenKoshy
    May 2, 2017 at 4:00
  • \$\begingroup\$ I don't fully understand c# though. I understood your main concerns that you pointed out but the code confuses me a bit. Maybe I should have started learning c# before Java haha. I'll wait for a Java modification for now but thank you so much for the help \$\endgroup\$
    – Crypto
    May 2, 2017 at 4:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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