package numberguesser;

import java.io.*;

public class NumberGuesser {

  public NumberGuesser() {

    GuessNumber();
  }

  public void GuessNumber() {

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    /* 90 holds the upper bound + 1 to output if the user makes an error */
    int errorOutput;
    /* 91 used to divide the difference of lastGuess and currentGuess to add or
     subtract to/from next guess
     */
    final int CONSTANT_2 = 2;
    /* 92 holds the 0, 1, 999 user input value */
    int userInput = 0;
    /* 94 used to hold the value of the last guess */
    int lastGuess = 0;
    /* 95 used to hold the value of the current guess */
    int currentGuess = 0;
    /* 96 used to make negative differences positive */
    final int CONSTANT_NEG_1 = -1;
    /* 97 temp storage to hold calculated differences */
    int tempStorage;
    /* 89 counts the number of errors before telling the user he/she has made a
     miscalculation (must equal 14 to cause output of errorOutput because this
     is the number it takes to reach 0 when having an upper bound of 100,000,000
     */
    int errorCounter = 0;

    int axRegister;

    System.out.print("? ");

    /* 0 - 7
       This segment of the code takes in the upper bound, adds 1 to the value
       and stores it in "errorOutput" to display if a user error is made.
     */

    try {

      currentGuess = Integer.parseInt(br.readLine());
    }

    catch (IOException e) {

      e.printStackTrace();
    }

    errorOutput = currentGuess + 1;

    ////////////////////////////////////////////////////////////////////////

    /* This loop represents the loop that the assembly program follows each
     time a guess is presented to the user.
     */

    while (true) {

      /* 8 - 11
       Loads the currentGuess and subtracts the last guess to either add or
       subtract half of the difference for the next guess.
       */

      axRegister = currentGuess;
      axRegister -= lastGuess;

      ////////////////////////////////////////////////////////////////////////

      /* 12 - 15
       If the value in the axRegister is negative from taking the difference
       between guesses, make it positive
       */

      if (axRegister < 0)
        axRegister *= CONSTANT_NEG_1;

      ////////////////////////////////////////////////////////////////////////

      /* 16 - 23
       We need to find out if the difference is 1. If it is, we can't
       half the difference because floats aren't supported and the difference
       will come out to 0. So if it's 1, we'll add 1, so that half of that is 1.
       So, we'll take 1 away from the value and check if it's still positive.
       If it is not, add 2 (one for the one we previously subtracted, and 1 for
       making the result of the division 1). If it is positive, add only 1 for
       the one we previously subtracted.
       */

      axRegister -= 1;

      if (axRegister > 0);
      else
        axRegister += 1;

      axRegister += 1;

      ////////////////////////////////////////////////////////////////////////

      /* 24 - 27
       We need to divide the difference by two in order to add or subtract
       it from the lastGuess and then store it in a temporary place.
       */

      axRegister /= CONSTANT_2;
      tempStorage = axRegister;

      ////////////////////////////////////////////////////////////////////////

      /* 28 - 31, 77 - 88, 98 - 99
       We need check once more if the difference is 1 in order to increment
       our errorCount so that we will only permit 14 errors before telling the
       user that he/she has made an error and output errorOutput. (The value is
       14 because with an upper bound of 100,000,000 the errorCounter will
       increment 14 times from 13 - 0. This is the only way to reach 0 with this
       algorithm.) So, we subtract 1 from the axRegister value and test whether
       the value is now 0. If it is, we subtract 14 from the error counter and
       test whether it now equals 0 (in order to indirectly test whether it was
       equal to 14), if this test proves false, we add 15 (14 for what we
       previously subtracted, and 1 more to increment the errorCounter. Then
       we save the value in errorCounter
       */

      axRegister -= 1;

      if (axRegister == 0) {

        axRegister = errorCounter;

        axRegister -= 14;

        if (axRegister == 0) {

          System.out.println(errorOutput);
          System.exit(1);
        }

        axRegister += 15;
        errorCounter = axRegister;
      }

      ////////////////////////////////////////////////////////////////////////

      /* 32 - 37
       Output the currentGuess and take userInput to find out if 0, the guess
       was too low, 1, the guess was too high, or 999, the guess was right
       */

      System.out.print(currentGuess + "\n? ");

      try {
        userInput = Integer.parseInt(br.readLine());
      }

      catch (Exception e) {

        e.printStackTrace();
      }

      axRegister = userInput;

      ////////////////////////////////////////////////////////////////////////

      /* 38-39, 45 - 52
       If the value was 0, the guess was too low, so to increase it, we will
       add our currentGuess to our previously computed tempStorage value.
       */

      if (axRegister == 0) {

        axRegister = tempStorage;
        axRegister += currentGuess;
        tempStorage = axRegister;
      }

      ////////////////////////////////////////////////////////////////////////

      /* 40 - 43, 53 - 64
       If the value was 1, the guess was too high, and we'll need to subtract
       the difference from the last guess. If the axRegister is now negative,
       multiply by a -1 to make it positive.
       */

      if (axRegister == 1) {

        axRegister = tempStorage;
        axRegister -= currentGuess;
        tempStorage = axRegister;

        if (axRegister > 0);

        else {

          axRegister *= CONSTANT_NEG_1;
          tempStorage = axRegister;
        }
      }

      ////////////////////////////////////////////////////////////////////////

      /* 44
       If the userInput was not 0 and not 1, then we assume it is 999 and that
       we guessed correctly. We then terminate the program.
       */

      else if (axRegister == 999) {

        System.exit(0);
      }

      ////////////////////////////////////////////////////////////////////////

      /* 65 - 72
       Now we need to move the currentGuess to the lastGuess and our
       tempStorage value to the currentGuess for the next iteration.
       */

      axRegister = currentGuess;
      lastGuess = axRegister;
      axRegister = tempStorage;
      currentGuess = axRegister;

      ////////////////////////////////////////////////////////////////////////

      /* 73 - 76
       The axRegister value should never be negative at this stage, so whether
       it's positive or zero, continue the loop.
       */

      if (axRegister > 0)
        continue;
      if (axRegister == 0)
        continue;

      ////////////////////////////////////////////////////////////////////////
    }
  }

  public static void main(String[] args) {

    NumberGuesser numberGuesser = new NumberGuesser();
  }
}
