10
\$\begingroup\$

I recently developed an interest in AI and thought I would develop this little chat bot. Are there any recommendations/modifications?

import java.io.*; import java.util.*; import java.lang.*; public class Conversate{ private static String name; public Conversate(String name){ this.name=name; } public static int randomWithRange(int min, int max){ int range = Math.abs(max - min) + 1; return (int)(Math.random() * range) + (min <= max ? min : max); } public static void main (String []arg){ System.out.println("Hello I'm Ella! and you are?"); Scanner in = new Scanner(System.in); String namer = in.nextLine(); namer.trim(); if (namer.length()>15){ System.out.println("Your name is kinda long isn't it!"); } System.out.println("and your last name is?"); Scanner in2 = new Scanner(System.in); String namer2 = in2.nextLine(); namer2.trim(); System.out.println("are you a boy or a girl?"); Scanner in3 = new Scanner(System.in); String gender = in3.nextLine(); char gen = 'f'; if (gender.equalsIgnoreCase("boy") || gender.equalsIgnoreCase("man") || gender.equalsIgnoreCase("guy") || gender.equalsIgnoreCase("m") || gender.equalsIgnoreCase("male") ){ gen = 'm'; System.out.println("oooo...Macho Macho!, Look at you!"); System.out.println("ELLA BLOWS YOU A KISS!"); System.out.println("lol!! I'm a girl.... I guess you can tell."); }else if (gender.equalsIgnoreCase("girl") || gender.equalsIgnoreCase("woman") || gender.equalsIgnoreCase("lady") || gender.equalsIgnoreCase("f") || gender.equalsIgnoreCase("female") ){ gen = 'f'; System.out.println("OH YEAH!!! GIRL POWER!!!"); }else { System.out.println("Your answer is not quite clear..."); System.out.println("I'll decide what you are"); try{ Thread.sleep(3000); }catch (InterruptedException ex){ Thread.currentThread().interrupt(); } System.out.println("You are a Human BeanStalk! ha ha ha ha!"); } Person ppl = new Person(namer,namer2, gen); System.out.println("How old or young are you?"); int ager = in3.nextInt(); ppl.setAge(ager); if (ppl.known()) { System.out.println("HI "+namer+"! Good to see you again!"); }else{ System.out.println("I don't think we have met before"); try{ ppl.savePerson("ella.txt"); }catch (IOException e ){ System.out.println(e); } } feelings(); if (namer.equalsIgnoreCase("Ella")){ System.out.println("oh wow! that's my name too!"); }else System.out.println("Pleased to meet you"); System.out.println("em... "+namer +"? wouldn't you like to know how I am?"); String resp = in.nextLine(); if (resp.equalsIgnoreCase("No") || resp.equalsIgnoreCase("Nope") || resp.equalsIgnoreCase("n") || resp.equalsIgnoreCase("Not")){ System.out.println("FINE! then go away!"); System.exit(0); }else if (resp.equalsIgnoreCase("maybe")){ System.out.println(namer+(" it's not a hard question is it?? ... have a good think about it for a few seconds!")); try{ Thread.sleep(10000); }catch (InterruptedException ex){ Thread.currentThread().interrupt(); } System.out.println("...Good! Now I'm sure you want to know how if feel so I'll tell you!"); }else if(resp.equalsIgnoreCase("Yes") || resp.equalsIgnoreCase("ok") || resp.equalsIgnoreCase("Sure") || resp.equalsIgnoreCase("Y") || resp.equalsIgnoreCase("yep")){ System.out.println("Oh you are too kind!"); try{ Thread.sleep(2000); }catch (InterruptedException ex){ Thread.currentThread().interrupt(); } try{ File file = new File("resp.txt"); BufferedReader reader = new BufferedReader(new FileReader(file)); String ln = reader.readLine(); List<String> lines = new ArrayList<String>(); while(ln != null){ lines.add(ln); ln = reader.readLine(); } Random r = new Random(); System.out.println(namer+" "+lines.get(r.nextInt(lines.size()))); }catch (IOException e){ e.printStackTrace();} int rrepB = randomWithRange(0,2); System.out.println(namer +" So how are you today?"); String rrsp = in.nextLine(); try{ FileWriter write = new FileWriter("resp.txt",true); PrintWriter prt = new PrintWriter(write); prt.printf("%s" + "%n", rrsp); prt.close(); }catch (IOException e){ e.printStackTrace(); } System.out.println ("Here's Something to think about..."); try{ Thread.sleep(3000); }catch (InterruptedException ex){ Thread.currentThread().interrupt(); } try{ File file2 = new File("convo.ella"); BufferedReader reader2 = new BufferedReader(new FileReader(file2)); String ln2 = reader2.readLine(); List<String> lines2 = new ArrayList<String>(); while(ln2 != null){ lines2.add(ln2); ln2 = reader2.readLine(); } Random r2 = new Random(); System.out.println(namer+", "+lines2.get(r2.nextInt(lines2.size()))); }catch (IOException e){ e.printStackTrace();} } System.exit(0); } } 
\$\endgroup\$
1
  • 1
    \$\begingroup\$ If you are not afraid of going deeper into the subject, I recommend playing around with the Stanford Core NLP pipeline (nlp.stanford.edu/software/corenlp.shtml#Download). This allows you to analyse the sentence structure and handle more complex interactions. \$\endgroup\$ Commented Nov 27, 2014 at 17:16

3 Answers 3

8
\$\begingroup\$

I strongly recommend to use an IDE for Java development. Try IntelliJ or Eclipse or NetBeans. I'm guessing you are not using one because the formatting is extremely poor. Formatting is a serious concern, because code is read far more often than it is written. It's worth paying attention to. In Eclipse, you could use the Control-Shift-f keyboard shortcut to reformat the entire file. The result will be far more readable.

Remove unused stuff from the code. Every line of code is a potential bug or security hole. Code without a purpose has no place in a program. For example the Conversate constructor and the name field can be safely removed.

There is no need to create multiple scanners from System.in. No need for in2, in3. You can reuse the first one.

The trim here is pointless:

String namer = in.nextLine(); namer.trim(); 

The .trim() method returns a new trimmed String object. The original string is not modified (strings in Java are immutable, they cannot change). The new string is thrown away. Most probably you wanted to do this:

String namer = in.nextLine().trim(); 

In this code:

String gender = in3.nextLine(); char gen = 'f'; if (gender.equalsIgnoreCase("boy") || gender.equalsIgnoreCase("man") || gender.equalsIgnoreCase("guy") || gender.equalsIgnoreCase("m") || gender.equalsIgnoreCase("male")) { 

It's inefficient to do equalsIgnoreCase repeatedly. It would be better to lowercase the input once, so that you could use simple equals instead. But it would be still a lot of typing. A better solution is to build a Set of the accepted names, and check if the lowercased gender is contained in the Set.

For example, define these sets at the top of the class:

private static Set<String> GIRLY = new HashSet<String>(Arrays.asList( "girl", "woman", "lady", "f", "female", "chick" )); private static Set<String> BOYISH = new HashSet<String>(Arrays.asList( "buy", "man", "guy", "m", "male", "dude", "bloke", "chap", "kid" )); 

And then in the code you can process the gender like this:

String gender = in3.nextLine().trim().toLowerCase(); char gen = 'f'; if (BOYISH.contains(gender)) { gen = 'm'; // ... } else if (GIRLY.contains(gender)) { gen = 'f'; // ... 
\$\endgroup\$
8
\$\begingroup\$

I just have a few general things to point out for now, which should be a good starter:

  • Although you have some additional methods, I still feel that there can be more. It's good to reduce the amount of work done by main(), especially for readability and maintenance concerns. It may also be necessary to use additional classes (the outermost class doesn't have to be the only one).

    Regarding the use of classes, you should consider this first. It'll especially be harder to expand on this application without additional classes splitting the various responsibilities. Otherwise, it looks very procedural and harder to follow. Be sure to read up on good Java practices to help bring this application to its fullest potential.

  • This may be a more idiomatic way of acquiring a random number within a range:

    // this is constructed in main() Random rand = new Random(); // ... public static int randomWithRange(int min, int max, Random rand) { return rand.nextInt((max - min) + 1) + min; } 

    (The needed import is java.util.Random.)

    More alternatives can also be found here.

  • You don't really need System.exit(0) here. There are no loops in this part, so none of that code will be repeated. The program will still gracefully exit from main().

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Creating a new Random object inside such a method is a bad idea. Random objects are meant to be reused! \$\endgroup\$ Commented Nov 28, 2014 at 12:15
  • \$\begingroup\$ @SimonAndréForsberg: I guess I didn't realize that it's similar to std::srand. Would I just create it in main() and pass the object to this method? \$\endgroup\$ Commented Nov 28, 2014 at 15:28
  • \$\begingroup\$ I think that is what I would do, yes. \$\endgroup\$ Commented Dec 1, 2014 at 11:15
5
\$\begingroup\$

In addition to the points already mentioned (especially about not needing to use multiple scanners), I'd recommend you use a switch statement when handling multiple cases.

If you're worried about the equivalents like "man" and "boy" janos provides a good solution that I'd still use a switch for, or you can also account for them by simply alternating when you use the break points and altering the letter case beforehand.

For example these two verbose, horizontally unkempt checks

 `if (gender.equalsIgnoreCase("boy") || gender.equalsIgnoreCase("man") || gender.equalsIgnoreCase("guy") || gender.equalsIgnoreCase("m") || gender.equalsIgnoreCase("male")) { // boy stuff } else if ender.equalsIgnoreCase("girl") || gender.equalsIgnoreCase("woman") || gender.equalsIgnoreCase("lady") || gender.equalsIgnoreCase("f") || gender.equalsIgnoreCase("female")) { // girl stuff }` 

can be

 switch(gender.toLowerCase()) { case "boy": case "guy": case "man": case "male": case "m": gen = 'm'; // Guy messages break; case "girl": case "lady": case "woman": case "female": case "f" gen = 'f'; // Girl messages break; default: // Message about the user being an alien } 
\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.