-2

This is the accept function for my tic tac toe program, so s is only going to store data in String format and in between 0,0 or 2,2.

I am now using the getNumericValue function to store the numbers in p and q respectively, but during runtime, I get a StringIndexOutOfBounds exception, when trying to store the value in p.

The problem is happening only when choice() function to decide x or O is called before accept() else it's running fine. What is the problem with the choice() funtion?

void accept()throws IOException
{
    System.out.println("Your move:");
    String s=xy.readLine();

    int p = (Character.getNumericValue(s.charAt(0)))-1;
    int q = Character.getNumericValue(s.charAt(2))-1;
    if(ar[p][q]==0)
        ar[p][q]=1;
    else
    {
        System.out.println("You can't capture a location that has already been captured!");
        accept();
    }
}



void choice() throws IOException
    {
        System.out.println("Welcome to tictactoe");
        System.out.print("Enter your weapon X or O : ");
        chp = Character.toUpperCase((char)xy.read());

        if (chp=='X')
            chc='O';
        else 
            chc = 'X';

        System.out.println("kkbot chose: "+ chc);
    }
  • 3
    Read the [documentation for `String.charAt`](https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#charAt(int)). You get a `StringIndexOutOfBoundsException` if the index you pass it is >= the length of the String. In other words, is `s` fewer than two characters, making `2` an invalid index? – qxz Jan 13 '17 at 08:10
  • What is the input format? – Shyam Baitmangalkar Jan 13 '17 at 08:11
  • @ShyamBaitmangalkar String Even after giving the correct input in the correct format, s is always storing an empty string for some reason and Character.getNumericValue returns -1. – Aditya Jyoti Paul Jan 13 '17 at 08:33
  • If `s` is always an empty string, then your question is likely a duplicate of [Scanner is skipping nextLine() after using next(), nextInt() or other nextFoo() methods](http://stackoverflow.com/q/13102045/5221149). Of course, it's difficult to be sure what happened to `xy` before the method was called. – Andreas Jan 13 '17 at 08:35
  • I am using BufferedReader not Scanner for input. – Aditya Jyoti Paul Jan 13 '17 at 08:43

3 Answers3

1

Your problem is:

This is the accept function for my tic tac toe program, so s is only going to store data in the format and in between 0,0 or 2,2.

But then your code does:

String s=xy.readLine();
int p = (Character.getNumericValue(s.charAt(0)))-1;
int q = Character.getNumericValue(s.charAt(2))-1;

The user can enter whatever he wants. Nothing in readLine() would prevent him from adding an empty or too long string!

Before you do anything with that string, you have validate that it has the assumed length; like in:

String inputFromUser = "";
do {
  System.out.println("Your move [enter a value like A1]: ");
  inputFromUser = scanner.readLine();
} while (inputFromUser.length != 2);

Beyond that: please use real names for your variables. s, xy, p, q ... tell the reader nothing about the purpose of these variables. Yes, you save a bit of time while typing; and you will spent 10 times that time when reading your source code later on; and you dramatically increase the likelihood of stupid typos with those ugly single-character names, too!

GhostCat
  • 127,190
  • 21
  • 146
  • 218
0

If at all you are just trying to store values like 0,0 or 1,1 in two separate int variables, that should be a straight forward process. You should take precautions for erroneous inputs though. Hence, your accept() method should be something like this:

public void accept(){
        Scanner sc = new Scanner(System.in);
        System.out.println("Your move [Enter marking position in the form x,y]: ");
        String userInput = sc.nextLine();
        String[] userMarkedPositions = userInput.split(",");
        if(userMarkedPositions.length == 2){
            int x = Integer.parseInt(userMarkedPositions[0]);
            int y = Integer.parseInt(userMarkedPositions[1]);
            //Followed by your other operations
            //....
            //....
        }else{
            System.out.println("Invalid input!!");
            System.out.println("Input should be in the form of x,y");
            accept();
        }
        sc.close();
    }

And just like @GhostCat has rightly mentioned, you should be using proper names for your variables. That improves the readability of your code.

Shyam Baitmangalkar
  • 1,017
  • 12
  • 15
0

Hey I finally found the problem in the code. The choice() function accepts a character, but after that when the string is accepted, instead of giving the user the chance to enter the string the machine takes null as the input string automatically(produced when pressing space after the character).

Problem

This problem is produced whenever one tries to accept a string or any other data type after CHAR, for example, the input for 's' here after the input 'ch'.

Solution

Read input as a string, and extract the first character to consume and discard the subsequent spaces and newlines I also found a way to hack this problem though. :)

import java.io.*;
class tictactoe
{
    BufferedReader xy=new BufferedReader(new InputStreamReader(System.in));
    void accept()throws IOException
    {
        System.out.println("Enter your weapon X or O : ");
        char ch = xy.readLine().charAt(0);  #Ahaaa momemt
    
        System.out.println("Your move:");
        String s=xy.readLine();              
    }
}