Java - Как напечатать() вывод в предыдущую строку после ввода

Я как бы новичок в Java, и я все еще пытаюсь понять его, поэтому я извиняюсь, если это глупый вопрос, но мне было интересно, как печатать вывод в той же строке, что и вход, Например, я программирую простую игру, в которой пользователь пытается угадать 4-значное число (скорее, как Mastermind). У меня есть механика, все разобрались, но мне сложно отображать ее на консоли. Вначале это может выглядеть примерно так: (a)

Turn    Guess   Bulls   Cows
----------------------------
1

Затем пользователь должен ввести свое предположение: (b)

Turn    Guess   Bulls   Cows
----------------------------
1       1234

И как только пользователь нажимает Enter, программа должна проверить свою догадку на секретный номер и вывести число "быков" (цифры в их предположении, которые точно соответствуют секретному номеру) и "коровы" (цифры в их предположите, что это часть числа, но не в том месте), а затем запустите новую строку и снова ожидайте ввода пользователя. Итак, если секретное число было, скажем, 4321... (c)

Turn    Guess   Bulls   Cows
----------------------------
1       1234    0       4
2

Проблема в том, что я не могу на всю жизнь понять, как получить вывод для отображения в той же строке, что и вход. Вот фрагмент того, что у меня до сих пор (урезано, потому что полный код намного уродливее):

number = "4321";
String guess;
int attempts = 1;
do
{
    System.out.print(attempts + "\t\t");
    guess = keyboard.next();
    attempts++;
    int bulls = checkBulls(guess, number);
    int cows = checkCows(guess, number);
    System.out.print("\t\t" + bulls + "\t\t" + cows + "\n");
}
while (!guess.equals(number));

Который получает меня до (б), но тогда, когда я нажимаю enter, это происходит:

Turn    Guess   Bulls   Cows
----------------------------
1       1234                 // so far so good
    0       4                // ack! These should've been on the previous line!
2

Я знаю, что это не очень важно для игры, и, вероятно, только я делаю вещи более сложными, чем нужно, но это заставляет меня сходить с ума. Я полагаю, что происходит, когда вы нажимаете enter после ввода вашей догадки, программа запускает новую строку, а затем печатает быков и коров. Есть ли способ обойти это?

Ответы

Ответ 1

Вы должны заглянуть в Ansi Escape Codes.

Что-то вроде:

public void update() {
    final String guessString = keyboard.next();

    System.out.println("\033[1A\033[" + guessString.length() + 'C'
        + "\t{next col}");
}

приведет к:

1234   {next col}

(где 1234, а затем {RETURN} был введен пользователем, в соответствующей поддерживающей консоли.

"\033[1A" перемещает курсор вверх на 1 строку; и "\033[xC" перемещает курсор x вправо (где выше мы вычисляем x как длину их угадывания).

Другой вариант, который у вас есть с этим подходом, - очистить консоль ("\033[2J"), чтобы вы могли полностью перерисовать таблицу (что, вероятно, проще в обслуживании).

Ответ 2

Ваша проблема в том, чтобы очистить консоль или очистить строку, которая зависит от консоли, на которой вы работаете, и зависит от пользователя!

См. Консоль очистки Java или Явная строка Java

В любом случае этот пример очищает строки, и он работает в оболочке Unix bash. (Не в консоли Eclipse) Он использует "\b" для очистки char (обратная косая черта)

 public static void main(String[] args) throws Exception {
        int i=0;

        while (true)
        {            

            String hello="Good morning"+i;
            System.out.print(hello+i);
            int j=0;
            while(j<=hello.length()){
                 System.out.print("\b");
                j++;
            }
            i++;
            Thread.sleep(1000);
            if(i==100)
                break;
        }
    }

Проблема в вашем случае заключается в том, что вам нужно очистить и новую строку, так как вы читаете ввод, а theere - простой способ читать ввод без новой строки. См. Как прочитать один char с консоли в Java (как пользователь ее набирает)?

Ответ 3

Я знаю, что это не ваша реализация, но этого может быть достаточно. То, что вы можете сделать, это распечатать ход игры после каждого входа. Затем вы можете увидеть ход игры после каждой попытки, и плата будет обновляться каждый раз.

    ArrayList<String> turns = new ArrayList<>();
    turns.add("Turn\t\tGuess\t\tBulls\t\tCows\n");
    turns.add("----------------------------------------------------");
    Scanner keyboard = new Scanner(System.in);
    String number = "1234";
    String guess = "";
    int attempts = 0;

    while(!number.equals(guess))
    {
        for(String line : turns)
            System.out.println(line);
        System.out.println("Guess the magic number...");
        guess = keyboard.nextLine();
        attempts++;
        int bulls = checkBulls(guess, number);
        int cows = checkCows(guess, number);
        String attemptOutput = attempts + "\t\t" + guess + "\t\t" + bulls + "\t\t" + cows + "\n";
        turns.add(attemptOutput);
    }

Ответ 4

Вот другая реализация, которая будет достигать той же цели с точки зрения отображения, но вы должны заметить, что я очищаю экран несколькими новыми строками, поэтому конечный эффект все равно такой же, как...

  • пользователь вводит номер под столбцом Guess.
  • каждая попытка будет отображаться сразу же после нажатия пользователем ENTER по вашему желанию.

ПРИМЕЧАНИЕ. У меня есть жестко закодированные быки и значения коров для запуска программы.

import java.util.ArrayList;
import java.util.Scanner;

public class Game {

    public static void main(String[] args) {
        ArrayList<String> attempts = new ArrayList<String>();
        attempts.add("Turn\t\tGuess\t\tBulls\t\tCows\n");
        attempts.add("----------------------------------------------------");
        Scanner keyboard = new Scanner(System.in);
        String number = "1234";
        String guess = "";
        int turn = 1;

        while (!number.equals(guess)) {
            // multiple new lines to clear screen
            System.out.println("\n\n\n\n\n\n\n\n");
            for (String line : attempts)
                System.out.println(line);
            System.out.print(turn + "\t\t");
            guess = keyboard.nextLine();
            // checkbull implementation
            int bulls = 0;
            // checkcow implementation
            int cows = 4;
            String attemptOutput = turn + "\t\t" + guess + "\t\t" + bulls
                    + "\t\t" + cows;
            turn++;
            attempts.add(attemptOutput);
        }
    }
}

Пример прогона

введите описание изображения здесь